简体   繁体   English

如何在安装InstallShield 2013的安装程序中包含KB2670838?

[英]How can I include KB2670838 in an installer with InstallShield 2013?

I'm using InstallShield 2013 to make a Basic MSI installer for an application that requires Windows Platform Update KB2670838 . 我正在使用InstallShield 2013为需要Windows平台更新KB2670838的应用程序制作基本MSI安装程序。

For .NET frameworks and other requirements, I select them in InstallShield in the Redistributables section. 对于.NET框架和其他要求,我在Redistributables部分的InstallShield中选择它们。 KB2670838 is not available. KB2670838不可用。

If I download KB2670838 from Microsoft I get a .msu file. 如果我从Microsoft下载KB2670838,我会得到一个.msu文件。 Can that be included in the installer somehow so that it automatically installs if needed? 可以以某种方式包含在安装程序中,以便在需要时自动安装吗? If not, is there a way to stop the install and tell the user that "KB2670838 is required but not installed. Get it here..."? 如果没有,是否有办法停止安装并告诉用户“KB2670838是必需的但未安装。请在此处获取......”?

The Add/Remove programs list in the registry could help you get a rough idea of what's installed: 注册表中的“ 添加/删除程序”列表可以帮助您大致了解已安装的内容:

  • HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall HKEY_LOCAL_MACHINE \\ SOFTWARE \\微软\\的Windows \\ CurrentVersion \\卸载

It seems this doesn't provide a full list of what is installed though: http://social.technet.microsoft.com/Forums/windows/en-US/d913471a-d7fb-448d-869b-da9025dcc943/where-does-addremove-programs-get-its-information-from-in-the-registry?forum=w7itprogeneral 似乎这并未提供所安装内容的完整列表: http//social.technet.microsoft.com/Forums/windows/en-US/d913471a-d7fb-448d-869b-da9025dcc943/where-does- addremove -程序获得,其信息从-在最注册表?论坛= w7itprogeneral

Another way may be to use the file information from the knowledge base article: http://support.microsoft.com/kb/2670838/en (For More Information : File Information) and use WIX / MSI's AppSearch / LaunchCondition feature. 另一种方法可能是使用知识库文章中的文件信息http//support.microsoft.com/kb/2670838/en (更多信息:文件信息)并使用WIX / MSI的AppSearch / LaunchCondition功能。 That should do the trick, though I find the syntax a bit counterintuitive. 虽然我发现语法有点违反直觉,但这应该可以解决问题。

Another approach is to write a custom action and combine these two sources (add /remove entry and file info). 另一种方法是编写自定义操作并组合这两个源(添加/删除条目和文件信息)。 Such a custom action will make no changes to the system, and is hence less problematic than other custom actions that cause rollback-problems. 这样的自定义操作不会对系统进行任何更改,因此与导致回滚问题的其他自定义操作相比,问题更少。 I find it easier to test and maintain a custom action in case there are further prerequisites that are needed at some point. 我发现测试和维护自定义操作更容易,以防某些时候需要进一步的先决条件。 This is a matter of taste though. 这是一个品味问题。 I just find it easier to run a prerequisite script against a selection of files to test that it identifies them correctly and run through as expected than to keep running the MSI file for every test. 我发现更容易针对选择的文件运行必备脚本以测试它是否正确识别它们并按预期运行,而不是为每个测试继续运行MSI文件。

Here is a similar question with some pointers from superuser.com: https://superuser.com/questions/521175/determine-if-windows-hotfix-has-been-applied 以下是来自superuser.com的一些类似问题: https//superuser.com/questions/521175/determine-if-windows-hotfix-has-been-applied

And another link to serverfault.com (system administration site). 另一个指向serverfault.com(系统管理站点)的链接。 Nice approach using PowerShell which can certainly be migrated to a custom action: https://serverfault.com/questions/312778/determine-if-user-has-hotfix-981889-installed 使用PowerShell的好方法当然可以迁移到自定义操作: https//serverfault.com/questions/312778/determine-if-user-has-hotfix-981889-installed

Even more serverfault.com stuff involving update.exe , WMI and a Powershell script to view all installed hotfixes : https://serverfault.com/questions/263847/how-can-i-query-my-system-via-command-line-to-see-if-a-kb-patch-is-installed . 甚至更多涉及update.exeWMIPowershell脚本的 serverfault.com内容, 以查看所有已安装的修补程序https//serverfault.com/questions/263847/how-can-i-query-my-system-via-command- line-to-see-if-a-kb-patch-is-installed Recommended read . 推荐阅读 Microsoft: http://technet.microsoft.com/en-us/library/hh849836.aspx 微软: http//technet.microsoft.com/en-us/library/hh849836.aspx

PSInfo appears to be able to show installed hotfixes: http://technet.microsoft.com/en-us/sysinternals/bb897550 PSInfo似乎能够显示已安装的修补程序: http//technet.microsoft.com/en-us/sysinternals/bb897550

In InstallShield, you should typically deliver this sort of update as a prerequisite (Tools > Prerequisite Editor), or as a package included in a Suite (reference [SystemFolder]wusa.exe to install an .msu file). 在InstallShield中,您通常应将此类更新作为先决条件(工具>先决条件编辑器)或作为套件中包含的软件包提供(参考[SystemFolder]wusa.exe以安装.msu文件)。 In both cases this keeps the redistributable installation logically separate from your package's installation, while providing your users a single installer experience. 在这两种情况下,这使得可再发行的安装在逻辑上与您的软件包的安装分离,同时为您的用户提供单一的安装程序体验。

Glytzhkof mentions several really good points about how to determine whether the update has been installed. Glytzhkof提到了几个关于如何确定是否已安装更新的非常好的观点。 You will want to incorporate these into your conditions (on the prerequisite or suite package), and also into detecting the update or lack thereof in your .msi package so it can abort if the required update has not been installed by the time the .msi is launched. 你会想这些整合到你的条件(在上述前提条件或套件包),并进入你的检测更新或缺少.msi包,以便它可以中止,如果需要的更新并没有被时间所安装.msi推出。

@Glytzhkof Good point. @Glytzhkof好点。 So how do I get InstallShield to abort and give the user a nice message so they know what to do? 那么我如何让InstallShield中止并给用户一个好消息,让他们知道该怎么做? – shoelzer 1 hour ago - shoelzer 1小时前

I will just add a new answer then - too long to write in a comment. 我只想添加一个新的答案 - 太长时间不能写评论。

  • Locate the file details you need to scan for under "For More Information : File Information" in this kdb article: http://support.microsoft.com/kb/2670838/en 在此kdb文章的“更多信息:文件信息”下找到您需要扫描的文件详细信息: http//support.microsoft.com/kb/2670838/en
  • Select a few files to scan for and add as file searches in Installshield (see below screenshot). 选择要扫描的几个文件,并在Installshield中添加为文件搜索(参见下面的屏幕截图)。 You specify a property for each file (FILE1FOUND, FILE2FOUND, FILE3FOUND, etc...), and if the search matches the file details (version, size, date, etc...) the property is set to the full path of the file. 您为每个文件指定了一个属性(FILE1FOUND,FILE2FOUND,FILE3FOUND等等),如果搜索与文件详细信息(版本,大小,日期等等)匹配,则该属性设置为该文件的完整路径文件。 Otherwise the property is undefined or set to a default value (screenshot shows predefined search, and not file search, but you get the idea). 否则,该属性未定义或设置为默认值(屏幕截图显示预定义搜索,而不是文件搜索,但您明白了)。
  • Finally you add LaunchCondition entries for each file to ensure that all files you have selected to check are the correct version or higher. 最后,为每个文件添加LaunchCondition条目,以确保您选择检查的所有文件都是正确的版本或更高版本。 I guess this is in Prerequisites or similar - I can't recall. 我想这是先决条件或类似 - 我不记得了。 Open the compiled MSI and check that it looks like the LaunchConditon table . 打开已编译的MSI并检查它是否与LaunchConditon表类似。

Installshield的搜索视图

For the record: (not part of above suggestion) 记录:(不属于上述建议)

Personally I am in favor of coding a single script for complex logic like this to ensure the logic can be inspected as a whole and crucially tested as a whole outside the MSI file. 就个人而言,我赞成为这样的复杂逻辑编写单个脚本,以确保逻辑可以作为一个整体进行检查,并在MSI文件之外作为一个整体进行重要测试。 It is also good to add comments to such code to explain what the script is checking, and why (helps corporate deployment). 向这些代码添加注释以解释脚本正在检查的内容以及原因(帮助企业部署)也是很好的。 A script can be run through dozens of tests against the machine directly without recompiling the MSI. 脚本可以直接针对机器运行几十个测试,而无需重新编译MSI。 This can save a lot of time if the logic is complex. 如果逻辑复杂,这可以节省大量时间。 If you write a compiled dll you can show a message box and attach the visual studio debugger to the msiexec.exe process (client or server depending on what context your custom action is running in) and step-through the code whilst embedded in the MSI, but this seems out of scope for your scenario. 如果编写已编译的dll,则可以显示一个消息框,并将visual studio调试器附加到msiexec.exe进程(客户端或服务器,具体取决于运行自定义操作的上下文),并在嵌入MSI时逐步执行代码,但这似乎超出了您的方案的范围。 Just want to mention it for other people who might read this. 只是想为其他可能会读到这个的人提一下。 Also check Stefan Kruger's installsite.com for more information on complex setup debugging like this. 另请查看Stefan Kruger的installsite.com ,了解有关此类复杂设置调试的更多信息。

It is important to note that scripting is never generally recommended for scenarios where the script makes changes to the system - if there is a built-in MSI way to achieve the same result . 值得注意的是,脚本对系统进行更改的情况通常不建议使用脚本 - 如果有内置的MSI方法可以实现相同的结果 The reason for this is that a script that makes changes to a machine will need a separate rollback-operation to be specified for it for the MSI to follow best practice. 这样做的原因是,对机器进行更改的脚本需要为其指定单独的回滚操作,以便MSI遵循最佳实践。 This can be a spectacular amount of work and complexity to get right. 这可能是一项壮观的工作量和复杂性,以便做到正确。 The above script would only check system conditions, so there is no need for rollback support. 上面的脚本只会检查系统条件,因此不需要回滚支持。

Let me try and add a reference style answer since my other answer is a bit organic to say the least at this point - I will leave it in since it contains an MSI discussion. 让我尝试添加一个参考样式的答案,因为我的另一个答案在这一点上至少可以说是有点 - 我会留下它,因为它包含一个MSI讨论。 See MSI recommendation in the middle section below : 请参阅下面中间部分的MSI建议

WMI : WMI

wmic qfe where "HotfixID = 'KB973687'"

PowerShell : (just get-hotfix for full list) PowerShell :(只需获取完整列表的修补程序)

get-hotfix | findstr "981889"

SystemInfo (remove arguments for list format): SystemInfo (删除列表格式的参数):

systeminfo /fo csv

PSInfo (seems to not list everything on all machines, and may not run silently properly): PSInfo (似乎没有在所有机器上列出所有内容,并且可能无法正常运行):

PSinfo -h

Registry (apparently not complete list of hotfixes): 注册表 (显然不是完整的修补程序列表):

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

For MSI custom action use , I would actually use a custom action that inspects file versions as explained in my other answer. 对于MSI自定义操作使用 ,我实际上会使用检查文件版本的自定义操作,如我的其他答案中所述。 Very reliable, and takes into account that the hotfix may be deprecated whilst the files are still up to date. 非常可靠,并考虑到在文件仍处于最新状态时可能不推荐使用此修补程序。


References : 参考文献

Had the same issue and solved it by adding a prerequisite of a PowerShell script and a batch file to execute it. 有同样的问题并通过添加PowerShell脚本和批处理文件的先决条件来执行它来解决它。

The pre.ps1 file looks something like this: pre.ps1文件看起来像这样:

function TestConnection
{
    Test-Connection -ComputerName "8.8.8.8" -Quiet
}

get-hotfix -id KB2670838
if(!$?){
    #SourceURI = "https://download.microsoft.com/download/1/4/9/14936FE9-4D16-4019-A093-5E00182609EB/Windows6.1-KB2670838-x64.msu";
    #$FileName = $SourceURI .Split('/')[-1]
    #$BinPath = Join-Path $DownloadPath -ChildPath $FileName
    Invoke-Webrequest -Uri $SourceURI -OutFile $BinPath
    #Start-Process -FilePath $BinPath -ArgumentList "/q /norestart" -Wait -NoNewWindow
}

the pre.cmd file looks something like this: pre.cmd文件看起来像这样:

@echo off
::set PS_FILE=%~dp0Prerequisite.ps1
set PS_FILE=%~dpn0.ps1
set PS_EXEC_PATH=%SystemRoot%\sysnative\WindowsPowerShell\v1.0\
set PS_EXEC_PATH=%SystemRoot%\System32\WindowsPowerShell\v1.0\
::set PS_EXEC_PATH=%SystemRoot%\SysWOW64\WindowsPowerShell\v1.0\
set PS_EXEC_PATH=
set PS_EXEC=%PS_EXEC_PATH%powershell.exe
echo %PS_EXEC%
echo %PS_FILE%

::%PS_EXEC% -file %PS_FILE% set-executionpolicy remotesigned
::%PS_EXEC% -NoProfile -ExecutionPolicy Bypass -Command "& '%PS_FILE%'"
::This is with admin rights
%PS_EXEC% -NoProfile -Command "& {Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""%PS_FILE%""' -Verb RunAs}"

::pause

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM