【问题标题】:Using Microsoft.Deployment.WindowsInstaller.Installer.ConfigureProduct to uninstall silently?使用 Microsoft.Deployment.WindowsInstaller.Installer.ConfigureProduct 静默卸载?
【发布时间】:2018-09-12 02:45:22
【问题描述】:

我无法使用 ConfigureProduct 安静地运行卸载。我有以下内容:

using Microsoft.Deployment.WindowsInstaller;

Installer.ConfigureProduct(productCode, 0, InstallState.Absent, "/q");

根据之前的一些帖子,“/q”应该可以工作,但每次运行代码时都会出现以下异常。

"Invalid command line argument. Consult the Windows Installer SDK for detailed command line help."

请注意,“/q”在使用 msiexec.exe 时确实有效,但我想使用 Microsoft.Deployment.WindowsInstaller 来执行此操作。

我还尝试通过以下方式将 UI 设置为静音:

Installer.SetInternalUI(InstallUIOptions.Silent);
Installer.ConfigureProduct(productCode, 0, InstallState.Absent, "");

然后我得到以下异常:

"Fatal error during installation."

从消息中我收集到 SetInternalUI 用于安装而不是卸载但不确定。

我正在使用来自 WiX 3.9 R2 安装的 DLL,即版本 2.0.50727。

感谢任何帮助。谢谢!

编辑:我仔细查看了“ConfigureProduct”方法中“commandLine”参数的 cmets。

    //   commandLine:
    //     Specifies the command line property settings. This should be a list of the
    //     format Property=Setting Property=Setting.

所以基本上不,你不能传递“/q”、“/l”或其他任何不是“Property=Setting”形式的东西。答案中链接的参考帖子中的示例似乎是错误的。 (或者版本之间发生了一些变化,但我对此表示怀疑。)

【问题讨论】:

    标签: c# wix windows-installer


    【解决方案1】:

    如果它正常卸载而没有任何错误,那么最可能的问题是卸载需要提升并且您的代码没有运行提升,因此它失败了。在静默卸载期间,它不会要求用户提升!

    SetInternalUI 适用于卸载。例如,以下 C++ sn-p 完全符合您的要求,使卸载完全静默:

    INSTALLUILEVEL il = MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
    UINT n = MsiConfigureProductEx(productid, INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT, L"REBOOT=R"); 
    

    并且该 ConfigureProduct 调用使用相同的 API。

    【讨论】:

    • 是的,这就是我收到致命错误的原因。我从提升的命令提示符启动该程序,它工作。有没有一种简单的方法可以使用 Microsoft.Deployment.WindowsInstaller API 在提升模式下运行 ConfigureProduct?
    【解决方案2】:

    试试这个关于卸载 MSI 文件的不同方法的参考(选项 6 描述了 DTF):

    很遗憾,我目前没有可用于测试的 Visual Studio - 尽管我无法测试任何东西,但我仍然会试一试。不用说,这使回答变得困难:

    • 您的静默卸载程序可能会崩溃,这就是它在静默模式下失败的原因。
    • 通常这将涉及一个自定义操作,该操作可能无法正确调节并且运行不当(或在静默模式下运行时根本不运行)。

    尝试在静默卸载期间启用日志记录,如此处所示(适当调整日志文件的路径)。特殊的 ! 标志将刷新日志文件 - 这意味着它是连续写入而不是分批写入,因此不会因任何潜在的崩溃而丢失日志记录(这会减慢 (un)安装过程相当):

    using Microsoft.Deployment.WindowsInstaller;
    
    public static void Uninstall( string productCode)
    {
       Installer.SetInternalUI(InstallUIOptions.Silent);
       Installer.ConfigureProduct(productCode, 0, InstallState.Absent, "REBOOT=\"R\" /L*V! c:\uninstall.log");
    }
    

    要在日志文件中查找相关信息,请查看此log file checking tip from Rob Mensching(Wix 的创建者)。

    【讨论】:

    • 哇,你花了多长时间才写完?而且您一定真的很想找到我仍在使用 VBScript 的时间。 :)
    • 似乎是 10 年。似乎可怜的 Puneet 不知道“foo”是什么意思。 community.flexerasoftware.com/…
    • 那是编辑和扩展数十次的“进化主题”之一。并且 VBScripts 已经足够好用了。不是很好,但简单而有效地处理世界上最糟糕的错误。
    • 是的,我记得我曾嘲笑你的维基百科链接:en.wikipedia.org/wiki/Foo :-)。
    • 世界上最糟糕的错误处理和病毒扫描程序拦截是当今脚本无法接受的原因。我无法告诉你有多少次我看到“on error resume next”以非常非常糟糕的方式结束。
    【解决方案3】:

    只是为了通过链接到新答案来提供更好的答案: Uninstalling program

    UAC 和 GUI:基本上您的静默卸载失败,因为它在没有提升的情况下运行。当以交互方式运行时,您会收到 UAC 提示并可以提升权限 - 只要您的帐户是管理员帐户并允许您这样做。当静默运行时,这种提升不会发生,并且卸载失败。解决方案是运行提升的应用程序可执行文件。

    异常处理:您可能还想使用适当的异常处理来确保向用户报告因缺少提升而导致的错误消息。有关示例,请参见上面链接中的代码。这是一个快速内联部分:

    try
      {
        Installer.SetInternalUI(InstallUIOptions.Silent); // Set MSI GUI level
        Installer.ConfigureProduct(productcode, 0, InstallState.Absent, "REBOOT=\"ReallySuppress\"");
      }
      catch (Exception e)
      {
         Console.WriteLine("Exception: " + e.Message);
         Console.ReadLine (); // Keep console window open
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-30
      • 2017-09-10
      • 2011-09-11
      • 2020-11-26
      • 1970-01-01
      • 2018-07-10
      • 2012-12-29
      • 2011-06-26
      相关资源
      最近更新 更多