2011-06-08 66 views
1

我打電話給pInvoke調用內核的CreateProcess()並將它傳遞給我想要卸載的某個應用程序的UninstallString。此UninstallString與您嘗試卸載應用程序時執行的「添加/刪除程序」相同。這個調用給CreateProcess(),似乎所有的MSI UninstallStrings如工作:CreateProcess和installshield的卸載字符串

MSIEXEC.EXE/I {88BAE373-00F4-3E33-828F-96E89E5E0CB9}

,但不會推出針對的InstallShield UninstallStrings這樣的事情as: 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; 
    } 
+0

爲什麼不叫'System.Diagnostics.Process.Start'? – 2011-06-08 01:04:48

+0

添加您的電話代碼。我向你保證,使用.net類會更容易。 – rerun 2011-06-08 01:05:50

+0

我沒有調用System.Diagnostics.Process.Start,因爲它沒有啓動它。我將不得不解析它,並將可執行文件與將通過ProcessStartinfo傳遞的參數分開。 – user577240 2011-06-08 01:14:11

回答

0

我的問題是,我通過c#命令行參數傳遞卸載字符串。但是,當卸載字符串包含引號(如setup.exe「c \ program files ...」)時,這些引號被編譯器刪除。所以爲了解決我的問題,我將它們替換爲三元組。 str.Replace(「\」「,」\「\」\「」),它的竅門。

感謝, KJ

0

這可能不是你的問題,但創建過程中需要有啓動信息結構歸零即ZeroMemory。還需要將cb參數設置爲結構的大小。

+0

我不確定您的最後一條提示是什麼意思。需要在卸載字符串中插入對msiexec.exe的調用?任何想法爲什麼運行相同的字符串在命令行提示符內工作? – user577240 2011-06-08 01:31:40

+0

我甚至用一個簡單的uninstallstring嘗試:「C:\ Windows \ SysWOW64 \ RunDll32.EXE」「C:\ Program Files \ NVIDIA Corporation \ Installer2 \ installer.1 \ NVI2.DLL」,UninstallPackage Display.3DVision沒有運氣。即使嘗試使用pInfo.FileName =「C:\ Windows \ SysWOW64 \ RunDll32.EXE」和pInfo.Arguments =「C:\ Program Files \ NVIDIA Corporation \ Installer2 \ installer.1 \ NVI2.DLL」,UninstallPackage Display.3DVision with沒有運氣。發生什麼事是RunDll32.exe進程運行並立即退出。當我將它們複製並粘貼到命令行提示符中時,運行該設置。 – user577240 2011-06-08 04:17:28

相關問題