相当于Process.Start(),没有单独的参数

本文关键字:没有单 参数 Process Start 相当于 | 更新日期: 2023-09-27 17:53:12

我正在编写一个需要运行任意命令的简单应用程序,例如:

powershell -File myscript.ps1
cmd /C "ping localhost"

Process.Start()将是完美的,除了它需要将参数作为单独的参数给出。最初我认为我可以在第一个空格字符上分割字符串,但是如果可执行路径被引用并包含空格怎么办?是否有像Process.Start()这样的东西允许您只给它一个字符串,带或不带参数,并让它像粘贴到命令提示符一样执行它?

相当于Process.Start(),没有单独的参数

为什么不直接通过cmd/C运行所有内容呢?

Process.Start("cmd", "/C " + command);

直接调用CreateProcess函数:

public static class Native
{
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    private struct STARTUPINFO
    {
        public Int32 cb;
        public string lpReserved;
        public string lpDesktop;
        public string lpTitle;
        public Int32 dwX;
        public Int32 dwY;
        public Int32 dwXSize;
        public Int32 dwYSize;
        public Int32 dwXCountChars;
        public Int32 dwYCountChars;
        public Int32 dwFillAttribute;
        public Int32 dwFlags;
        public Int16 wShowWindow;
        public Int16 cbReserved2;
        public IntPtr lpReserved2;
        public IntPtr hStdInput;
        public IntPtr hStdOutput;
        public IntPtr hStdError;
    }
    [StructLayout(LayoutKind.Sequential)]
    private struct PROCESS_INFORMATION
    {
        public IntPtr hProcess;
        public IntPtr hThread;
        public int dwProcessId;
        public int dwThreadId;
    }
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    private static extern bool CreateProcess(
        string lpApplicationName,
        string lpCommandLine,
        IntPtr lpProcessAttributes,
        IntPtr lpThreadAttributes,
        bool bInheritHandles,
        uint dwCreationFlags,
        IntPtr lpEnvironment,
        string lpCurrentDirectory,
        [In] ref STARTUPINFO lpStartupInfo,
        out PROCESS_INFORMATION lpProcessInformation);
    public static void CreateProcessFromCommandLine(string commandLine)
    {
        var si = new STARTUPINFO();
        var pi = new PROCESS_INFORMATION();
        CreateProcess(
            null,
            commandLine,
            IntPtr.Zero,
            IntPtr.Zero,
            false,
            0,
            IntPtr.Zero,
            null,
            ref si,
            out pi);
    }
}
internal class Program
{
    public static void Main()
    {
        Native.CreateProcessFromCommandLine("ping google.com -t");
        Console.Read();
    }
}

您可以使用Path类来计算命令行字符串,并像这样运行Process.Start:

// This is our command string
var cmd = @"C:'Program Files'Sub folder 1'executable name.exe -arg1 -arg2 -argN"; 
var exeName = Path.GetFileName(cmd); // "executable name.exe -arg1 -arg2 -argN"
var borderPos = exeName.IndexOf(".exe") // or .cmd, .bat, etc.
borderPos = borderPos == -1 ? exeName.IndexOf(" ") : borderPos + 4;
var arguments = exeName.Substring(borderPos).Trim();
var program = cmd.Substring(0, cmd.Length - arguments.Length);
Process.Start(program, aguments);

类似这样的代码应该可以做到这一点,但是上面的代码是未经测试的…