应用程序是否依赖于编译它的环境? [英] Are applications dependent on the environment where it was compiled?

查看:26
本文介绍了应用程序是否依赖于编译它的环境?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们的 MSI 安装程序中有一个 System.BadImageFormatException.我已经阅读了有关目标框架的信息,但我们已经检查过,它针对的是正确的框架(.NET Framework 4.5 与我们的 QA 机器相同).

We are having a System.BadImageFormatException in our MSI installers. I have already read about the target frameworks, but we already checked and it's targeting the correct framework (.NET Framework 4.5 same with our QA machines).

我们有完全相同的源代码,但是我们'build team'编译的msi installer的结果失败了,但是我们'dev'编译的msi installer可以工作.问题是,构建和编译应用程序的环境是否会影响输出(例如:msi 安装程序)?

We have exactly the same source codes, but the results of the msi installer compiled by our 'build team' fails, but the msi installer compiled by us 'dev' works. Question is, does the environment where an application was built and compiled affects the output (example: msi installers)?

推荐答案

一些建议的调试步骤

那么是实际的 MSI 文件触发了这些错误,还是安装后的应用程序?

Some Suggested Debugging Steps

So it is the actual MSI file which triggers these errors, or the application after installation?

以下是尝试调试此类问题时需要考虑的一些想法和问题(不分先后).我的赌注是第一个列表中的第 3 个问题:

Below are some thoughts and questions to consider when trying to debug issues such as these (in no particular order). My bet is on issue 3 in this first list:

  1. 此异常是否在您运行 MSI 本身(或者它是 setup.exe?)时发生,或者在您尝试启动应用程序后发生安装?只是为了验证 - 我假设是 MSI.

  1. Does this exception occur as you run the MSI itself (or is it a setup.exe?), or as you try to launch the application after installation? Just to verify - I assume the MSI.

您在设置中有自定义操作吗?如果您的 MSI 中有托管代码自定义操作,您的构建目标平台是什么?任何 CPU 我想?请核实.我认为这里的 COM-interop 存在一些问题,但我对细节很模糊.有时您可能需要选择一个特定的平台.在这种情况下,您可能会收到此类错误消息(坏图像).请参阅下面的托管代码"部分,了解有关托管代码和部署的完整咆哮" - 以及可能导致的一些问题.

Do you have custom actions in the setup? If you have managed code custom actions in your MSI, what platforms do you target in your build? Any CPU I would presume? Please verify. I think there are some issues with COM-interop here, but I am fuzzy on the details. Sometimes you may have to pick a specific platform. In this case you can get such error messages (bad image). See section "Managed Code" below for a whole "rant" about managed code and deployment - and some problems that may result.

无论上述情况如何,在您的 WiX 源文件中,Product 元素 中的 Platform 属性 的值是多少?可能的值:x86x64intel64intelarmia64.请报告(并尝试使用其他值进行测试 - 例如 x86、x64).这会影响 MSI 的平台设置.如果您不使用 WiX - 打开已编译的 MSI 文件,并检查 Platform 设置的摘要流.使用 Orca 这是 View =>摘要信息... - 查找 Platform.

Regardless of the above, in your WiX source file, what is the value of the Platform attribute in the Product element? Possible values: x86, x64, intel64, intel, arm, ia64. Please report (and try to test with other values as well - x86, x64 for example). This affects the MSI's platform setting. If you don't use WiX - open the compiled MSI file, and check the summary stream for the Platform setting. Using Orca this is View => Summary Information... - look for Platform.

您是否有任何恶意软件扫描程序安全软件或其他用于 MSI 编译和/或安装的潜在拦截器"?或者在您尝试安装的测试系统上?(我们必须始终提及这些问题——如果我们不这样做,人们可能会浪费时间——即使它似乎很少是唯一的问题).

Do you have any malware scanners, security software or other "potential blockers" for MSI compilation and / or installation on your build computer? Or on the test system where you try to install? (We must always mention these issues - people can waste days if we don't - even if it rarely seems to be the only issue).

这是使用亚洲字符的本地化 MSI 吗?(或阿拉伯语,或任何其他复杂的字符集?).我只是提到了这一点 - 坦率地说,我不明白这是 100% 相关的,但我想为您的场景澄清这个变量"(即我们可以消除它作为潜在的错误源).它通常会导致运行时错误,而不是 System.BadImageFormatException 问题 - 我相信.

Is this a localized MSI using Asian characters? (or Arabic, or any other complex character sets?). This I just mention - frankly I don't see how this is 100% relevant, but I want to clarify this "variable" for your scenario (i.e can we eliminate this as a potential error source). It would generally cause runtime errors, not System.BadImageFormatException issues - I believe.

我认为对不同的 MSI 文件进行比较可能不起作用,因为其中一个文件是不良图像"?你试过了吗?也许它仍然是一个有效的 COM 结构化存储文件 - 但 msiexec.exe 引擎无法处理它?如果是这样,那么工具可能能够很好地读取文件中的内容 - 我不知道,试一试.

I assume a compare of the different MSI files may not work because one of the files is a "bad image"? Did you try? Maybe it is still a valid COM structured storage file - but the msiexec.exe engine can't handle it? If it is, then tools may be able to read the content inside the file just fine - I don't know, give it a try.

  • 对于您的情况:我最初认为单个编译的 MSI 在不同的位置(环境)中表现不同 - 因此建议检查任何运输途中的损坏(网络问题、samba 问题、存储问题、恶意软件问题等...)通过对不同位置的副本进行二进制差异(位级比较).由于您似乎从相同的来源编译了两个(或更多)MSI 文件,因此这种二进制比较显然毫无意义.差异是肯定的.

  • For your scenario: I initially thought a single, compiled MSI behaved differently in different locations (environments) - and hence suggested to check for any damage in transit (network issues, samba issues, storage issues, malware issue, etc...) by doing a binary diff on the copies in the different locations (bit-level comparison). Since you seem to compile two (or more) MSI files from the same sources, such a binary compare is obviously meaningless. Differences are certain.

但是,内容比较"可以告诉您一些信息 - 这会比较 MSI 内表/流中的实际内容.我想我会添加一个关于如何比较我可以从这里链接到的 MSI 文件的问答(添加:如何比较两个(或多个)MSI 文件的内容?).这假定 MSI 是可读的 - 即使它不可运行.知道的唯一方法就是尝试.

However, a "content compare" could tell you something - this compares actual content in the tables / streams inside the MSIs. I think I will add a Q/A on how to compare MSI files that I can link to from here (added: How can I compare the content of two (or more) MSI files?). This presumes that the MSI is readable - even if it is not runnable. Only way to know is to try.

我希望并相信以上列表可以帮助您解决问题.

I hope and believe that the above list should help you sort out your problem.

我在托管代码问题的主题上写下了自己的悬崖.这个想法是描述几个要检查的问题,但它变成了长时间的讨论.我可能会删除下面的所有内容,并可能在其他地方复活它.它可能与您完全无关.整个主题是托管代码以及它如何以新的有趣"的方式崩溃:

I wrote myself off a cliff below on the subject of managed code issues. The idea was to describe a couple of issues to check, but it became a long discussion. I may delete all the stuff below and perhaps resurrect it elsewhere. It may not be relevant for you at all. The overall topic is managed code and how it can crash in new and "interesting" ways:

这是另一个失控的庞大答案.一世认为它仍然有价值,将其保留.

This is another one of those sprawling answers that got out of hand. I think it still has value, leaving it in.

关于.NET 自定义操作(托管代码)的几个进一步问题.我远不是这个主题的专家,因为我像躲避瘟疫一样避开它们(目前 - 这可能会随着时间的推移而改变).

A couple of further issues with regards to .NET custom actions (managed code). I am far from an expert on this topic, since I shun them like the plague (for now - this may change over time).

其中一些内容偏离主题 - 出于您的目的 - 但我会将其保留为对 MSI 使用的托管代码的一般性评论.

Some of this veered quite a bit off topic - for your purpose - but I will leave it in as general comments on managed code for MSI use.

MSI 专家 Chris Painter 是该主题的负责人 - 他已经承担了这个潜在的痛苦世界",并且似乎也从此类自定义操作中受益,但是这些管理的自定义操作 似乎被普遍接受为 有问题 - 如果您以天真的方式接近他们.务实,权衡利弊与下列潜在问题.

MSI expert Chris Painter is the man for this topic - he has taken on this potential "world of pain" and seem to benefit from such custom actions too, but these managed custom actions seem generally accepted to be problematic - if you approach them in a naive way. Be pragmatic and weigh benefits against potential problems listed below.

一条友好的建议:对于全球分发,我现在永远不会使用托管代码 - 尽管它越来越安全" - 我们必须承认这一点.使用此类自定义操作的大规模分发 MSI 包有太多潜在的错误源(家庭用户可能会卸载 .NET,企业用户可能会看到 .NET 版本被禁用,以及下面的整个问题列表,我担心catch 22"卸载问题比什么都重要 - 下面的整个部分,等等......).

A friendly piece of advice: for worldwide distribution I would never use managed code as of now - though it is "getting safer" - we have to admit that. There are too many potential error sources for a large scale distribution MSI package using such custom actions (home users may uninstall .NET, corporate users may see versions of .NET disabled, and the whole list of problems below, and I fear "catch 22" uninstall problems more than anything - a whole section on this below, etc...).

正如我所说,我不是专家,但是有许多严重的问题.如果他们现在排序",也许克里斯可以纠正我.DTF 框架(与 WiX 一起分发)支持在常规 win32 dll 包装器中嵌入托管代码自定义操作 dll.这有助于可靠性.我会在这里挖掘一些链接以供参考.Chris 是这里的先驱和早期采用者.

As I said, I am not an expert, but there are many, and serious problems. Maybe Chris can correct me if they are "sorted" by now. The DTF framework (distributed along with WiX) features support for embedding a managed code custom action dll inside a regular win32 dll wrapper. This helps reliability. I will dig up a few links here for reference. Chris has been a pioneer and early-adopter here.

自定义操作使用的托管代码问题的部分列表:

Partial list of managed code problems for custom action use:

  1. .NET 框架可能缺失禁用损坏(完全或在您的代码请求/需要的版本中).现在,如果您所有的 3000 个公司包都有一个 .NET dll,其中嵌入了托管代码,该怎么办?在这种情况下,他们甚至无法卸载——更不用说升级了.在第 5 期下方有更多内容.

  1. The .NET framework may be missing, disabled or corrupted (entirely or in the version requested / needed for your code). Now, what if all your 3000 corporate packages have a .NET dll with managed code embedded in them? They can't even uninstall in this case - much less upgrade. More below in issue #5.

当面向不同版本的 .NET 运行时使用不同的自定义操作时,所有这些都将加载相同的 CLR 版本.所以他们告诉我(我在阅读时简直不敢相信 - 请阅读它!).足以让我跑到山上:-).这可能会以多种方式爆炸"是我听到自己的想法.相应地应用合适的偏执狂!万事万物的常驻邪恶再次抬起它丑陋的头 - 等等......说真的,不要听信偏执,但要警惕严重的问题.这个问题可以管理吗?我想 - 我不得不说是,但忽略这不是问题.许多不同的操作系统和 .NET 版本都需要严格的 UAT/QA.本机 dll 会做得更好吗?我想是的.

When targeting different versions of the .NET runtime with different custom actions, all will load the same CLR version. So they tell me (I could not believe it whilst reading it - please read it!). Enough for me to run for the hills :-). "This can blow up in any number of ways" is what I hear myself think. Apply suitable paranoia accordingly! The resident evil of all things rears its ugly head again - etc... Seriously, don't listen to paranoia, but be on alert for serious problems. Is this problem managable? I guess - I would have to say yes, but it is not a problem to ignore. Serious UAT / QA needed on many different OS and .NET versions. Would a native dll do better? I think so.

安装到 GAC 的组件不能用作设置中的托管自定义操作的依赖项(鸡或蛋 - 我想).这与 Fusion/MSI 的提交模型有关.

Components installed to the GAC can not be used as dependencies for your managed custom actions in the setup (chicken or the egg - I suppose). This has to do with the commit models of Fusion / MSI.

  • Bob Arnson 对此发表了评论 - 请查看(他是 WiX 核心团队的成员).我不知道这是否仍然是他在托管代码方面的首要问题 - 以及回滚.
  • 题外话:我读过 Arnson 说VBScript 操作比托管代码更糟糕(Painter 肯定同意,当然 WiX 老板本人 Rob Mensching - 博客).我认为这几乎适用于所有情况,但不适用于企业应用程序包场景(我有经验) - 或永远不会在生产中使用的临时测试(快速而简单).
    • 我在这里描述了这背后的原因(实用问题):Windows Installer 在 Win 10 上失败,但在使用 WIX 的 Win 7 上没有(本质上,任何编译的东西都会在现实、混乱的世界中增加源代码控制问题——企业打包人员必须接手彼此的工作动态以及 MSI 中完全嵌入的透明源文件可以节省一天的时间 - 一直以来,还有技能集问题,还有更多......).
    • 我不建议将 VBScript 用于受控环境(标准化工作站)中的企业用途以外的任何用途.VBScript 对于任何形状或形式的公开全球 MSI 版本来说都不够好.它们可以用于不返回错误代码的只读自定义操作,并设置为忽略所有运行时错误,但不能 - 有更好的方法.
    • 更新:我可以补充一点,我会在 GUI 序列中的只读自定义操作中使用 VBScript(只是一个属性设置器脚本),以便摆脱 .NET 框架完全作为依赖.当 .NET 框架出现在所有目标机器上的时候会到来,但它还没有完全到位(即使它在那里也可能被破坏.Windows 现在积极修复 ActiveScript 以使其始终运行 - 并且 MSI 拥有自己的 ActiveScripting运行时 - 脚本将运行,但您很容易自己弄乱代码,使自定义操作仍然可怕).
    • 我应该补充一点,我在上面的链接中建议使用 Javascript 而不是 VBScript 的建议将很快被删除.在实际使用中,Javascript 已被证明与 VBScript 一样糟糕,只是增加了一些过于详细的问题.Javascript 提供的增强的异常处理并不能弥补 MSI API 在其开发过程中似乎已经用 VBScript 测试过的事实.Javascript 可能不是,因此在使用 MSI API 时有一些不明显的笨拙问题.我在这上面浪费了昂贵的时间 - 我建议你不要浪费你的时间.
    • 我还使用脚本来测试原型设计调试我的 MSI 包(调试属性设置、应用搜索、覆盖命令行)测试等...).我发现这是最快的方法(谁想为此编译一些特别的东西?).只是不要用你的脚本测试代码来发布!如果使用 Installshield,我将使用 Installscript 进行此类脚本编写".
    • 对于未来:嵌入托管代码的一个很好的用途直接在 MSI 中,以可检查(和可重用)的形式 - 制作自定义操作白盒 - 嵌入完整源代码和完整 代码访问安全性 也是如此,使它们无法以 freebasing 提升的权限运行.只是想着可能会发生什么 - 让我们看看您在这个自定义操作中做了什么?
    • Bob Arnson has commented on this - check it out (he is on the core WiX team). I don't know if this still is his top issue with managed code - along with rollback.
    • Small digression: I have read Arnson stating that VBScript actions are worse than managed code (Painter certainly agrees, and definitely the WiX boss himself Rob Mensching - blog). I think this is true for just about all cases, but not for corporate application package scenarios (which I have experience with) - or ad-hoc testing that will never be used in production (quick and easy).
      • I describe the reasoning behind this here (pragmatic issue): Windows Installer fails on Win 10 but not Win 7 using WIX (essentially anything compiled adds a source control problem in the real, chaotic world - and corporate packagers have to pick up each other's work on the fly and a fully embedded, transparent source file in the MSI saves the day - all the time, and there is a skill set issue as well, and there is more...).
      • I do not recommend VBScript for anything but corporate use in controlled environments (standardized workstations). VBScript is not good enough for public, worldwide MSI releases in any shape or form. They can work for read-only custom actions returning no error codes and set to ignore all runtime errors, but no - there are better ways.
      • UPDATE: I can add that in a snag I would use VBScript in read-only custom actions in the GUI sequence (just a property setter script) in order to get rid of the .NET framework as a dependency altogether. The time will come when the .NET framework is on all target machines, but it is not quite there yet (and even if it is there it could be broken. Windows now actively fixes ActiveScript to always be running - and MSI hosts its own ActiveScripting runtime - scripts will run, but you could easily mess up the code yourself to make the custom actions horrendous still).
      • I should add that my recommendation to use Javascript over VBScript in the link above will be removed soon. Javascript has proved just as bad as VBScript in practical use, with some added snags that are too detailed to go into. The enhanced exception handling offered by Javascript does not make up for the fact that the MSI API seems to have been tested with VBScript during its development. Javascript was probably not, and hence has a few clunky issues when working with the MSI API that are not immediately apparent. I have wasted costly time on this - I would recommend you don't waste yours.
      • I also use scripting for testing, prototyping and debugging my MSI packages (to debug property settings, app searches, override command lines for testing, etc...). I find this the quickest way (who wants to compile something ad-hoc for this?). Just don't roll with your script test code for release! If using Installshield I use Installscript for such "scripting".
      • And for the future: one good use for managed code would be embedded directly in the MSI, in inspectable (and reusable) form - making custom actions white box - with full source embedded and with full code access security too, making them unable to run with freebasing elevated rights. Just thinking about what could come - let us see what you are doing in this custom action of yours?

      为了详细说明问题 1,托管代码可能对某个不可用的 .NET 运行时版本进行硬编码.我想这可能是更容易处理的问题?如果我错了,请纠正我,克里斯.我只是一个涉足这个.设置最新版本"仍然可能会导致问题...

      To elaborate issue 1, managed code may hard-code a certain .NET runtime version that is not available. I guess this is probably the easier problem to deal with? Correct me if I am wrong Chris. I am just a dabbler with this. Setting "lastest version" could still cause issues though...

      我还要补充一点:如果在卸载期间托管自定义操作失败,由于 .NET 框架损坏(或出于任何其他原因 - 专注于托管代码)问题 - 例如,Windows 更新中 Windows 本身的设计/安全更改) - 您无法卸载,因此无法(主要)升级您现有的安装.在我看来,这是一个严肃的 catch 22.如果您有 3000 个实时软件包和数千个桌面需要管理并且 dll 嵌入在每个 MSI 中,请尝试此操作...

      Let me add a pet peeve of mine as well: if a managed custom action fails during uninstall due to a corrupt .NET framework (or for any other reason - focused on managed code issues - for example a design / security change in Windows itself from Windows Update) - you can't uninstall and thereby not (major)-upgrade your existing installation. A serious catch 22 in my opinion. Try this if you have 3000 live packages and thousands of desktops to manage and the dll is embedded in each MSI...

      • 创建在卸载/升级时触发错误的任何类型的自定义操作代码也是我制作 C++ 自定义操作 dll 时的最大恐惧 - 因此它不是托管代码所独有的.一个典型的错误是在 InstallFinalize 之后或在 UI 序列中设置自定义操作以检查退出代码" - 返回的小错误会导致主要升级的完全回滚.经典的第 22 条规则" - 现在,如果不解决旧产品卸载顺序中的问题,您将无法升级.

      • Creating custom action code of any kind that trigger errors on uninstall / upgrade was my big fear when making a C++ custom action dll as well - so it is not unique to managed code. A classic error is to set custom actions after InstallFinalize or in the UI sequence to "check exit code" - and a trivial error returned causes full rollback of a major upgrade. A classic "catch 22" - now you can not upgrade without fixing the problem in the old product's uninstall sequence.

      尽管这是所有自定义操作代码的普遍问题,但我觉得托管代码的风险增加了很多.如果 .NET 框架的一些奇怪的策略更改使大型公司中的所有包都无法卸载和升级,因为它们都嵌入了相同的有问题的自定义操作 dll,该怎么办?或者更糟糕的是,这是一个无法回滚的 Windows 设计更改?

      Despite this being a general problem for all custom action code, I feel the risk is heightened quite a bit with managed code. What if some weird policy change to the .NET framework makes all packages in a large corporation un-uninstallable and un-upgradeable since they all have embedded the same problematic custom action dll? Or worse yet, it is a Windows design change that you can't roll-back?

      • 在这种情况下应该有应急措施.这是我完全远离托管代码的核心原因——我更喜欢深入了解——更少的层依赖.最小的依赖,最小的纠缠(没有帝国纠缠).如果最小依赖 C++ dll 没有运行,那么 Windows 的核心通常已损坏,并且在大多数情况下系统需要重建.对于 .NET 自定义操作,您至少需要修复 .NET 框架(这可能比我想象的要容易 - 据我所知 - 但不要这么认为).

      • A contingency should be available in such cases. This is the core reason I stay away from managed code entirely - I like down to the wire better - fewer layers to depend upon. Minimal dependencies, minimal entanglements (no imperial entanglements). If a minimal dependency C++ dll does not run, then the core of Windows is generally broken and the system needs a rebuild in most cases anyway. For .NET custom actions you would minimally have to fix the .NET framework (which might be easier than I think - for all I know - don't think so though).

      我正在寻找使 DLL 位于先决条件包中的所有公司包外部的方法(理想情况下,安装程序本身中也有一个最小的、基线的、嵌入的 DLL - 如果缺少外部 DLL/未找到).这个想法是,一旦可用,外部 DLL 是首选,并且可以通过单个更新的先决条件包"为所有包升级.修复了所有 3000 个软件包 - 一次全部?

      I was looking at ways to make the DLL external to all corporate packages in a pre-requisite package (ideally with a minimal, baseline, embedded DLL in the setup itself as well - if the external DLL is missing / not found). The idea being that an external DLL is preferred once available, and upgradable for all packages by a single, updated "prerequisite package". All 3000 packages fixed - all at once?

      我从来没有考虑过确定这的技术可行性.容忍我,我正在为你的目的而跑题.如果 WiX 人正在阅读 - 这里的技术可能性是什么?基本上我期待听到不可能"——然后我就完成了.考虑到这一点时,我正在为亚洲和阿拉伯语位置的嵌入式 DLL 的潜在问题做准备(由于 Unicode/代码页问题可能导致严重的意外和致命的运行时故障),以及 Windows 中任何意外的安全更改(我们保留看到 - Windows 10 勒索软件保护目前间歇性地触发安装到用户配置文件文件夹的文件的运行时故障,或者 突然需要 MSI 修复的管理员权限 - kb2918614 在 Vista 上突然出现,以及其他任何他们意外不断变化的内容......).我不想坐在成千上万的不可升级、不可卸载的包中 - 已经部署到数万台机器上.

      I never got around to determining the technical feasibility of this. Bear with me, I am getting off topic for your purpose. If the WiX guys are reading - what are the technical possibilities here off the top off your head? Essentially I am expecting to hear "impossible" - and then I am done with it. When thinking about this I was preparing for potential problems with the embedded DLL in Asian and Arabic locations (potentially serious and unexpected and fatal runtime failures due to Unicode / code page issues), and also for any unexpected security changes in Windows (that we keep seeing - Windows 10 ransomware protection which currently intermittently triggers runtime failure for files installed to userprofile folders, or the sudden need for admin rights for MSI repair - kb2918614 which appeared out of the blue on Vista, and whatever else they keep changing unexpectedly...). I did not want to sit with thousands of un-upgradable, un-uninstallable packages - already deployed to tens of thousands of machine.

      我对企业使用的最后手段"是使用自制"修补程序 EXE破解"本地超级隐藏 MSI 缓存文件夹中的所有缓存 MSI 文件由修补程序包部署.通常在各方面都很疯狂,但在技术上看起来是可能的(直到数字签名关闭了这种可能性?).对我来说,如果数万台交易大厅机器突然遭遇灾难,我能想到的唯一可以接受的最后手段".

      My "last resort" contingency for corporate use was to "hack patch" all cached MSI files in the local, super-hidden MSI cache folder using a "home grown" patcher EXE deployed by a hotfix package. Generally insane in every way, but it looked technically possible (until digital signatures shuts off the possibility?). And for me the only acceptable "last resort" I could think of if tens of thousands of trading floor machines were hit by disaster suddenly.

      我至少可以想到另外两个选项 - 其中一个是对受影响的软件包进行小幅升级(大量工作、更清洁、保证工作).最后一个选项将不会被提及:-) - (Voldemort, "那些我们没有提到的",等等...)

      I can think of at least two other options - one of which is to minor upgrade affected packages (lots of work, cleaner, guaranteed to work). The last option will not be mentioned :-) - (Voldemort, "those we do not speak of", etc...).

      用于修补嵌入式自定义操作 dll 的次要升级补丁的自动生成功能也在我的意外事件列表中 - 次要升级只会修补 dll - 没有其他更改.然后可以在一个包一个包的基础上处理问题.当指向需要修补的实时 MSI 包时,单击按钮应该可以使用此修补程序.嵌入式自定义操作 dll 修补程序".如果可能的话,永远不应该使用的东西.应急解决方案"很少是漂亮的.

      An auto generation feature for minor upgrade patches to patch the embedded custom action dll's was also on my list of contingencies - the minor upgrade would only patch the dll - no other changes. Then problems could be handled on a package-by-package basis. This patch should be available at the click of a button when pointing to a live MSI package in need of patching. An "embedded custom action dll hotfixer". A thing that should not ever be used if at all possible. Contingency "solutions" are rarely pretty.

      我的两分钱:我能想到的几个场景中,最小依赖项比 MSI 中的嵌入式自定义操作更重要.它必须在任何机器任何状态任何语言任何位置任何安装模式(卸载是这里的第 22 条),理想情况下完全没有任何非标准依赖项.正是出于这个原因,我静态链接了 C++ 代码.对于全球发行版,我觉得这是目前唯一足够好的东西 - 静态链接的 C++ 代码 - (Installscript 可能例外 - 来自 Installshield - 现在显然没有依赖项运行 - 嵌入式运行时?我不知道他们是怎么做到的 - 在过去,Installscript 语言所需的运行时先决条件存在传奇问题.应该从 Installshield 12 版开始修复).

      My two cents: I can think of few scenarios where minimal dependencies are more important than for an embedded custom action in an MSI. It must work on any machine, in any state, in any language, in any location in any installation mode (and uninstall is the catch 22 here) ideally without any non-standard dependencies at all. I statically link C++ code for this very reason. For worldwide distribution I feel this is the only thing that is currently good enough - statically linked C++ code - (with the possible exception of Installscript - from Installshield - which is now running without dependencies apparently - embedded runtime? I don't know how they do it - in the olden days there were legendary problems with the required runtime pre-requisite for the Installscript language. It should be fixed since version 12 of Installshield).

      这不是一个完整的列表.这是我的跑山清单":-).

      This is not a complete list. It is my "run for the hills list" :-).

      • 不过不用担心 - 只要意识到这一切 - 如果托管代码的好处对您来说足够重要,请使用它们,但不要指望完全顺利航行是我的看法.我会坦率地告诉我的经理关于这些潜在的熊陷阱,而不会听起来像一个彻头彻尾的、偏执的疯子.一位优秀的经理将能够出售"任何应急计划作为必需品,您可以花时间进行工作甚至快速演示(相信我,这里的注意力很短 - 它必须是有史以来最快的演示).最大的问题是您是要处理一个包,还是像我们在企业部署中所做的那样处理数千个包.后者的情况发生了很大变化.必须将所有已部署包中嵌入的所有功能的风险降至最低.

      • No fear though - just be aware of it all - and use the benefits of managed code if they are substantial enough for you, but don't expect entirely smooth sailing is my take on it. I would be upfront with my manager about these potential bear traps, without sounding like a total, paranoid lunatic. A good manager will be able to "sell" any contingency plans as necessities, that you can get time to work on and even demonstrate quickly (believe me, attention span here is short - it has to be the quickest demo ever). The big question is whether you have one package to deal with, or thousands like we do in corporate deployment. Things change a lot for the latter. Risk must be minimized for all features that are embedded in all deployed packages.

      如果我 100% 诚实,托管代码并没有以前那么糟糕.使用 DTF 和其他框架有所帮助.但是卸载问题的潜在运行时问题令人担忧.公司的 .NET 框架发生了全球性变化——您的所有软件包都无法再卸载?或者较新版本的 .NET 框架在部署时未发现自定义操作中发现未知错误?它可能会在尝试卸载/升级时突然表现出来".可控,但你会诅咒自己...

      If I am 100% honest, it is not as bad with managed code as it used to be. Using DTF and other frameworks have helped. But the potential runtime issues for uninstall problems are worrying. A global change to the .NET framework in the company - and all your packages can no longer uninstall? Or a newer version of the .NET framework reveals unknown bugs in the custom action not found when it was deployed? It may suddenly "manifest itself" on attempted uninstall / upgrade. Managable, but you will curse yourself...

      我会为您的支持人员准备上述托管代码问题 - 他们应该了解这些问题并真正了解 .NET 的含义.

      I would prepare your support guys for the above managed code issues - they should know about the issues and really understand what .NET is about.

      我们的托管代码自定义操作从未遇到任何问题"——老实说,这是著名的遗言.

      "We have never seen any problems with our managed code custom actions" - famous last words - to be honest.

      • 如果您的目标计算机是统一和标准化的(SOE 环境)——这对公司来说是正常的——那么您的包可能看起来比实际更好(现在对于带有脚本的包也是如此).等待基于新操作系统的下一个 SOE 版本......我会尽早对包资产中的所有包进行试点测试.

      • If your target computers are uniform and standardized (SOE environment) - which is normal for corporations - then your packages may appear better than they really are (now this is true for packages with scripts too). Just wait for the next SOE version based on a new operating system... I would pilot test early with all packages in the package estate.

      您仍然可能会面临所有目标计算机以完全相同的方式开始失败的讽刺意味(Windows 更新中的 Windows 设计更改、触发干扰的安全软件更新、某些位置的 SOE 更新失败等......).

      You could still face the irony that all target computers start failing in exactly the same way (Windows design changes in Windows Updates, security software updates that trigger interference, SOE updates that fail for some locations, etc...).

      对于全球发行版来说,情况大不相同,而且事情往往会以许多难以调试和修复甚至根本无法解决的方式失败.您通常根本无法访问问题系统 - 首先.也许在这里阅读部署的复杂性"部分中的一些进一步评论:Windows Installer 和 WiX 的创建.

      For worldwide distribution things are quite different and things tend to fail in any number of ways that are hard to debug and fix or even work out at all. You normally have no access to the problem system at all - for starters. Maybe read some further comments in "The Complexity of Deployment"-section here: Windows Installer and the creation of WiX.

      所以我永远不会使用托管代码来全球分发复杂的包 - 除非您要交付非常具体的产品并且比正常情况更详细地了解目标机器的性质.成本/收益.

      So I would never use managed code for global distribution of a complex package - unless you are delivering a very specific product and know the nature of your target machines in more detail than normal. Cost / benefit.

      如果许多机器受到不可预见的死锁"触发(例如无法卸载/升级)的影响,我会采取应急措施.在这种情况下有些偏执,但并非不可能.愚蠢的战争游戏".风险由您的经理管理,由您技术处理.

      I would have a contingency for what to do if many machines are affected by unforeseen triggers of "deadlocks" such as not being able to uninstall / upgrade. Some paranoia in this scenario, but not impossible. Silly "war games". Risk is for your manager to manage, and for you to handle technically.

      installsite.org 上添加一个指向老化但仍然有效的常见问题解答条目的链接托管自定义操作及其问题的主题:How can I create Custom Actions in托管语言,如 C#?.

      Adding a link to an aging, but still valid FAQ entry from installsite.org on the topic of managed custom actions and their problems: How can I create Custom Actions in Managed Languages, like C#?.

      并且首先要对任何自定义操作持怀疑态度

      • 托管代码只会增加自定义操作的波动性.自定义操作很复杂,一开始就很难做到.他们模拟运行或在错误的上下文无意中运行,他们意外运行了两次,他们根本没有运行,但他们>以错误的安装模式运行,它们由于缺少依赖项而崩溃,它们由于错误的编码而导致异常升级和卸载失败强> 与触发回滚类似,您对本地化文件夹的引用进行硬编码,因此您的设置在非英语机器上崩溃,您可以命名...

      • Managed code just adds to custom action volatility. Custom actions are complex and difficult to get right in the first place. They run impersonated or in the wrong context unintentionally, they run twice unexpectedly, they don't run at all when expected to, they run in the wrong installation mode, they crash due to missing dependencies, they cause exceptions due to bad coding that fail upgrades and uninstalls alike by triggering rollback, you hard code references to localized folders so your setup crashes in non-English machines, you name it...

      MSI 本身的内置结构,或 WiX 等框架或 Installshield 和 Advanced Installer 等商业工具中预先编写的自定义操作(支持回滚)已经过数千、数百万甚至数十亿的测试(!) 的用户 - 它们由可用的最佳部署专家编写.即使对于这些组件,仍然会发现错误 - 这说明了一切.您认为自己可以做得更好吗?总是更喜欢现成的、经过测试和维护的解决方案 - 如果有的话.

      Built-in constructs in MSI itself, or pre-written custom actions (with rollback support) in frameworks such as WiX or commercial tools such as Installshield and Advanced Installer have been tested by thousands, millions or even billions (!) of users - and they are written by the best deployment experts available. Even for these components, bugs are still found - which says it all. Do you think you could do it better on your own? Always prefer ready-made, tested and maintained solutions - if available.

      关于自定义操作的一般问题的完整咆哮:为什么在我的 WiX/MSI 设置中限制使用自定义操作是个好主意?

      A whole rant about the problems with custom actions in general: Why is it a good idea to limit the use of custom actions in my WiX / MSI setups?

      <小时>

      来源"

      一些进一步的链接(其中一些内容现在可能已经过时了,但这些是值得信赖的来源 - 不容忽视 - Mensching 是 WiX 仁慈的独裁者):


      "Sources"

      Some further links (some of this content may be showing its age by now, but these are trustworthy sources - not to be ignored - Mensching is the WiX benevolent dictator):

      这篇关于应用程序是否依赖于编译它的环境?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆