获取有效的可执行文件名
.NET 应用程序(托管)在 Windows 7 64 位上运行。它实际上是在64位环境上运行的。
该应用程序检查正在运行的进程(例如,calc.exe),该进程位于c:\windows\syswow64\calc.exe。
那么,为什么该函数
Process.MainModule.Filename
返回c:\windows\system32\calc.exe?当从 SYSWOW64 目录未重定向时,是否可以获得有效的可执行主模块位置?
有哪些可能的解决方法?我写得最快的是以下片段:
bool iWindows = pFilename.StartsWith(@"c:\windows\", StringComparison.InvariantCultureIgnoreCase);
bool iWindowsSystem32 = pFilename.StartsWith(@"c:\windows\system32\", StringComparison.InvariantCultureIgnoreCase);
if ((iWindows == true) || (iWindowsSystem32 == true)) {
string pActualFileName;
if (iWindowsSystem32 == true)
pActualFileName = pFilename.Replace(@"c:\windows\system32\", @"c:\windows\syswow64\");
else
pActualFileName = pFilename.Replace(@"c:\windows\", @"c:\windows\syswow64\");
我错过了什么吗?
A .NET application (managed) runs on Windows 7 64 bit. It is actually running on a 64 bit environment.
The application inspect running process (for example, calc.exe) which is located in c:\windows\syswow64\calc.exe.
So, why the function
Process.MainModule.Filename
returns c:\windows\system32\calc.exe? Is it possible to get the effective executable main module location, when is unredirected from SYSWOW64 directory?
What are possible workarounds? The quickest I wrote is the following snippet:
bool iWindows = pFilename.StartsWith(@"c:\windows\", StringComparison.InvariantCultureIgnoreCase);
bool iWindowsSystem32 = pFilename.StartsWith(@"c:\windows\system32\", StringComparison.InvariantCultureIgnoreCase);
if ((iWindows == true) || (iWindowsSystem32 == true)) {
string pActualFileName;
if (iWindowsSystem32 == true)
pActualFileName = pFilename.Replace(@"c:\windows\system32\", @"c:\windows\syswow64\");
else
pActualFileName = pFilename.Replace(@"c:\windows\", @"c:\windows\syswow64\");
Am I missing something?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
尝试获取程序集,然后获取程序集位置,例如
Try getting the assembly and then getting the assembly location, such as
在使用
Process.MainModule 之前尝试调用 Wow64DisableWow64FsRedirection .文件名
.使用 IsWow64Process 验证程序是否在 64 位操作系统上运行或 Environment.Is64BitOperatingSystem(如果您使用 .NET) 4.0),然后建议使用Wow64DisableWow64FsRedirection。更新:我确信您的代码中有一个小错误,或者问题可能出在您安装的 .NET runtines 上。 测试了以下测试代码的问题
我使用安装在 Vindows 7 64 位 (x64) 上的 .NET 4.0 和 Visual Studio 2010 。在 Vindows 7 64 位上,有两个版本的
calc.exe
:一个 32 位版本位于C:\Windows\SysWOW64\calc.exe
下,另一个 64 位版本位于C:\Windows\SysWOW64\calc.exe
下C:\Windows\system32\calc.exe
。如何轻松验证文件具有不同的文件大小(776,192 和 918.528 字节)。如果我将程序编译为 64 位程序,它会启动C:\Windows\system32\calc.exe
并且Process.GetProcessById(processId).MainModule.FileName
显示也正确文件名。还可以使用 Process.GetProcessById() 来获取单独启动的 32 位版本 calc.exe 的正确路径(请参阅注释行)。所以这个程序的 64 位版本在我的环境中没有问题。如果您有 32 位应用程序,您将能够在调用 Wow64DisableWow64FsRedirection,但是您将无法能够访问64位程序的内存,并且
Process.MainModule
将抛出异常System.ComponentModel.Win32Exception
,代码为NativeErrorCode: 299
和消息:“32 位进程无法访问 64 位进程的模块。”
能够获取 64 位应用程序的完整文件名,您应该使用 API 来获取 64 位操作系统组件(如 WMI 等)生成的结果。但这已经是另一个问题了,因为你编写的程序是64位程序。Try to call Wow64DisableWow64FsRedirection before the usage of
Process.MainModule.Filename
. Verifying that the program are running on 64-bit operation system with IsWow64Process or Environment.Is64BitOperatingSystem (if you use .NET 4.0) before usage of Wow64DisableWow64FsRedirection is recommended.UPDATED: I am sure that you have a small error in your code or the problem can be on .NET runtines which you have installed. I tested your problem with respect of the following test code
with .NET 4.0 and Visual Studio 2010 installed on Vindows 7 64-bit (x64). On Vindows 7 64-bit there are two version of
calc.exe
: one 32-bit underC:\Windows\SysWOW64\calc.exe
and another 64-bit underC:\Windows\system32\calc.exe
. How can easy verify the files has different file size (776,192 and 918.528 bytes). If I compile the program as 64-bit program it startsC:\Windows\system32\calc.exe
andProcess.GetProcessById(processId).MainModule.FileName
shows also correct file name. One can also useProcess.GetProcessById()
to get correct path of 32-bit version of calc.exe which are started separately (see commented lines). So 64-bit versin of this program has no problem in my envoronment.If you do have 32-bit application you will be able to access to the full filesystem after the call of Wow64DisableWow64FsRedirection, but you will not be able to access the memory of 64-bit programs and
Process.MainModule
will throw the excepionSystem.ComponentModel.Win32Exception
with the codeNativeErrorCode: 299
and theMessage: "A 32 bit processes cannot access modules of a 64 bit process."
To be able to get the full filename of 64-bit application you should use API with get you results produced from a 64-bit operation system component (like WMI and so on). But it's already another probelm, because how you wrote your program is 64-bit program.