CommandLineToArgvW 函数
[DllImport("shell32.dll", SetLastError = true)]
private static extern IntPtr CommandLineToArgvW([MarshalAs(UnmanagedType.LPWStr)] string lpCmdLine, out int pNumArgs);
参数:
[in] lpCmdLine 类型: LPCWSTR
指向包含完整命令行的 以 null 结尾的 Unicode 字符串的指针。 如果此参数为空字符串,则函数返回当前可执行文件的路径。
[out] pNumArgs 类型: int*
指向接收返回的数组元素数的 int 的指针,类似于 argc。(有关 argv 和 argc 参数约定的详细信息,请参阅 参数定义 和分析 C Command-Line 参数。 )
返回值:
类型: LPWSTR*
指向 LPWSTR 值数组的指针,类似于 argv。
如果函数失败,则返回值为 NULL。 要获得更多的错误信息,请调用 GetLastError。
CommandLineToArgvW 返回的地址是 LPWSTR 值数组中第一个元素的地址;
此数组中的指针数由 pNumArgs 指示。 指向 以 null 结尾的 Unicode 字符串的每个指针都表示在命令行上找到的单个参有关 argv 和 argc 参数约定的详细信息,请参阅 参数定义 和分析 C Command-Line 参数。
重要说明
CommandLineToArgvW 将引号外的空格视为参数分隔符。 但是,如果 lpCmdLine 以任意数量的空格开头, CommandLineToArgvW 会将第一个参数视为空字符串。 忽略 lpCmdLine 末尾的多余空格。
public static string[] commandLineToArgs(string commandLine){int argc;var argv = CommandLineToArgvW(commandLine, out argc);if (argv == IntPtr.Zero)throw new System.ComponentModel.Win32Exception();try{var args = new string[argc];for (var i = 0; i < args.Length; i++){var p = Marshal.ReadIntPtr(argv, i * IntPtr.Size);args[i] = Marshal.PtrToStringUni(p);}return args;}finally{Marshal.FreeHGlobal(argv);}}
GetCommandLineW 函数可用于获取适合用作 lpCmdLine 参数的命令行字符串。 此函数接受包含程序名称的命令行;程序名称可以用引号括起来,也可以不用引号引起来
private static string[] GetCommandLine(this Process process){using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT CommandLine FROM Win32_Process WHERE ProcessId = " + process.Id))using (ManagementObjectCollection objects = searcher.Get()){var commandLine = objects.Cast<ManagementBaseObject>().SingleOrDefault()?["CommandLine"]?.ToString();if (string.IsNullOrWhiteSpace(commandLine))return new string[] { };return commandLineToArgs(commandLine);}}
参考文献:
1. https://www.cnblogs.com/nanfei/p/14005863.html
2. CommandLineToArgvW 函数 (shellapi.h) - Win32 apps | Microsoft Learn
该部分的解释可查看以下进行对应(这部分内容在分析 C 命令行自变量 | Microsoft Learn):
3. 分析 C 命令行自变量 | Microsoft Learn
4. GetCommandLineW 函数 (processenv.h) - Win32 apps | Microsoft Learn