如何在c#中获取二进制文件的路径?

时间:2013-05-21 01:41:22

标签: c#

出于某些报告目的,我正试图获取某个二进制文件的位置。

我这样做了,它正在工作,但是当我尝试获取testProc.MainModule.FileName时,我现在得到一个NullReferenceException;而且我认为可能是程序在我能够抓住之前关闭。有没有更好的方法呢?

ProcessStartInfo testPSI = new ProcessStartInfo(RunOptions.TestBinary);
testPSI.RedirectStandardError = true;
testPSI.RedirectStandardOutput = true;
testPSI.UseShellExecute = false;
Process testProc = new Process();
testProc.StartInfo = testPSI;   
testProc.Start();
ret = testProc.MainModule.FileName;
testProc.Kill();
if (ret != null)
    return ret;

1 个答案:

答案 0 :(得分:3)

选项1:使用您已有的路径。

除非我遗漏了某些内容,否则您自己创建了该过程(使用RunOptions.TestBinary),因此您应该已经知道该路径。您可以使用Path.GetFullPath(RunOptions.TestBinary)获取可执行文件的完整路径,或者如果二进制文件位于PATH上,您可以手动检查每个目录以确定执行二进制文件的位置。

选项2:使用C#的WMI库:

如果测试主机进程与正在执行的进程之间的位数(32位/ 64位)存在差异,则枚举模块和获取文件名将不起作用。但是,您可以使用WMI来解决此限制。

添加对System.Management的引用并尝试以下操作(警告:无错误处理):

static string GetImagePath(int processId)
{
    string query = string.Format("SELECT ExecutablePath FROM Win32_Process WHERE ProcessID='{0}'", processId);
    ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
    ManagementObjectCollection results = searcher.Get();
    ManagementObject process = results.Cast<ManagementObject>().First();
    return (string)process["ExecutablePath"];
}

选项3:向目标进程添加同步:

如果这确实是一个计时问题(即被监视的进程在测试进程可以检查它之前就已经死了),那么您可以在两个进程之间添加一些同步(例如,命名的互斥)。如果您真的想深入挖掘,可以使用ETW来捕获流程启动事件(见下文)。

选项4:使用the TraceEvent .NET library捕获流程启动事件。

Vance Morrison(编写了TraceEvent库)有an in-depth article关于如何捕获进程启动事件的信息。这个解决方案确实需要引入一堆依赖关系,但由于它使用ETW,因此不存在计时问题(即使进程快速死亡,进程启动事件仍然被触发)。这是迄今为止最复杂的解决方案。