自动更新桌面应用程序似乎是.NET中的一个难题。从microsoft的clickonce到各种开源和付费解决方案,有许多解决方案。所有这些模式都是:
1检查远程服务器以查找要运行的版本
2下载新版本
3打开包装到临时文件夹
4启动一个填充程序,在应用程序关闭后用新的替换旧文件
5杀死正在运行的应用程序,以便垫片进程可以开始工作
6重新启动主应用程序
这个过程似乎有许多活动部分和失败点。但是,您可以将应用程序编写为一个下载并执行远程dll的简单循环。这似乎避免了自动更新应用程序所涉及的许多复杂性,例如用户权限,uac,防病毒程序等。
这对我来说似乎是坚实的,也是未来的。我的应用程序不需要很多大型支持文件,所以我不应该使用这种方法吗?有没有办法可以犯这种错误?如果是这样,这些复杂性与其他自动更新解决方案的复杂性相比如何?
例如:
Thread helper;
int currentVersion=0;
static void Main()
{
//dumb loop, functions as a loader
while(true)
{
var remoteVersion = GetRemoteVersion();
if(remoteVersion > currentVersion)
{
if(helper != null)
{
//kill thread gracefully :)
}
currentVersion = remoteVersion;
byte[] bytes = GetRemoteDllAsByteArray();
var asm = Assembly.Load(bytes);
var t = asm.GetType("a known type with a static method called Start()");
var mi = t.GetMethod("Start");
//run this on a helper thread outside the main loop:
// the start method is the entry point to your application
helper= new Thread(() => mi.Invoke(null,null));
helper.SetApartmentState(ApartmentState.STA); //for winforms/wpf
helper.Start();
}
Thread.Sleep(1 day);//only check for new versions once a day
}
}
我的示例中的额外复杂性是您必须将所有依赖项打包为已下载的dll中的资源,但可以将其设置为构建步骤,并避免弄乱用户的文件系统。
答案 0 :(得分:1)
你的解决方案应该有效,如果你想保持简单,这似乎是一个很好的方法。
您应该在另一个域中加载程序集,因为如果您更新应用程序,则会在相同的名称空间中加载相同的类型。这会导致冲突。另一种方法是重新启动您的应用程序。
您不需要将所有依赖项打包为资源。使用下载,解压缩(zip)并包含所有程序集的二进制文件。
为此,您可以使用简单的方法(打包/解压缩):
在解析依赖关系时,您可以使用类似于此示例的内容:Assembly loaded using Assembly.LoadFrom() on remote machine causes SecurityException
还可以使用此系统为每个版本更新创建更新包(例如1.0 -> 1.5
或1.3 -> 1.5
)。如果首先检查已弃用的文件并为每个版本更新创建一个包,这可以避免大量流量。