2

いくつかのレポート目的で、特定のバイナリの場所を取得しようとしています。

私はこれを行っていて、機能していましたが、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;
4

1 に答える 1

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:ターゲット プロセスに同期を追加します。

これが本当にタイミングの問題である場合 (つまり、テスト プロセスが調べる前に監視対象のプロセスが停止している場合)、2 つのプロセス間に何らかの同期 (名前付きミューテックスなど) を追加できます。本当に深く掘り下げたい場合は、ETWを使用してプロセス開始イベントをキャプチャできます (以下を参照)。

オプション 4: TraceEvent .NET ライブラリを使用して、プロセス開始イベントをキャプチャします。

Vance Morrison (TraceEvent ライブラリの作成者) は、プロセス開始イベントをキャプチャする方法に関する詳細な記事を公開しています。このソリューションでは、多数の依存関係を取り込む必要がありますが、ETW を使用しているため、タイミングの問題はありません (プロセスがすぐに終了しても、プロセス開始イベントは引き続き発生します)。これは、最も複雑なソリューションです。

于 2013-05-21T02:03:40.397 に答える