我需要为使用 .Net 4.0 或 4.5 构建的桌面应用程序开发自动更新机制。它不应下载或更新任何 dll 或 exe 文件。这是公司的政策,我不能改变。
但是,允许下载任何类型的脚本、c# 代码、xml、json、xaml 等,这些脚本可以存储在此应用程序正在使用的 SQL 数据库中。
任何想法如何构建这种更新程序?有什么标准的方法或框架吗?
我需要为使用 .Net 4.0 或 4.5 构建的桌面应用程序开发自动更新机制。它不应下载或更新任何 dll 或 exe 文件。这是公司的政策,我不能改变。
但是,允许下载任何类型的脚本、c# 代码、xml、json、xaml 等,这些脚本可以存储在此应用程序正在使用的 SQL 数据库中。
任何想法如何构建这种更新程序?有什么标准的方法或框架吗?
由于不要求“下载二进制文件”,您将需要使用CSharpCodeProvider将您的 .cs 文件转换为程序集,然后可以按照我在原始答案中的描述进行加载。这是一个关于代码项目的很好的教程,关于如何在运行时使用该类来编译你的 .cs 代码。
原答案:
扩展杰西的评论。您的主程序需要是一个简单的加载程序,可以查询包含真实文件的“程序数据库”。
加载过程有 2 个阶段:引导 AppDomin、加载程序集
要引导您的应用程序域,您需要创建一个新的 AppDomain,将其限制为仅加载签名文件,然后加载加载其余 DLL 的加载程序
在您的代码中,您需要创建一个新的 AppDomain以将文件加载到其中。在该应用程序域中,您将希望创建一个仅允许加载由您的私钥签名的程序集的证据。
//Assumes you have your X509Certificate (the version that only has the public key)
// stored in Settings.Resources.
var onlySignedByMe = new Publisher(Settings.Resources.MyCompanyCertificate);
var evidence = new Evidence();
evedence.(onlySignedByMe);
var adi = new AppDomainInitializer(AppDomainInit);
var appDomainSetup = new AppDomainSetup();
appDomainSetup.AppDomainInitializer = adi;
appDomainSetup.ApplicationBase = System.Environment.CurrentDirectory;
var programAppDomain = AppDomain.CreateDomain("programAppDomain", evidence, appDomainSetup, PermissionSet(PermissionState.Unrestricted));
当 AppDomian 初始化时,它将从新域调用 AppDomainInit。从那里查询数据库以获取它需要加载的任何程序集。将这些文件加载到byte[]
然后byte[]
使用AppDomain 上的 Load 方法加载
private static void AppDomainInit(string[] args)
{
List<Byte[]> assemblies;
//Snip, populating the list;
Asesembly entryAssembly;
foreach(var assembly in assemblies)
{
var loadedAssembly = Assembly.Load(assembly);
if(TestForKnownEntryPointAssembly(loadedAssembly)
entryAssembly = loadedAssembly;
}
if(entryAssembly != null)
{
Type type = entryAssembly.GetType("MyNamespace.EntryClass");
MethodInfo method = type.GetMethod("Main");
method.Invoke(null, null);
}
}
这都是凭记忆写的,所以可能会有一些错误。