C# 应用更新而不重新启动应用程序

C# 应用更新而不重新启动应用程序,c#,wpf,winforms,patch,auto-update,C#,Wpf,Winforms,Patch,Auto Update,最近我参加了一个.NET职位的面试。在被问到的问题中,我真的很难回答一个问题。我希望有人能在这方面帮助我 场景(问题):应用程序的第一个版本(可能是winform/wpf UI应用程序)已经发布给客户机,他们开始使用该应用程序。但不幸的是,QA团队后来在当前版本中发现了一个严重的问题。现在的挑战是,我们应该能够发送并应用补丁(补丁),而不必强制应用程序重新启动。假设应用程序是实时应用程序,无法重新启动以应用补丁程序 就我个人而言,我在给出一个令人信服的答案时遇到了真正的困难,这个答案在应用补丁时

最近我参加了一个.NET职位的面试。在被问到的问题中,我真的很难回答一个问题。我希望有人能在这方面帮助我

场景(问题):应用程序的第一个版本(可能是winform/wpf UI应用程序)已经发布给客户机,他们开始使用该应用程序。但不幸的是,QA团队后来在当前版本中发现了一个严重的问题。现在的挑战是,我们应该能够发送并应用补丁(补丁),而不必强制应用程序重新启动。假设应用程序是实时应用程序,无法重新启动以应用补丁程序

就我个人而言,我在给出一个令人信服的答案时遇到了真正的困难,这个答案在应用补丁时不会影响应用程序的运行

答复:


感谢您迄今为止的所有贡献。我已经设法解决了这个问题。不确定这是否是面试官问的。尽管如此,我还是很高兴了解到微软的ClickOnce,它几乎实现了我想要的功能。

将旧文件重命名为其他文件(如在文件名中添加“old”),并在新的可执行文件中复制相同的文件名。下次运行时,新的可执行文件将运行。

首先,您需要知道此应用程序是否依赖于配置文件,如xml、ini或任何形式的基于文本的文件。如果是这样,补丁可以作为配置插入,只要它们在当前流程范围之外可编辑


如果第一个解决方案不可行,那么第二个解决方案将确定正在运行的应用程序是否具有可靠的dll,以及通过引用dll注入补丁作为依赖项是否会暂时解决问题,直到调用重新启动。

对于当前正在运行的可执行文件,您几乎被卡住了-您无法明智地修改内存中运行的进程

然而,从DLL加载的东西要灵活得多。程序集可以在运行时动态加载,并且可以在单个应用程序中启动多个AppDomain。一种解决方案可能是这样的:

  • 您的可执行文件是一个薄包装器,它将所有功能传递给DLL
  • DLL功能已加载并通过单独的AppDomain运行
  • 当需要修补程序时,将复制新DLL(与现有DLL并排)
  • 无论是自动启动还是响应用户交互,都会在现有AppDomain的旁边启动一个新AppDomain,运行新补丁
  • 在应用程序中的适当位置(例如,全屏切换或定时刷新),新的AppDomain将成为“实时”AppDomain
  • 旧AppDomain已关闭并丢弃
然而,这是非常高层次的。在现实情况下,您很可能会有一个多层应用程序,其中包含缓存和实时数据以及许多其他考虑因素。例如,可能有必要将应用程序的前端逻辑与缓存或数据处理部分分开,以便在不干扰其余部分的情况下切换出任何一部分


某些不常见的技术可能在这里有用,具体取决于具体的需求。高级缓存允许在前端不丧失显示数据能力的情况下交换数据层。命令队列或可靠的消息传递机制可以使UI在业务层被调出时保持响应,然后新的业务层可以处理队列。如果您假设一个(逻辑上)基于服务器的应用程序,那么每一层的冗余可以允许一层的一个冗余“服务器”在另一个服务器继续处理时被更新。。。等等。

如果你从一开始就有这个要求,你可以将你的应用程序分成两个不同的应用程序——UI部分和一个在单个原子函数调用中完成所有工作的服务。最有可能的是,您的错误在服务中,因此您可以随时更换该应用程序,而不会中断用户体验。

修复程序适用于程序的哪一部分?只有用户界面?我想你可以使用MEF之类的工具卸载和重新加载更新的代码。这个问题可以解释为允许在不强制关闭的情况下进行更新(即覆盖文件),但在选择关闭和重新打开之前,应用不需要反映更改,在大多数情况下,这比将路径应用到运行中的程序要容易得多,该程序不需要重新运行就可以立即看到。@eandersson:位置不明确。尽管如此,如果它是一个UI修复程序或已在进程虚拟空间中的dll中的修复程序,您将如何处理?@eandersson:我向采访者提出的一个解决方案是,如果它是一个dll,那么您可以将其安装在GAC上,并将配置指向最新的dll。但是我无法扩展我的解决方案,因为我忘记了配置中的属性。然而,他拒绝了,因为dll的敏感性,并且只能作为私有汇编。即使你可以破解一个加载在内存中的程序,如果它正在处理数据,你仍然可以得到它,你如何保持数据的一致性?如果它是一个仅监控的应用程序,那么可能会将新版本作为一个单独的安装。启动它,然后停止旧的并删除它。但从技术上讲,这不是“修补”。你不能重命名正在使用的东西。这只适用于在加载过程中只读入一次的数据文件。@JeremyK这取决于它的使用方式,正如您在数据文件中指出的那样。即使在当前运行的情况下,可执行文件通常也可以被完全覆盖。这不是重命名某些文件。相反,在dll中实现一个已加载到进程/虚拟空间的修复程序。试想一个场景,交易员正在使用此应用程序捕捉滞后无法承受的市场反馈。这只是应用程序使用的一个任意示例。@sophieJ问题是,期望的最终结果是am