Windows Installer在Win 10上失败,但在使用WIX的Win 7上失败 [英] Windows Installer fails on Win 10 but not Win 7 using WIX
问题描述
我最近被分配更新我们的项目安装程序以在Windows 10上运行,而我对如何使其工作不知所措.我没有安装程序的经验,并且不仅要熟悉整个过程,而且要熟悉我们的项目如何处理它.
到目前为止,该安装程序可以在Windows 7 VM上完美运行,但是在Windows 10 VM上运行时,安装将在接近尾声时失败并开始回滚.我已经得到它吐出了一些日志文件,我正在仔细研究它们,但损失相当大.
我已经找到了这一点:
MSI (s) (B0:F4) [17:39:02:883]: Note: 1: 1708
MSI (s) (B0:F4) [17:39:02:883]: Note: 1: 2205 2: 3: Error
MSI (s) (B0:F4) [17:39:02:883]: Note: 1: 2228 2: 3: Error 4: SELECT `Message` FROM `Error` WHERE `Error` = 1708
MSI (s) (B0:F4) [17:39:02:883]: Note: 1: 2205 2: 3: Error
MSI (s) (B0:F4) [17:39:02:883]: Note: 1: 2228 2: 3: Error 4: SELECT `Message` FROM `Error` WHERE `Error` = 1709
MSI (s) (B0:F4) [17:39:02:883]: Product: GPEP -- Installation failed.
在安装程序似乎失败时或附近发生的末尾.
下一行在末尾有这个:
Installation success or error status: 1603.
我调查了错误并发现了这个问题:解决方案
将此添加为答案-注释太长,我认为这也是正确的答案.如果您阅读此答案,请也从上方
依赖于缺少的运行时(如Powershell)肯定会触发回滚. MSI为某些脚本自定义操作(活动脚本)托管自己的运行时.例如VBScript和JavaScript.为了可靠地进行部署,建议所有使用的自定义操作要么是自包含的最低依赖性C ++ dll或可执行文件(win32),要么是(不太理想的)VBScript或JavaScript(如果使用Installshield,甚至是Installscript-请参见下面的详细信息). /p>
我的有争议的意见 :用于可靠性和健壮性的最差的自定义操作是需要特定版本的.NET框架的.NET二进制文件.这也适用于PowerShell-它不仅是托管代码,而且还是脚本.我很想说这些技术不应该用于部署,但是如果您需要使用PowerShell,则必须至少在安装开始时添加一个验证已安装PowerShell"自定义操作,并以如果PowerShell不可用,则会显示(和/或记录)正确的错误消息. 这是真实答案的结尾:-).如果您要制作一个用于一般发行的软件包(而不仅仅是您自己公司内部部署的软件包),则下面是一些冗长的沉思".如果我是您,即使您仅在内部进行部署,我也会阅读它, PowerShell自定义操作可能会成为酝酿成规模的部署问题. 托管代码和脚本均存在问题. PowerShell实际上是同时存在的. 这是Rob Mensching的博客关于脚本自定义操作为什么不好的原因.本质上:脚本易碎,缺少语言功能,难以调试,并且防病毒产品经常将其阻止.阅读博客.并且 意见警告 :但是,总体而言,.NET二进制文件和PowerShell脚本是最不可靠的自定义操作.我永远不会将它们用于针对各种计算机的设置. 如果您要制作 MSI以便将其常规分发到任何地方的任何计算机上,我将花一些时间将PowerShell脚本转换为其他脚本.最好是C ++ dll-我认为这是最可靠的.没有要说的依赖项或要依赖的层.如果您一直使用Installshield,则即使InstallScript也可以接受(此时它可以在没有预装运行时的情况下运行-大大提高了其可靠性和实用性-尽管它是一种陈旧的语法,但它是一种晦涩的语言.被低估了-它可以完成工作,并且比C ++更简单. JavaScript 和 VBScript 自定义操作甚至可以用于一般分发到任何计算机的MSI,但仍然可以使用不推荐.我倾向于只将它们用于内部公司部署"软件包.这些可以标准化,并且至关重要的是脚本对其他系统管理员和打包程序透明.他们可以查看并检查安装过程中正在执行的操作.这通常是可取的,并且 MSI对企业的主要好处之一部署,但有时您需要编译的二进制文件来隐藏实施详细信息(例如,在验证许可证密钥时).这样就不能使用任何类型的脚本-显然.通过透明并嵌入到MSI中(因此始终可以获取完整的运行源代码),它可以帮助不同的应用程序包装商在需要时接管其他人的工作.在部署团队中,总会有人来调试脚本-但是很少有人会知道正确的C ++.在内部应用程序开发人员在没有太多部署知识的情况下制作自己的MSI文件的公司中,脚本可能会完全误入歧途,并导致非常困难的部署问题.通常,需要对应用程序本身进行小的更改以允许更可靠的部署.例如,应用程序应该执行自己的启动配置-这些操作都不应该在安装脚本中完成,但是许多开发人员都可以这样做. 使用脚本自定义操作是有争议的.如果您询问2位开发专家,您将获得4条意见.在我看来,白框"自定义操作(脚本)如果用于执行某些不常见的特定操作,则非常适合公司使用,以便人们可以看到发生了什么.对于始终需要的内容,公司应在MSI文件中创建由自定义表驱动的经过编译的C ++ dll,并提供完整的质量检查和回滚支持-所有脚本自定义操作通常都缺少这种东西(实行). 数据驱动"(定制表)C ++定制操作具有最大的优势,即具有最小的依赖性,并且也是透明的(将发生的事情是透明的,但是实际的实现被编译和隐藏了,这也可以提高安全性). WiX工具包提供了这样的自定义操作dll,并以C ++编写了回滚支持.它应该可以解决企业部署所需的大多数自定义任务.尽管所有这些都超出了您的问题-只是题外话:-). 如果我猜想我会说Windows Installer可能已更新为能够托管Powershell自己的运行时-但这只是猜测.我不确定技术细节-似乎需要整个.NET运行时?如果您问我,我仍然会更喜欢JavaScript而不是PowerShell脚本,但是我知道您可能致力于将PowerShell作为公司标准?另外, Rob Mensching , Chris Painter , Phil Wilson , Bob Arnson ,也许还有其他人(我不是确定在脚本中 Stefan Kruger的 的位置,或 Robert Dickau的 strong>视图)-为此会杀了我,但这是JavaScript自定义操作的模板(我尚未试用,但看起来还不错):
更新,2018年5月:不再推荐在VBScript上使用Javascript. 摘要: 我可以肯定的一件事是,托管代码自定义操作的可用性将导致人们在其设置中执行太多不应在设置中执行的操作(丰富的API ,相对容易编码).这是因为编码更容易,更快捷,并且所涉及的开发人员可能对应该如何进行正确的部署缺乏了解.这不可避免地导致各种自定义操作的过度使用,进而导致主要的部署问题,例如Error 1603 I'm looking into the solutions on that page but all of that should be in order. We're running the installer in the same way with the same permissions on the Win 10 and Win 7 VM's. I doubt this will be enough information to get any concrete responses, so more than anything I'm looking for constructive advice how where to look and how to figure this out. I have more details I could post, but it's such a large volume of information and I don't know how to pick out what is genuinely relevant. Adding this as an answer - it is too long as a comment, and I think it is the correct answer as well. If you read this answer, please also see my comment above for a very good MSI log file debugging tip from Rob Mensching (creator of WiX) - and how to ensure all entries make it into the log file by enabling "flush to log" for crashing custom actions. Dependency on a missing runtime like Powershell would certainly trigger the rollback. MSI hosts its own runtime for certain script custom actions (active scripting). For example VBScript and JavaScript. For reliable deployment, it is recommended that all custom actions used be either self-contained minimum-dependency C++ dlls or executables (win32) or (less desirable) VBScript or JavaScript (or even Installscript if you use Installshield - see details below). Disputed opinion of mine: The worst custom actions to use for reliability and robustness are .NET binaries requiring a specific version of the .NET framework. This also applies to PowerShell - which is not only managed code, but also a script. I am very tempted to say that these technologies shouldn't be used for deployment, but if you need to use PowerShell you must at a minimum add a "verify PowerShell installed" custom action at the start of your setup, and exit gracefully with a proper error message displayed (and/or logged) if PowerShell is not available. That is the end of the real answer :-). Below are some "verbose musing" in case you are making a package for general distribution (and not just a package for your own company's internal deployment). If I were you I would read it even if you only deploy internally, PowerShell custom actions could be a brewing deployment problem of caliber. Both managed code and scripts are problematic. PowerShell is effectively both at the same time. Here is Rob Mensching's blog on why script custom actions are bad. Essentially: scripts are fragile, they lack language features, they are hard to debug and anti-virus products often block them. Read the blog. And here is Aaron Stebner's blog on why managed code is bad. Essentially you are not guaranteed a proper runtime environment when you depend on the presence of the .NET framework. I am not sure what is installed as standard on Win7 and Win10. If your are deploying as an "internal package" to your company, I think it should be OK to just add a reliable check for the presence of PowerShell, and then to abort with a meaningful error message if PowerShell is not found. Opinion Warning: But overall .NET binaries and PowerShell scripts are the worst custom actions for reliability. I would never use them for setups targeting diverse computers. If you are making an MSI for general distribution to any computer anywhere, I would take the time to convert the PowerShell script to something else. Preferably a C++ dll - which I find most reliable. There are no dependencies to speak of or layers to depend on. Even InstallScript is acceptable if you would have been using Installshield (it can run without a pre-installed runtime at this point - which has significantly improved its reliability and usefulness - it is an obtuse language though with rather archaic syntax. In fairness, not to be underestimated - it does the job, and is simpler than C++). JavaScript and VBScript custom actions are possible to use even for MSIs that are for general distribution to any computer, but still not recommended. I tend to use them only for "internal company deployment" packages. These can be standardized and crucially scripts are transparent to other system administrators and packagers. They can see and inspect what is being done as part of the installation. This is generally desirable and one of the key benefits of MSI for corporate deployment, but sometimes you need a compiled binary to hide implementation details (for example when you validate a license key). Then scripts of any kind can't be used - obviously. By being transparent and also embedded in the MSI (so the full, running source is always available), it helps different application packagers to be able to pick up someone else's work when need be. And in a deployment team there is always someone available to debug scripts - but few may know proper C++. In corporations where developers of internal applications make their own MSI files without much deployment knowledge, scripting can go completely astray and cause very difficult deployment problems. Very often what is needed is small changes to the application itself to allow more reliable deployment. An application should do its own startup configuration for example - none of this should be done in setup scripts, but many developers do this. Using script custom actions is controversial. If you ask 2 development experts you will get 4 opinions. In my view "white box" custom actions (scripts) are good for corporate use if they do something specific that isn't common so people can see what is going on. For stuff that is needed all the time, a corporation should make a compiled C++ dll driven by custom tables in the MSI file with full QA and rollback support - something that is generally always missing for all script custom actions (it isn't trivial to implement). A "data driven" (custom tables) C++ custom action has minimal dependencies as its biggest strength, and it is also transparent (what will happen is transparent, but the actual implementation is compiled and hidden - which can also improve security). The WiX toolkit provides such a custom action dll with rollback support written in C++. It should solve most custom tasks required for corporate deployment. All of this is way beyond your question though - just a digression :-). If I were to guess I would say that Windows Installer might be updated to be able to host its own runtime for Powershell - but this is just speculation. I am not sure of the technical details - it would seem the whole .NET runtime would be needed? If you ask me, I would still prefer a JavaScript to a PowerShell script, but I realize you are probably committed to PowerShell as a company standard? Also, Rob Mensching, Chris Painter, Phil Wilson, Bob Arnson and probably others too (I am not sure of Stefan Kruger's position on scripts, or Robert Dickau's view) - will kill me for this, but here is a template for a JavaScript custom action (untested by me, but looks OK): How to debug an MSI Custom Action that is implemented in Javascript? . If I can just blurt it out: anything is better than PowerShell at the present time - even JavaScript. Rest assured, I have wasted a lot of time debugging extremely poor VB Script custom actions. Probably the most incompetent and deprived language ever used for deployment. Maybe we will see VB Script deprecated and PowerShell added as a viable MSI scripting option in due time? I wouldn't judge this as safe until all operating systems in use would have at least a baseline version of the .NET framework installed - and even then I believe policies could lock specific versions of .NET from being used. Do you want a package that suddenly can't uninstall because the target version of the .NET framework is no longer operational? Fixing such an issue could be an incredible amount of work - especially for a corporation with a large package estate (thousands of packages, thousands of machines). I wrote up a summary of "recommendations" for custom action implementation. It became pages long without saying much - I deleted it. Instead, here is a list of my custom action implementation preference (in order of decreasing robustness and reliability): UPDATE May,2018: no longer recommending Javascript over VBScript. Summary: One thing that I am certain of, is that the availability of managed code custom actions will cause people to do way too many things in their setups that should never be done in a setup (rich API, relatively easy coding). This is all because coding is easier and faster, and the developer in question may lack an understanding of how proper deployment should be done. This inevitably leads to overuse of custom actions of all kinds, and in turn major deployment problems as the complexity of custom actions trigger unexpected errors. 这篇关于Windows Installer在Win 10上失败,但在使用WIX的Win 7上失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
答案
总是比JavaScript更喜欢VB脚本 ,因为它看起来像异常处理(VB Script完全缺少). 更新:实际测试表明,与Javascript相比,VBScript实际上更适合与MSI一起使用.例如:使用Javascript访问 MSI API 时,出现了一些难以理解的问题.创建MSI时,使用VBScript进行的测试可能比使用Javascript进行的测试更多.老实说:这两种语言"都有严格的限制,而且都很难调试.
The Answer
Verbose Musings
always prefer JavaScript over VB Script since it has something that looks like exception handling (which VB Script lacks entirely). UPDATE: real-world testing indicates that VBScript is actually better to use with MSI than Javascript. For example: I have seen obscure problems when accessing the MSI API with Javascript. MSI itself was probably tested more with VBScript than with Javascript when it was created. Let's be honest: both "languages" have severe limitations and both are hard to debug.On Error Resume Next
for error handling? It can't get much worse. I generally only use scripts for read-only operations and set property actions.
Recommended Custom Action Implementation