.NET/C# 獲取一個正在運行的進程的命令行參數
- 2020 年 2 月 10 日
- 筆記
在自己的進程內部,我們可以通過 Main
函數傳入的參數,也可以通過 Environment.GetCommandLineArgs
來獲取命令行參數。
但是,可以通過什麼方式來獲取另一個運行著的程式的命令行參數呢?
進程內部獲取傳入參數的方法,可以參見我的另一篇部落格:.NET 命令行參數包含應用程式路徑嗎?。
.NET Framework / .NET Core 框架內部是不包含獲取其他進程命令行參數的方法的,但是我們可以在任務管理器中看到,說明肯定存在這樣的方法。

實際上方法是有的,不過這個方法是 Windows 上的專屬方法。
對於 .NET Framework,需要引用程式集 System.Management
;對於 .NET Core 需要引用 Microsoft.Windows.Compatibility
這個針對 Windows 系統準備的兼容包(不過這個兼容包目前還是預覽版本)。
<ItemGroup Condition="$(TargetFramework) == 'netcoreapp2.1'"> <PackageReference Include="Microsoft.Windows.Compatibility" Version="2.1.0-preview.19073.11" /> </ItemGroup> <ItemGroup Condition="$(TargetFramework) == 'net472'"> <Reference Include="System.Management" /> </ItemGroup>
然後,我們使用 ManagementObjectSearcher
和 ManagementBaseObject
來獲取命令行參數。
為了簡便,我將其封裝成一個擴展方法,其中包括對於一些異常的簡單處理。
using System; using System.Diagnostics; using System.Linq; using System.Management; namespace Walterlv { /// <summary> /// 為 <see cref="Process"/> 類型提供擴展方法。 /// </summary> public static class ProcessExtensions { /// <summary> /// 獲取一個正在運行的進程的命令行參數。 /// 與 <see cref="Environment.GetCommandLineArgs"/> 一樣,使用此方法獲取的參數是包含應用程式路徑的。 /// 關於 <see cref="Environment.GetCommandLineArgs"/> 可參見: /// .NET 命令行參數包含應用程式路徑嗎?https://blog.walterlv.com/post/when-will-the-command-line-args-contain-the-executable-path.html /// </summary> /// <param name="process">一個正在運行的進程。</param> /// <returns>表示應用程式運行命令行參數的字元串。</returns> public static string GetCommandLineArgs(this Process process) { if (process is null) throw new ArgumentNullException(nameof(process)); try { return GetCommandLineArgsCore(); } catch (Win32Exception ex) when ((uint) ex.ErrorCode == 0x80004005) { // 沒有對該進程的安全訪問許可權。 return string.Empty; } catch (InvalidOperationException) { // 進程已退出。 return string.Empty; } string GetCommandLineArgsCore() { using (var searcher = new ManagementObjectSearcher( "SELECT CommandLine FROM Win32_Process WHERE ProcessId = " + process.Id)) using (var objects = searcher.Get()) { var @object = objects.Cast<ManagementBaseObject>().SingleOrDefault(); return @object?["CommandLine"]?.ToString() ?? ""; } } } } }
使用此方法得到的命令行參數是一個字元串,而不是我們通常使用字元串時的字元串數組。如果你需要將其轉換為字元串數組,可以使用我在另一篇部落格中使用的方法:
參考資料
- Can I get command line arguments of other processes from .NET/C#? – Stack Overflow
- How to get Command Line info for a process in PowerShell or C# – Stack Overflow
本文會經常更新,請閱讀原文: https://blog.walterlv.com/post/get-command-line-for-a-running-process.html ,以避免陳舊錯誤知識的誤導,同時有更好的閱讀體驗。
本作品採用 知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議 進行許可。歡迎轉載、使用、重新發布,但務必保留文章署名 呂毅 (包含鏈接: https://blog.walterlv.com ),不得用於商業目的,基於本文修改後的作品務必以相同的許可發布。如有任何疑問,請 與我聯繫 ([email protected]) 。