0

我需要为使用 .Net 4.0 或 4.5 构建的桌面应用程序开发自动更新机制。它不应下载或更新任何 dll 或 exe 文件。这是公司的政策,我不能改变。

但是,允许下载任何类型的脚本、c# 代码、xml、json、xaml 等,这些脚本可以存储在此应用程序正在使用的 SQL 数据库中。

任何想法如何构建这种更新程序?有什么标准的方法或框架吗?

4

1 回答 1

1

由于不要求“下载二进制文件”,您将需要使用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);
    }

}

这都是凭记忆写的,所以可能会有一些错误。

于 2012-10-19T16:11:23.780 回答