【问题标题】:CreateProcess and installshield's uninstall stringsCreateProcess 和 installshield 的卸载字符串
【发布时间】: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#


【解决方案1】:

我的问题是我通过 c# 命令行参数传递了卸载字符串。但是当卸载字符串包含引号时(如 setup.exe "c\program files..."),编译器会删除这些引号。所以为了解决我的问题,我在用三元组传递它们之前替换它们。 str.Replace("\"", "\"\"\"") 就可以了。

谢谢, kj

【讨论】:

    【解决方案2】:

    这可能不是您的问题,但创建过程需要将启动信息结构清零,即 ZeroMemory。还需要将 cb 参数设置为结构体的大小。

    【讨论】:

    • 我不确定你最后的提示是什么意思。对 msiexec.exe 的调用需要插入到卸载字符串的哪个位置?知道为什么在命令行提示符下运行相同的字符串吗?
    • 我什至尝试了一个简单的卸载字符串:"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 进程运行并立即退出。当我在命令行提示符中复制并粘贴相同内容时,安装程​​序运行。
    猜你喜欢
    • 2011-02-25
    • 2011-02-24
    • 1970-01-01
    • 2012-01-27
    • 2012-02-12
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 2013-12-10
    相关资源
    最近更新 更多