Original address: http://www.cnblogs.com/hbccdf/archive/2014/03/09/3590916.html
Since the operating system has been upgraded to 64-bit, there will be a constant need to face 32-bit, 64-bit problems. I believe there are many people who are not very clear about the difference between 32-bit programs and 64-bit programs, and Program Files (x86). At the same time, for the program DLL file should be put into the System32 folder, or SYSWOW64, most people make the decision is, 32-bit program put to system32,64 bit program put to SYSWOW64. Is that so, then today is a case of my side to explain in detail.
DLL file mismatch causes the database to fail to start
Some time ago, the database made some functional improvements, and then compiled with VS2010 to check out a version for testing department testing. After the test department gets the database, the database program is registered as a service by batch processing. Although the process of performing a batch process, actually registering the service is done by running the database program and giving it the command-line arguments, see this article about the registration and uninstallation of the Windows Service series--debug, release version, and its rationale.
After running the program through batch processing, the following issues occur:
This kind of problem, the test department is not calm, asked me to see. I tried to run the program again, and this problem still occurs. "But in my machine running very good ah", this is the first sentence I said, I believe many people read this sentence on the understanding of the smile.
There is a problem, since my machine can run normally, then why not the test machine, the first to find the reason.
The database is compiled with VS2010, and running on other machines requires the operating system to run and the VS2010 runtime installed, otherwise it will not function properly because the DLL files necessary to run the program are missing. I think this is the reason, but another thought, if there is no runtime, will prompt the lack of msvcr100.dll, Msvcp100.dll and other files, the problem is clearly not missing DLL problem. The problem is a bit complicated, for the sake of simplicity, try to install the runtime first, see if you can solve it.
The VS2010 x86 and x64 runtime installation packages are all loaded once. Running the program again is still an eye-catching mistake.
Although the installation runtime does not solve this problem, it is empirically determined that either the DLL file is missing or the DLL file version is out of the question. So, the next step is to find a way to prove this conjecture.
By Dependency Walker to detect the database program, all dependent DLL files are present and no problems are found. Then through the ListDLLs tool in Windows Sysinternals to detect the DLL file that the currently running process has loaded, and see from the list that the Msvcr100.dll is not loaded, it is estimated that this DLL file is out of the question. After I found this file from my machine and replaced the Msvcr100.dll file on the test machine, the database is working.
Originally, just started the database, the hint can not find the Msvcr100.dll file, test colleagues from other XP system of the machine to find this file, and put into the System32 and SysWow64, so it led to this problem.
Because the XP system is 32-bit, So the found Msvcr100.dll file is also 32-bit, when the 32-bit program into the System32 folder, start the 64-bit database, the 32-bit DLL will be loaded, because the 64-bit program can only load 64-bit DLLs, so when the program tries to load the 32-bit DLL, it will be an error.
Is it System32 or SysWow64?
Win7, Server2008 and other 64-bit system came out, in order to be compatible with 32-bit programs, so adopted the WOW64 scheme, in the System folder, you can see a System32 folder, and a SysWow64 folder. Although this scheme for the program, can be easily compatible with 32-bit programs, but for the general user, want to distinguish between System32 and SysWow64 that is a bit difficult, because the name is too confusing.
As for why Microsoft uses the WOW64 solution, I will not elaborate, interested friends can read this article: what is SysWow64. This article describes in detail the WOW64 technology and the 64-bit system compatible with 32-bit programs.
Finally, we can know:
- The SysWow64 folder is a 64-bit Windows store for 32-bit Windows system files, while the System32 folder is the place to store 64-bit program files.
- When a 32-bit program loads the DLLs in the System32 folder, the operating system automatically maps to the corresponding files in the SysWow64 folder.
See these, you will certainly think you really understand the difference between System32 and SysWow64, I also, I think I really understand, but really understand, is really understand?
Whatever it is, please keep reading it.
Distinguish DLL files 32-bit 64-bit program It makes me feel confused.
The above mentioned database does not start this situation, has been encountered more than once. Every time I encounter this problem, I would like to have a tool to check whether the DLL programs in the System32 and SysWow64 folders are the corresponding 64-bit and 32-bit programs. As far as I know, only dumpbin can see if a DLL file is 32-bit or 64-bit, but it's obviously not the tool I want because you can only view one file at a time.
Well, do it yourself, clothed, since there is no such tool, then write a bar, it is good to judge whether the DLL file is 32-bit or 64-bit is not very difficult.
Under Windows System, EXE, DLL files can be called PE files, they have the same file format, called PE file format.
The first part of the PE file is image_dos_header, size 64B, and for the 32-bit 64-bit check, there is an important member e_lfanew, the value of which is image_nt_headers offset.
Image_dos_header is defined as follows:
Typedef struct _IMAGE_DOS_HEADER
{//(Note: The leftmost is the offset of the file header.)
+0h WORD e_magic //Magic DOS signature MZ(4Dh 5Ah) DOS executable tag
+2h WORD e_cblp //Bytes on last page of file
+4h WORD e_cp //Pages in file
+6h WORD e_crlc //Relocations
+8h WORD e_cparhdr //Size of header in paragraphs
+0ah WORD e_minalloc //Minimun extra paragraphs needs
+0ch WORD e_maxalloc //Maximun extra paragraphs needs
+0eh WORD e_ss //intial(relative)SS value Initialization stack SS for DOS code
+10h WORD e_sp //intial SP value Initial stack pointer SP for DOS code
+12h WORD e_csum //Checksum
+14h WORD e_ip //intial IP value Initialization command entry for DOS code [pointer IP]
+16h WORD e_cs //intial(relative)CS value Initial stack entry for DOS code
+18h WORD e_lfarlc //File Address of relocation table
+1ah WORD e_ovno //Overlay number
+1ch WORD e_res[4] //Reserved words
+24h WORD e_oemid //OEM identifier(for e_oeminfo)
+26h WORD e_oeminfo //OEM information;e_oemid specific
+29h WORD e_res2[10] //Reserved words
+3ch DWORD e_lfanew //Offset to start of PE header Point to PE file header
} IMAGE_DOS_HEADER;
Image_nt_headers is defined as follows:
typedef struct _IMAGE_NT_HEADERS
{
+0h DWORD Signature;
+4h IMAGE_FILE_HEADER FileHeader;
+18h IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS;
Signature field: In a valid PE file, the Signature field is set to 00004550h,ascii code character is "PE00". Marks the beginning of this PE file header. The "PE00" string is the beginning of the PE file header, where the E_lfanew field of the DOS header is pointing.
Image_file_header Structure Definition:
Typedef struct _IMAGE_FILE_HEADER
{
+04h WORD Machine; // Run the platform
+06h WORD NumberOfSections; // Number of blocks in the file
+08h DWORD TimeDateStamp; // file creation date and time
+0Ch DWORD PointerToSymbolTable; // Point to the symbol table (mainly used for debugging)
+10h DWORD NumberOfSymbols; // Number of symbols in the symbol table (ibid.)
+14h WORD SizeOfOptionalHeader; // IMAGE_OPTIONAL_HEADER32 structure size
+16h WORD Characteristics; // file attributes
} IMAGE_FILE_HEADER;
Where the machine field represents the target CPU type of the executable file:
- image_file_machine_i386 0x014c x86
- Image_file_machine_ia64 0x0200 Intel Itanium
- Image_file_machine_amd64 0x8664 x64
This is not very intuitive, the last picture to look at:
With this, we can use the program to determine the 32-bit, 64-bit, the code is as follows:
Public static bool IsPE32(string path)
{
FileStream file = File.OpenRead(path);
/ / Move to the location of e_lfanew
stream.Seek(0x40 - 4, SeekOrigin.Begin);
Byte[] buf = new byte[4];
stream.Read(buf, 0, buf.Length);
/ / Calculate the location of the Machine based on the value of e_lfanew
Int pos = BitConverter.ToInt32(buf,0) + 4;
stream.Seek(pos, SeekOrigin.Begin);
Buf = new byte[2];
stream.Read(buf, 0, buf.Length);
/ / Get the value of Machine, 0x14C is 32 bits, 0x8664 is 64 bits
Int16 machine = BitConverter.ToInt16(buf, 0);
If (machine == 0x14C)
{
Return true;
}
Else
{
Return false;
}
}
The core functionality is complete, and the rest is the interface and the Traversal folder:
According to the test results and the actual situation, the test results are no problem. So let's start the real test, System32 and SysWow64. Test results such as:
See, System32, SysWow64 in the detection of all the files are 32-bit programs, according to common sense can also be judged that the actual is not the case. There must be something wrong with the program, so just check with the hex editor to see if the two files are consistent.
Again to judge whether it is System32 or syswow64--unexpected pit
Viewing the Msvcr110d.dll in two folders via UE is really a 32-bit program, and compared with beyond compare, two files are no different. The MD5 for viewing two files with the tool is also exactly the same:
Is it true that all two files are 32, and I still don't think it's possible.
Next move the Msvcr110d.dll in System32 and SysWow64 to a different folder so that System32 and SysWow64 do not have the DLL file, and then run a 32-bit program that requires this DLL file Petest, the DLL file is not found. Copy the original System32 and SysWow64 Msvcr110.dll to the directory where the Petest is located and run the program. When using Msvcr110d.dll in SysWow64, the program can run normally, indicating that the file is indeed 32 bits. When you use Msvcr110d.dll in System32, the program does not run correctly, and the error that is mentioned at the beginning of the article appears. Why through beyond Compare, UE, MD5 detection for the same DLL file, one can run normally, the other one can not do it.
Think again of these two words:
- The SysWow64 folder is a 64-bit Windows store for 32-bit Windows system files, while the System32 folder is the place to store 64-bit program files.
- When a 32-bit program loads the DLLs in the System32 folder, the operating system automatically maps to the corresponding files in the SysWow64 folder.
The 32-bit program loads the DLL files in the System32 folder, and the operating system automatically maps to the SysWow64 folder, that is, 64-bit programs, and the system does not map anymore.
Viewing the UE, Beyond Compare, and MD5 three processes through the Task Manager are all 32-bit processes, that is, three programs are all 32-bit.
At this point we can re-understand the "32-bit program load DLL files in the System32 folder, the operating system will automatically map to the SysWow64 folder" This sentence, should be " as long as 32-bit programs Access System32 folder, whether it is loading DLLs, or reading text information, will be mapped to the SysWow64 folder .
This understanding is right, let's do an experiment to verify it.
Find a 32-bit text editor notepad++ (Win7 system comes with 64-bit), create a new 1.txt file in the SysWow64 folder, open edit this file, the content is SysWow64. Then in the Open File dialog box, enter "C:\Windows\System32\1.txt" in the input box, open the file, see the content is SysWow64,:
The 1.txt file is not created in System32, the 32-bit program accesses 1.txt files in System32, is automatically mapped to 1.txt files in the SysWow64 folder, and if you open the 1.txt file in System32 with a 64-bit Notepad editor, you will be prompted to find the file:
Thus, it is possible to verify that " as long as 32-bit programs access the System32 folder, whether it is loading DLLs or reading text information, it will be mapped to the SysWow64 folder " is correct.
Program Files (x86) and Program Files
In the case of System32 and SYSWOW64, consider whether program files (x86) and program files are also the case. When the Program Files directory is accessed by 32-bit programs, it is automatically mapped to the x86 directory.
It is also verified by 1.txt, and it is found that when 32-bit programs access the program Files directory, they are not mapped to the Programming files directory (x86).
Do 32-bit programs really need to access System32?
After so much verification, it is finally known that the 32-bit program cannot access the SYSTEM32, only 64-bit programs to access, which is considered to be a very large hole in Windows. But think about it, 32-bit programs really need to access the System32. Just use this DLL detection tool.
If a 32-bit program cannot access System32 on a 64-bit system, it needs to be compiled to 64 bits in order to access it. If the program is compiled into 64-bit, it will not be able to run on 32-bit systems, and since there is no need to detect 32-bit, 64-bit on 32-bit systems, only 32-bit programs are required. This is really a contradiction, it must be compiled two programs, a 32-bit, a 64-bit, to adapt to different operating systems. If it is C + +, then the answer is this, you must compile a 32-bit one 64-bit. And dotnet is not the same, compile the time to choose "AnyCPU", and do not select "preferred 32-bit" (the default is selected in VS2012), the compiled program can be run on both 32-bit and 64-bit systems, 32-bit system is 32-bit process, 64-bit system is 64-bit process , is not very convenient, this is the charm of dotnet and anycpu.
At this point, DLL detection program, do not need to do any code modification, simply select AnyCPU at compile time, and remove the "preferred 32-bit" option, you can normally detect System32, SysWow64 folder dll files.
Summary of differences between 32-bit programs and 64-bit programs
At this point, I think it is true to understand the difference between System32 and SysWow64, this kind of pit, is a step past, then to summarize the difference between the 32-bit program and 64-bit programs:
- syswow64 folder, which is 64-bit Windows, where 32-bit Windows system files are stored, and System32 folders, is the place to store 64-bit program files.
- . NET program is configured in AnyCPU and select "Preferred 32-bit" compilation , which will run as a 32-bit process, and the files in the System32 folder cannot be accessed at this time; if No "preferred 32-bit" is selected, and will run as a 64-bit process so that the System32 folder can be accessed. (In VS2012, the "preferred 32-bit" is selected by default).
- 32-bit programs have their own registry with 64-bit programs. The
- 32-bit and 64-bit programs have access to program Files (x86) and the programming files directory.
- More differences can be referred to: 32-bit and 64-bit windows:frequently asked questions .
Work and learning process will encounter a lot of pits, accidentally will fall, but from where to fall from where to climb up, summing up lessons learned, with full enthusiasm again set sail, victory is not far ahead.
Because my level is limited, if there is any wrong in the text, please criticize me, I appreciate it!
DLL file 32-bit 64-bit detection tool and Windows folder SysWow64 Pit "forward"