CreateProcess and installshield's uninstall strings
I'm calling pInvoke to call the Kernel's CreateProcess() and passing it the UninstallString of some app I'd like to uninstall. This UninstallString is the same thing Add/Remove Programs executes when you try to Uninstall an application. This call to CreateProcess() seems to work for all MSI UninstallStrings such as:
MsiExec.exe /I{88BAE373-00F4-3E33-828F-96E89E5E0CB9}
but doesn't launch anything for InstallShield UninstallStrings such as: RunDll32 C:\PROGRA~2\COMMON~1\INSTAL~1\PROFES~1\RunTime\10\50\Intel32\Ctor.dll,LaunchSetup "C:\Program Files (x86)\InstallShield Installation Information{34B37A74-125E-4406-87BA-E4BD3D097AE5}\setup.exe" -l0x9 -removeonly
What am I missing? If I run the same UninstallString inside a command line window it runs and launches the uninstaller. I tried ShellExecute() but doesn't seem to work either. I know I could parse the Uninstall string into the executable (Rundll32) and the rest as arguments and pass them to the managed Process class as StartInfo but I woud like to avoid having a special case just for InstallShield strings, especially since the command line runs the string fine.
Any ideas?
[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_IN开发者_StackOverflow中文版FORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
This may not be your issue but create process needs to have the startup info structure zeroed out ie ZeroMemory. Also the cb parameter needs to be set to the size of the structure.
My problem was that I was passing in the uninstall string via c# command line args. But when the uninstall string contained quotes (like setup.exe "c\program files...") these quotes were removed by the compiler. So in order to work around my problem, I am replacing them before passing them in with triples. str.Replace("\"", "\"\"\"") and it does the trick.
Thanks, kj
精彩评论