我正在尝试将Excel插件部署到大众市场。该插件需要VSTO运行时(vstor_redist.exe)和.NET 4.5(适用于64位操作系统)或.NET 4.0(适用于32位操作系统)。我愿意假设潜在用户至少已经拥有.NET 2.0。目前我的设置包括:
分隔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>
一个.NET 2.0包装器,它包含bootstrappers作为嵌入式资源,并且部署&amp;为客户端操作系统运行正确的引导程序。 (基本上是Yochai Timmer在Single MSI to install correct 32 or 64 bit c# application中的答案)
整个事情感觉像是一个turducken,但是当用户拥有管理员凭据时,它可以很好地用于静默升级和全新安装。但是,如果用户不是管理员,并且还没有安装VSTO和相应的.NET,则会因为错误而失败:“0x8007051b - 在长时间下载后,此安全ID可能不会被指定为对象的所有者”过程
我想要做的是提前检查用户是否需要请求管理员干预并为他们安装VTSO和/或.NET,并显示一条消息,理想情况下是网站链接,当这是案子。此检查可以在引导程序中,也可以在我的.NET 2.0包装程序中。关于如何最好地做到这一点的任何建议?
谢谢,Eric
答案 0 :(得分:0)
对我来说最好的方法是在我的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。