获取有效的可执行文件名

发布于 2024-09-16 11:21:33 字数 918 浏览 8 评论 0原文

.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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

顾挽 2024-09-23 11:21:33

尝试获取程序集,然后获取程序集位置,例如

System.Reflection.Assembly.GetExecutingAssembly().Location 

Try getting the assembly and then getting the assembly location, such as

System.Reflection.Assembly.GetExecutingAssembly().Location 
我不会写诗 2024-09-23 11:21:33

在使用 Process.MainModule 之前尝试调用 Wow64DisableWow64FsRedirection .文件名.使用 IsWow64Process 验证程序是否在 64 位操作系统上运行或 Environment.Is64BitOperatingSystem(如果您使用 .NET) 4.0),然后建议使用Wow64DisableWow64FsRedirection

更新:我确信您的代码中有一个小错误,或者问题可能出在您安装的 .NET runtines 上。 测试了以下测试代码的问题

using System;
using System.Diagnostics;

namespace Win64ProcesPath {
    class Program {
        static void Main (string[] args) {
            Process myProcess = new Process ();

            try {
                myProcess.StartInfo.UseShellExecute = false;
                myProcess.StartInfo.FileName = "calc.exe";
                myProcess.StartInfo.CreateNoWindow = true;
                myProcess.Start ();
                System.Threading.Thread.Sleep (1000);
                Console.WriteLine ("{0}", myProcess.MainModule.FileName);

                Process p = Process.GetProcessById (myProcess.Id);
                Console.WriteLine ("{0}", p.MainModule.FileName);

                //Process p32 = Process.GetProcessById (8048);
                //Console.WriteLine ("{0}", p32.MainModule.FileName);
            }
            catch (Exception e) {
                Console.WriteLine (e.Message);
            }
        }
    }
}

我使用安装在 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.exeC:\Windows\system32\calc.exe。如何轻松验证文件具有不同的文件大小(776,192 和 918.528 字节)。如果我将程序编译为 64 位程序,它会启动 C:\Windows\system32\calc.exe 并且 Process.GetProcessById(processId).Ma​​inModule.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

using System;
using System.Diagnostics;

namespace Win64ProcesPath {
    class Program {
        static void Main (string[] args) {
            Process myProcess = new Process ();

            try {
                myProcess.StartInfo.UseShellExecute = false;
                myProcess.StartInfo.FileName = "calc.exe";
                myProcess.StartInfo.CreateNoWindow = true;
                myProcess.Start ();
                System.Threading.Thread.Sleep (1000);
                Console.WriteLine ("{0}", myProcess.MainModule.FileName);

                Process p = Process.GetProcessById (myProcess.Id);
                Console.WriteLine ("{0}", p.MainModule.FileName);

                //Process p32 = Process.GetProcessById (8048);
                //Console.WriteLine ("{0}", p32.MainModule.FileName);
            }
            catch (Exception e) {
                Console.WriteLine (e.Message);
            }
        }
    }
}

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 under C:\Windows\SysWOW64\calc.exe and another 64-bit under C:\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 starts C:\Windows\system32\calc.exe and Process.GetProcessById(processId).MainModule.FileName shows also correct file name. One can also use Process.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 excepion System.ComponentModel.Win32Exception with the code NativeErrorCode: 299 and the Message: "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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文