【发布时间】:2011-09-10 12:28:48
【问题描述】:
我正在调用 pInvoke 来调用内核的 CreateProcess() 并将我想卸载的某个应用程序的 UninstallString 传递给它。当您尝试卸载应用程序时,此 UninstallString 与添加/删除程序执行的操作相同。对 CreateProcess() 的调用似乎适用于所有 MSI UninstallStrings,例如:
MsiExec.exe /I{88BAE373-00F4-3E33-828F-96E89E5E0CB9}
但不会为 InstallShield UninstallStrings 启动任何内容,例如: RunDll32 C:\PROGRA~2\COMMON~1\INSTAL~1\PROFES~1\RunTime\10\50\Intel32\Ctor.dll,LaunchSetup "C:\Program Files (x86)\InstallShield 安装信息{34B37A74-125E -4406-87BA-E4BD3D097AE5}\setup.exe" -l0x9 -removeonly
我错过了什么?如果我在命令行窗口中运行相同的 UninstallString,它会运行并启动卸载程序。我尝试了 ShellExecute() 但似乎也不起作用。我知道我可以 将 Uninstall 字符串解析为可执行文件(Rundll32),其余作为参数并将它们作为 StartInfo 传递给托管 Process 类,但我想避免仅针对 InstallShield 字符串出现特殊情况,特别是因为命令行可以正常运行字符串。
有什么想法吗?
[DllImport("kernel32.dll")]
public 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);
PROCESS_INFORMATION pi = new ProcessUtils.PROCESS_INFORMATION();
STARTUPINFO si = new ProcessUtils.STARTUPINFO();
CreateProcess(null, path, IntPtr.Zero, IntPtr.Zero, false, 0, IntPtr.Zero, null, ref si, out pi);
int pID = pi.dwProcessId;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public 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)]
public struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
【问题讨论】:
-
添加您的呼叫代码。我向你保证,使用 .net 类会更容易。
-
我没有调用 System.Diagnostics.Process.Start 因为它不会启动它。我将不得不解析它并将可执行文件与将通过 ProcessStartinfo 传递的参数分开。
-
我确实添加了调用代码。见上文... CreateProcess(null, path, IntPtr.Zero, IntPtr.Zero, false, 0, IntPtr.Zero, null, ref si, out pi);
标签: c#