您面临的问题是可执行文件名称和一些参数已经在您的变量中commandPath(不仅是路径,还有一些参数)。如果第一部分仅由字符组成(没有空格),将可执行文件与参数分开不会太难,但这是 Windows,所以你可能有空格,所以你被卡住了。所以它看起来。
解决方案是不使用Process.Start,也不使用ShellExecute。Process.Start,无论您要求它使用ShellExecute还是CreateProcess,在这两种情况下,它都需要设置FileName参数/成员,该参数/成员按原样传递给 CreateProcess 和 ShellExecute。
那怎么办?而是简单地说:使用CreateProcess自己。该 API 函数的一个鲜为人知的特性是,您可以将完整的命令行传递给它,就像在 WinKey+R (Windows Run) 下一样。您要求的“魔术”可以通过将其第一个参数设置为null并将其第二个参数设置为完整路径(包括所有参数)来实现。如下所示,它将为您启动Windows 照片库,同时使用与参数相同的字符串,Process.Start任何方式都会产生“找不到文件”错误:
STARTUPINFO si = new STARTUPINFO();
PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
CreateProcess(
/* app name */ null,
/* cmd line */ @"C:\Program Files\Windows Photo Gallery\WindowsPhotoGallery.exe testBogusParam",
/* proc atts */ IntPtr.Zero,
/* thread atts */ IntPtr.Zero,
/* inh handles */ false,
/* create flags */ 0,
/* env ptr */ IntPtr.Zero,
/* current dir */ null,
/* startupinfo */ ref si,
/* processinfo */ out pi);
请注意,我故意没有在可执行路径周围包含引号。但是,如果可执行路径有引号,就像上面的代码一样,它仍然可以工作,所有的魔法都在那里。将其与您的代码片段相结合,以下将以您想要的方式启动该过程:
/* with your code */
String commandPath = ReadFromRegistry();
String fullCommand = commandPath + " " + fileName; // assuming not %1
STARTUPINFO si = new STARTUPINFO();
PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
CreateProcess(
null,
fullCommand,
IntPtr.Zero,
IntPtr.Zero,
false,
0,
IntPtr.Zero,
null,
ref si,
out pi);
声明是您可以从http://www.pinvoke.net获得的内容,但为了方便起见,这里是应该粘贴在类部分中以使上述内容生效的部分。这些函数的参考,如何检查结果(成功/失败)STARTUPINFO和PROCESS_INFORMATION结构可以在微软的 MSDN中找到。为方便起见,我建议将调用CreateProcess放在实用程序函数中。
/* place the following at the class level */
[DllImport("kernel32.dll")]
static extern bool CreateProcess(
string lpApplicationName,
string lpCommandLine,
IntPtr lpProcessAttributes,
IntPtr lpThreadAttributes,
bool bInheritHandles,
uint dwCreationFlags,
IntPtr lpEnvironment,
string lpCurrentDirectory,
ref STARTUPINFO lpStartupInfo,
out PROCESS_INFORMATION lpProcessInformation);
public struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public uint dwProcessId;
public uint dwThreadId;
}
public struct STARTUPINFO
{
public uint cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public uint dwX;
public uint dwY;
public uint dwXSize;
public uint dwYSize;
public uint dwXCountChars;
public uint dwYCountChars;
public uint dwFillAttribute;
public uint dwFlags;
public short wShowWindow;
public short cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
希望我正确理解了您的问题。如果您在实现上述代码时遇到问题,请告诉我。