【问题标题】:WIX Install .NET and VSTO if Admin, fail early if non-AdminWIX 如果管理员安装 .NET 和 VSTO,如果非管理员则提前失败
【发布时间】:2014-02-28 23:02:38
【问题描述】:

我正在尝试将 Excel 插件部署到大众市场。该插件需要 VSTO 运行时 (vstor_redist.exe) 和 .NET 4.5(适用于 64 位操作系统)或 .NET 4.0(适用于 32 位操作系统)。我愿意假设潜在用户至少已经拥有 .NET 2.0。目前我的设置包括:

  1. 单独的 32 位和 64 位 WIX .msi 安装程序以每用户模式安装插件。
  2. 单独的 32 位和 64 位引导程序包,它们包装每个 .msi 并安装 VSTO 运行时和 .NET,如下面的代码所示:

    <util:RegistrySearch Id="VSTORuntimeTest" Root="HKLM" Key="SOFTWARE\Microsoft\VSTO Runtime Setup\v4R\" Value="VSTORFeature_CLR40" Variable="VSTORFeature"/>
    <util:RegistrySearch Id="VSTORuntimeVersionV4R" Root="HKLM" Key="SOFTWARE\Microsoft\VSTO Runtime Setup\v4R\" Value="Version" Variable="VSTORVersionV4R"/>
    <util:RegistrySearch Id="VSTORuntimeVersionV4" Root="HKLM" Key="SOFTWARE\Microsoft\VSTO Runtime Setup\v4\" Value="Version" Variable="VSTORVersionV4"/>
    
    <Chain>
      <!-- Install .Net 4.0 or 4.5, depending on build -->
      <?ifdef x64?>
      <PackageGroupRef Id="NetFx45Web" />
      <?endif ?>
    
      <?ifdef x86?>
      <PackageGroupRef Id="NetFx40Web" />
      <?endif ?>
      <RollbackBoundary />
    
      <!-- Install VSTO runtime -->
      <ExePackage Id="VSTORuntime" SourceFile="..\resources\vstor_redist.exe" Permanent="yes" Vital="yes" Cache="no" Compressed="no"
                  DownloadUrl="http://go.microsoft.com/fwlink/?LinkId=158917"
                  PerMachine="yes"
                  InstallCommand="/q /norestart"
                  DetectCondition="VSTORFeature"
                  InstallCondition="NOT VSTORFeature OR NOT (VSTORVersionV4R >=v10.0.40303) OR NOT (VSTORVersionV4 >=v10.0.21022)" />
      <RollbackBoundary />
    
      <?ifdef x64?>
      <MsiPackage
        Id="nx_msi_package_version"
        SourceFile="..\My 64 bit Setup.msi"
        Compressed="yes"
        Vital="yes" />
      <?endif ?>
    
      <?ifdef x86?>
      <MsiPackage
        Id="nx_msi_package_version"
        SourceFile="..\My 32 bit Setup.msi"
        Compressed="yes"
        Vital="yes" />
      <?endif ?>
    
    </Chain>
    
  3. 一个 .NET 2.0 包装器,其中包括作为嵌入式资源的引导程序,并为客户端操作系统部署和运行正确的引导程序。 (基本上是 Yochai Timmer 在Single MSI to install correct 32 or 64 bit c# application 中的回答)

整个事情感觉就像一个土鸡,但是当用户拥有管理员凭据时,它可以很好地用于静默升级和全新安装。但是,如果用户不是管理员并且还没有安装 VSTO 和适当的 .NET,那么它会在长时间下载后不正常地失败并出现错误:“0x8007051b - 此安全 ID 可能未分配为对象的所有者”过程。

我想做的是提前检查用户是否需要要求管理员干预并为他们安装 VTSO 和/或 .NET,并显示一条消息,最好是带有网站链接,当这是案子。这个检查可以在引导程序中,也可以在我的 .NET 2.0 包装器中。关于如何最好地做到这一点的任何建议?

谢谢,埃里克

【问题讨论】:

    标签: wix vsto burn


    【解决方案1】:

    对我来说最好的方法是在我的 32 位 C# 包装器中完成这项工作。正如我的问题中的代码所示,Burn 似乎没有提供任何支持 VSTO 的内置软件包——相反,我只是手动读取注册表并以此为基础。 Burn 确实为 .NET 4.0 和 .NET 4.5 提供了预构建的包,但我没有看到用这些支持 Fail Early 的简单方法。

    我的 C# 2.0 包装器现在包含以下逻辑:

        private static bool NeedsMorePermissionToInstallPrerequisites(out string error)
        {
            error = string.Empty;
    
            // Is user an admin?  If so, we're OK
            if (PrivilegeTester.CanBeAdmin())
            {
                return false;
            }
    
            // Is .NET already installed?
            bool isDotNetInstalled;
            string dotNetVersion;
            if (Is64BitOperatingSystem())
            {
                isDotNetInstalled = PrereqSoftwareChecker.IsDotNet45Installed();
                dotNetVersion = "Microsoft .NET 4.5";
            }
            else
            {
                isDotNetInstalled = PrereqSoftwareChecker.IsDotNet40Installed();
                dotNetVersion = "Microsoft .NET 4.0";
            }
    
            // Is VTSO already installed?
            bool isVtsoInstalled = PrereqSoftwareChecker.IsVstoRuntimeInstalled();
    
            if (isVtsoInstalled && isDotNetInstalled)
            {
                return false;
            }
    
            // If we got this far, there's trouble.  Build the error.
            [...]
    

    这里的 CanBeAdmin() 功能基于 Calling IPrincipal.IsInRole on Windows 7,而 IsVstoRuntimeInstalled() 会查看我在 VSTORuntimeTest 中使用的完全相同的一组注册表项,等等。在我的原始问题中的逻辑。 .NET 检查还使用 MSDN 中详细记录的密钥查看注册表。例如:

        internal static bool IsDotNet40Installed()
        {
            try
            {
                Version dotnet4Version  = new Version(GetHKLMValue("SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4.0\\Client", "Version").ToString());
                return dotnet4Version >= new Version("4.0.0.0");
            }
            catch
            {
                return false;
            }
        }
    
        private static object GetHKLMValue(string key, string valueName)
        {
            return Registry.GetValue("HKEY_LOCAL_MACHINE\\" + key, valueName, null);
        }
    

    如果 Burn 可以更好地处理这样的事情会很好,但这可能会很复杂,因为仅仅提供一个 Fail Early .NET 包和一个单独的 Fail Early VSTO 包并不足以构建一个完整的包列表需要由管理员独立安装。

    在 bootstrapper-wrapper 代码中使用 C# 和 .NET 2.0 显然是一种风险,但我猜在野外没有太多旧的 XP 盒子有 Office 并且至少没有 . NET 2.0。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-05
      • 1970-01-01
      • 2016-06-05
      • 2016-08-12
      相关资源
      最近更新 更多