【发布时间】:2016-04-07 20:31:54
【问题描述】:
我发现当从托管代码中调用 GetBinaryType 时,我得到的结果与从同一台机器上的本机代码调用 GetBinaryType 的结果相反。
我从别处借用了编组声明:
public enum BinaryType : uint
{
SCS_32BIT_BINARY = 0, // A 32-bit Windows-based application
SCS_64BIT_BINARY = 6, // A 64-bit Windows-based application.
SCS_DOS_BINARY = 1, // An MS-DOS – based application
SCS_OS216_BINARY = 5, // A 16-bit OS/2-based application
SCS_PIF_BINARY = 3, // A PIF file that executes an MS-DOS – based application
SCS_POSIX_BINARY = 4, // A POSIX – based application
SCS_WOW_BINARY = 2 // A 16-bit Windows-based application
}
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetBinaryType(
string lpApplicationName,
out BinaryType dwBinType
);
然后调用函数为
bool is64bit = false;
BinaryType binType = BinaryType.SCS_32BIT_BINARY;
// Figure out if it's 32-bit or 64-bit binary
if (GetBinaryType(phpPath, out binType) &&
binType == BinaryType.SCS_64BIT_BINARY)
{
is64bit = true;
}
对于 32 位本机二进制文件,GetBinaryType 返回 BinaryType.SCS_64BIT_BINARY (6),对于 64 位本机二进制文件,返回 BinaryType.SCS_32BIT_BINARY (0)。
为了验证,我编写了一个本地命令行工具,并针对相同的二进制文件运行它。
PCWSTR rgBinTypes[] = {
L"SCS_32BIT_BINARY", // 0
L"SCS_DOS_BINARY", // 1
L"SCS_WOW_BINARY", // 2
L"SCS_PIF_BINARY", // 3
L"SCS_POSIX_BINARY", // 4
L"SCS_OS216_BINARY", // 5
L"SCS_64BIT_BINARY", // 6
};
int _tmain(int argc, _TCHAR* argv[])
{
DWORD binType;
if (argc < 2)
{
wprintf(L"Usage: %S <binary-path>\n", argv[0]);
goto Cleanup;
}
if (!GetBinaryType(argv[1], &binType))
{
wprintf(L"Error: GetBinaryType failed: %d\n", GetLastError());
goto Cleanup;
}
wprintf(L"Binary type: %d (%s)\n", binType, binType < 7 ? rgBinTypes[binType] : L"<unknown>");
Cleanup:
return 0;
}
对于 32 位本机二进制文件,命令行工具正确返回 0 (SCS_32BIT_BINARY),对于 64 位本机二进制文件,正确返回 6 (SCS_64BIT_BINARY)。
我找到了一个关于其他人有同样问题的参考,但没有提供答案:https://social.msdn.microsoft.com/Forums/en-US/fc4c1cb4-399a-4636-b3c3-a3b48f0415f8/strange-behavior-of-getbinarytype-in-64bit-windows-server-2008?forum=netfx64bit
还有其他人遇到过这个问题吗?
我意识到我可以翻转托管枚举中的定义,但这看起来非常笨拙。
【问题讨论】:
-
GetBinaryType的行为会改变您的应用程序是否在 WOW64 上运行,例如如果您启用了“首选 32 位”或不针对任何 CPU。 -
您的 C# 程序是编译为 64 位还是 32 位?如果是 32-but,它可能正在经历重定向。