Получить эффективное исполняемое имя файла - PullRequest
1 голос
/ 25 августа 2010

Приложение .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\");

Я что-то упустил?

Ответы [ 2 ]

0 голосов
/ 25 августа 2010

Попробуйте получить сборку, а затем получить место сборки, например

System.Reflection.Assembly.GetExecutingAssembly().Location 
0 голосов
/ 25 августа 2010

Попробуйте позвонить Wow64DisableWow64FsRedirection перед использованием Process.MainModule.Filename.Перед использованием Wow64DisableWow64FsRedirection рекомендуется убедиться, что программа работает в 64-разрядной операционной системе с IsWow64Process или Environment.Is64BitOperatingSystem (если вы используете .NET 4.0)..

ОБНОВЛЕНО : Я уверен, что у вас небольшая ошибка в вашем коде, или проблема может быть в .NET-рутинах, которые вы установили.Я проверил вашу проблему в отношении следующего тестового кода

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);
            }
        }
    }
}

с .NET 4.0 и Visual Studio 2010, установленной в 64-разрядной версии Windows 7 (x64).В 64-разрядной версии Windows 7 есть две версии calc.exe: одна 32-разрядная под C:\Windows\SysWOW64\calc.exe и другая 64-разрядная под 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 и Message: "A 32 bit processes cannot access modules of a 64 bit process.", чтобы иметь возможность получитьполное имя файла 64-битного приложения, вы должны использовать API, чтобы получить результаты, полученные из компонента 64-битной операционной системы (например, WMI и т. д.).Но это уже другая проблема, потому что то, как вы написали свою программу, является 64-битной программой.

...