动态加载组件 - 设置和通信

2024-05-02

好吧...我有一个 WPF 应用程序(我们称之为Launcher.exe)它加载并执行另一个 WPF 应用程序(我们称之为Loaded.exe)动态地使用这样的东西:

Byte[] assemblyData;

using (BinaryReader reader = new BinaryReader(new FileStream(filePath, FileMode.Open)))
    assemblyData = reader.ReadBytes(Convert.ToInt32(fs.Length));

Assembly assembly = Assembly.Load(assemblyData);
MethodInfo method = assembly.EntryPoint;

if (method != null)
{
    Object instance = assembly.CreateInstance(method.Name);
    method.Invoke(o, null);
}

现在...问题是Launched.exe文件中有自己的设置Loaded.exe.config,并且还在绑定中使用它们。例如:

Topmost="{Binding Mode=TwoWay, Path=Topmost, Source={x:Static p:Settings.Default}}"

第一个问题是,如何使动态加载的程序集正确加载/绑定/更新,并且更一般地说,使用其自己的设置?我不认为它可以自动处理这个问题......

第二个问题是:可以Loaded.exe与交流Launcher.exe?比方说Loaded.exe只需要一些数据Launcher.exe能找回来……怎么能要呢?我想我需要两个程序集之间的代理之类的东西,但我什至不知道如何开始编码......


我想您需要使用它自己的 .config 文件加载一个单独的程序集,不是吗? 我这样做的一种方法是将程序集加载到新的 AppDomain 中。您可以将该程序集部署在一个单独的文件夹中,并包含所有所需的引用。

首先设置AppDomain,这里有一个方法:

AppDomain getAppDomainForAssembly(string assemblypath, string appdomainname) 
    {
        //this._assembly_file = AssemblyFile;

        string _assembly_file_name = System.IO.Path.GetFileName(assemblypath);
        string _rootpath = System.IO.Path.GetDirectoryName(assemblypath);

        //this._assembly_class_name = AssemblyClassNameToInstance;
        AppDomainSetup _app_domain_info = new AppDomainSetup();
        _app_domain_info.ApplicationBase = _rootpath;
        _app_domain_info.PrivateBinPath = _rootpath;
        _app_domain_info.PrivateBinPathProbe = _rootpath;
        _app_domain_info.ConfigurationFile = _rootpath + @"\app.config"; //Here put the path to the correct .assembly .config file
        AppDomain _app_domain = AppDomain.CreateDomain(
            appdomainname, null, _app_domain_info);

        return _app_domain;
    }

然后获取在程序集上执行该方法的对象的实例:

protected System.Reflection.Assembly _asm_resolve(string assemblyFile)
    {
        return System.Reflection.Assembly.LoadFrom(assemblyFile);
    }

object getInstanceFromAppDomain(ref AppDomain appDomain, 
  string assemblyPath, string className = null) 
    {
        if (string.IsNullOrEmpty(className))
        {
            System.Reflection.Assembly assembly = _asm_resolve(assemblyPath);
            System.Reflection.MethodInfo method = assembly.EntryPoint;

            return appDomain.CreateInstanceFromAndUnwrap(assemblyPath, method.Name);
        }
        else 
        {

            return appDomain.CreateInstanceFromAndUnwrap(assemblyPath, className);

        }
    }

即使我们知道对象类型,我们也可以创建一个具有泛型类型的方法:

T getInstanceFromAppDomain<T>(ref AppDomain appDomain, 
 string assemblyPath, string className = null) 
    {
        if (string.IsNullOrEmpty(className))
        {
            System.Reflection.Assembly assembly = _asm_resolve(assemblyPath);
            System.Reflection.MethodInfo method = assembly.EntryPoint;

            return (T)appDomain.CreateInstanceFromAndUnwrap(assemblyPath, method.Name);
        }
        else 
        {

            return (T)appDomain.CreateInstanceFromAndUnwrap(assemblyPath, className);

        }
    }

然后,在创建的实例上调用该方法,该方法在新的 appDomain 中执行:

void executeMethod(Type objecttype, string methodname, ref object instancedObject, object[] methodparams) 
    {
        objecttype.InvokeMember(
            methodname, System.Reflection.BindingFlags.InvokeMethod, null, instancedObject, methodparams);
    }

你可以这样使用:

AppDomain newappdomain = getAppDomainForAssembly(filePath, "Loaded.exe.domain");
        object loadedexe_object = getInstanceFromAppDomain(ref newappdomain,
            filePath);

        //If you know the method name to call...
        executeMethod(loadedexe_object.GetType(), "methodname", ref loadedexe_object, null);

        //or get entry point...
        executeMethod(loadedexe_object.GetType(),
            _asm_resolve(filePath).EntryPoint.Name, ref loadedexe_object, null);

对于第二个问题,您可以使用NamedPipes、Remoting、WCF... 您需要在同一台机器上实现进程间通信。 查看 MSDN 文档,使用 WCF 涵盖此场景的代码示例http://msdn.microsoft.com/en-us/library/system.servicemodel.netnamedpipebinding.aspx http://msdn.microsoft.com/en-us/library/system.servicemodel.netnamedpipebinding.aspx

请参阅 CodeProject 上的此示例,使用远程处理通过远程处理进行进程间通信 http://tech.pro/tutorial/633/interprocess-communication-using-named-pipes-in-csharp

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

动态加载组件 - 设置和通信 的相关文章

随机推荐

  • JQuery:如果自定义类包含大于“x”的数字,请添加 CSS 代码

    我想将 css 添加到指定的跨度类 如果它包含高于 55 的数字 而且这必须在页面加载上而不是按钮触发器上 谢谢任何帮助都会很棒 示例如下 目前不起作用 span class subTotalPrice 10 span span class
  • 在Java中,什么时候调用枚举常量的构造函数?

    要使用 Java 中的一个人为示例 代码如下 enum Commands Save S File F private String shortCut private Commands String shortCut this shortCu
  • 如何在Spring JPA中为审计字段@CreatedDate、@LastModifiedDate保存UTC格式的时间戳

    这是我的带有审计字段的实体的基类 对于字段 CreatedDate LastModifiedDate 默认情况下它会节省我的系统时间 我的要求是以 UTC 格式保存时间戳 有人有解决这个问题的方法吗 import java time Loc
  • 如何让我的应用程序出现在应用程序选择器中?

    我想宣传一下 我的应用程序能够查看 pdf 文件 这样当从文件管理器中选择 pdf 文件时 它就会出现在应用程序选择器中 这是我的意图过滤器的样子
  • 如何禁用 mui 文本字段自动完成?

    我正在使用最新版本的 mui 我有一个包含邮政编码字段的用户联系信息表单 如果值为空 我不希望此字段自动完成 但它会随着浏览器中保存的电子邮件自动完成 这是我到目前为止所尝试过的 自动完成 关闭 自动完成 关闭 自动完成 不 这是我的文本字
  • 使用 Cypher,如何返回仅包含其属性子集的节点

    假设我在 Neo4j 中创建了一个节点 CREATE Thing a foo b bar 我可以编写一个查询来获取该节点及其所有属性 MATCH n Thing a foo RETURN n 返回 a foo b bar 但是是否可以匹配一
  • 如何去掉gridview中的空格

    这件事已经困扰我有一段时间了 我似乎无法解决它 我有一个网格视图 在其中显示一些位图 通过适配器填充图像视图时 我在所有图像侧面添加了 5dp 的填充 iv setPadding 5 5 5 5 但不知何故 每个图像的顶部和底部都添加了更多
  • Android:如何以编程方式打开和关闭屏幕?

    在将这篇文章标记为 重复 之前 我写这篇文章是因为没有其他文章可以解决该问题 我正在尝试关闭设备 然后在几分钟或传感器发生变化后 将其重新打开 关闭显示测试 我可以使用以下方法关闭屏幕 params flags LayoutParams F
  • 在 Google Data Flow 上的 Spring Boot 项目中运行 Apache Beam 管道

    我正在尝试在 Google Data Flow 上的 Spring Boot 项目中运行 Apache Beam 管道 但我一直遇到此错误Failed to construct instance from factory method Da
  • 如何在 BlobStore 中设置文件名属性?

    我正在以编程方式上传图像文件并想要设置文件名 当我通过 POST 上传文件时 文件名属性会自动设置 但是 当使用下面的方法时 文件名未设置 image urllib2 urlopen url file name files blobstor
  • Google Play 商店中不支持的设备 - Flutter

    我已将我的应用程序上传到谷歌商店 但我的一些朋友无法安装它 他们得到 您的设备与此版本不兼容 我已经检查了sdk 屏幕尺寸和权限要求 也将uses features required设置为false 但仍然有一些设备无法安装它 我在游戏控制
  • 如何在 ASP.NET MVC 中构建选项卡式菜单?

    我想构建一个与 StackOverflow 的配置文件管理非常相似的选项卡式菜单 选项卡式菜单 StackOverflow http img410 imageshack us img410 3037 image1nw r jpg http
  • 使用 OpenMP 时无用的 printf 没有加速

    我刚刚编写了第一个 OpenMP 程序 它并行化了一个简单的 for 循环 我在双核机器上运行代码 发现从 1 个线程变为 2 个线程时速度有所提高 然而 我在学校 Linux 服务器上运行相同的代码并没有看到加速 在尝试了不同的事情之后
  • UNION ALL mysql 子句中的行默认顺序?..我的意思是,首先提取哪一行?

    例如 如果我有一个真正简单的查询 选择1 联合所有 选择2 然后通过 Perl 或 PHP 获取行 我会将 1 作为第一行 将 2 作为第二行吗 这种行为在任何地方都有描述吗 Thanx 没有默认顺序 无论是在表中还是在查询中 除非您使用
  • 如果循环符号链接没有用,那为什么允许它们呢?

    我刚刚在这里读这篇文章 类 Unix 系统中的循环符号链接有何用途 https stackoverflow com questions 12680821 what are circular symlinks in unix like sys
  • 从 URL 加载 Xml 时出现超时错误

    我正在执行将实时 xml 文件 从实时 url 加载到 XmlDataDocument 的任务 但每次我都会收到错误 操作已超时 代码如下 包含xml feeds的url 我想将其加载到xmlDoc中 XmlDataDocument xml
  • Oracle:在更新具有多列的表的一个字段时复制行

    有没有一种方法可以一般复制一行 特别是在不指定所有列的情况下 在我的情况下 我有一个大表 我想在其中复制除 ID 和另一列之外的所有列 事实上 数据是在年初复制的 该表有 50 多列 因此如果我不必指定所有列 则更改架构会更加灵活和稳健 这
  • 扩展程序上传后,typo3 网站离线[关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我刚刚向typo3 网站上传了一个新扩展 该网站就离线了 我收到 500 内部服务器错误 我可以做什么来倒回操作和 或使
  • Windows Unicode C++ 流输出失败

    我目前正在编写一个应用程序 它要求我在任意窗口上调用 GetWindowText 并将该数据存储到文件中以供以后处理 长话短说 我注意到我的工具在 战地 3 上失败了 我将问题范围缩小到窗口标题中的以下字符 http www filefor
  • 动态加载组件 - 设置和通信

    好吧 我有一个 WPF 应用程序 我们称之为Launcher exe 它加载并执行另一个 WPF 应用程序 我们称之为Loaded exe 动态地使用这样的东西 Byte assemblyData using BinaryReader re