我想从远程服务器更新我的exe。因此,当按钮单击我的wpf应用程序时,它将下载远程和远程txt文件,并替换exe运行的同一文件夹中的当前文件。所以它会在我的exe运行时覆盖当前的txt和exe文件。我怎么能做到这一点?
远程主机的网址类似于www.mydomain.com/MyAPP.exe
wpf应用程序,c#4.0
答案 0 :(得分:2)
我们解决此问题的方法是创建一个shell exe,作为最初安装并部署到客户端计算机的shell。
“真正的”可执行程序存储在此初始应用程序的子目录中。启动shell应用程序后,在下载并安装了真实应用程序的任何更新后,它会在单独的AppDomain中启动真实应用程序的可执行文件。
以下是从shell应用程序中启动的“真实”应用程序的核心:
System.AppDomainSetup oSetup = new System.AppDomainSetup();
string sApplicationFile = null;
// Use this to ensure that if the application is running when the user performs the update, that we don't run into file locking issues.
oSetup.ShadowCopyFiles = "true";
oSetup.ApplicationName = sAppName;
// Generate the name of the DLL we are going to launch
sApplicationFile = System.IO.Path.Combine(sApplicationDirectory, sAppName + ".exe");
oSetup.ApplicationBase = sApplicationDirectory;
oSetup.ConfigurationFile = sApplicationFile + ".config";
oSetup.LoaderOptimization = LoaderOptimization.MultiDomain;
// Launch the application
System.AppDomain oAppDomain = AppDomain.CreateDomain(sAppName, AppDomain.CurrentDomain.Evidence, oSetup);
oAppDomain.SetData("App", sAppName);
oAppDomain.SetData("User", sUserName);
oAppDomain.SetData("Pwd", sUserPassword);
oAppDomain.ExecuteAssembly(sApplicationFile);
// When the launched application closes, close this application as well
Application.Exit();
请注意,在我们的版本中,shell应用程序会从用户收集用户名和密码,以便正确访问更新网站。然后,此数据将通过AppDomain上的SetData
方法传递给“真实”应用。
答案 1 :(得分:2)
解决方案取决于您的具体情况。但是没有直接的解决方案,因为在将程序集加载到内存并使用时无法更新程序集。我可以提出两个解决方案:使用shadow copying并使用某种辅助可执行文件。我已经使用了它们。
影子复制。
显而易见的方法是将主要可执行文件复制为阴影,在应用程序运行时替换它,然后重新启动应用程序。但是无法使您的默认应用域被复制阴影,只有辅助应用域才可以。但您仍然可以将所有代码移动到另一个程序集(例如,MainAppLib.dll)并重写主应用程序可执行文件(MainApp.exe),使其仅包含“加载程序代码”。此加载程序代码必须创建另一个应用程序域,将其设置为阴影复制,然后在辅助应用程序域中运行程序逻辑。请注意,不要将主应用程序域直接引用到MainAppLib.dll中,因为这个程序集将被加载到主应用程序域中,而不会复制卷影并且程序集文件将被锁定。在大多数情况下,您可以使用AppDomain.ExecuteAssembly()方法。
帮助程式可执行文件
我们的想法是使用某种更新修整程序。您的主应用程序保持不变,您只需在其中添加少量代码,以便您的应用程序将下载更新,将其放入临时文件夹,然后您的主应用程序启动更新修整程序(在单独的过程中 )并退出。更新修整程序等待您的应用程序关闭,然后将新文件从临时文件夹复制到您的应用程序文件夹中,替换所有文件。更新修整程序不能替换它自己的可执行文件,但可以在启动更新修整程序之前由主应用程序完成。复制文件后,更新修整程序将运行您的应用程序。
p.s。就我个人而言,我更喜欢以前的解决方案,因为它涉及使用应用程序域,反射,程序集e.t.c的某种伏都教法术。如果需要,它可以演变为使用插件(例如通过MEF framework)。但后者更容易理解,特别是如果您从未使用过应用程序域和手动程序集加载,那就非常简单了。
答案 2 :(得分:1)
你可能会使用ClickOnce(基于你上面的评论,你会准备让另一个程序集获得exe ...因为另一个海报提到你无法替换正在运行的程序集)。您可以将其配置为在新版本的不同时间(例如在启动时)进行检查,并自动下载它们。它是一个非常强大的解决方案,您可以使用部署程序集做很多事情。