Tag: appdomain

如何正常卸载已运行线程的子AppDomain

我有一个加载子AppDomain的服务,然后启动一个在其中运行的线程。 它需要一个AppDomain,因为它动态生成并加载一些代码,我需要能够重新启动它而不会终止整个服务。 因此,在子AppDomain的事件循环中运行一个线程,它通过MarshalByRefObject传递给它的事件,MarshalByRefObject将东西粘在并发队列中。 我想停止并卸载子AppDomain并创建一个新的AppDomain。 我可以简单地在子AppDomain上调用Unload,但这将中止所有线程并抛出ThrearAbortException。 我怎样才能优雅地把它关掉? 如果我使用MarshalByRefObject在子AppDomain中设置一些静态标志,那么主进程如何能够等到它完成卸载? 我有一些示例代码,它显示了它的设置以及如何调用Unload来杀死它,我怎么能修改它以允许正常卸载并且永远不会有多个子AppDomains? using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Security; using System.Security.Permissions; using System.Reflection; using System.Threading; namespace TestAppDomains { /// /// Calls to methods magically get transfered to the appdomain it was created in because it derives from MarshalByRefObject /// class MarshalProxy : MarshalByRefObject { public AppDomain […]

列出存储在AppDomain中的所有自定义数据

为了在发生错误时存储进程状态,我想列出存储在AppDomain中的所有(自定义)数据(通过SetData)。 LocalStore属性是私有的,AppDomain类不可inheritance。 有没有办法枚举这些数据?

MEF和ShadowCopying DLL,以便我可以在运行时覆盖它们

我试图阻止我的应用程序锁定我的MEF插件目录中的DLL,以便我可以在运行时覆盖程序集(注意我实际上并没有尝试让MEF在运行时重新加载它们,在下一个应用程序启动很好,我只是不想要停止应用程序来复制) 我试图通过为我的mef加载的程序集创建一个阴影复制的应用程序域来执行此操作,如下所示: [Serializable] public class Composer:IComposer { private readonly string _pluginPath; public Composer(IConfigurePluginDirectory pluginDirectoryConfig) { _pluginPath = pluginDirectoryConfig.Path; var setup = new AppDomainSetup(); setup.ShadowCopyFiles = “true”; // really??? is bool not good enough for you? var appDomain = AppDomain.CreateDomain(AppDomain.CurrentDomain.FriendlyName + “_PluginDomain”, AppDomain.CurrentDomain.Evidence, setup); appDomain.DoCallBack(new CrossAppDomainDelegate(DoWorkInShadowCopiedDomain)); } private void DoWorkInShadowCopiedDomain() { // This work will happen […]

编组C ++指针接口通过C#函数调用非默认AppDomain

我在C ++和C#代码之间有一个有效的CLI接口。 代码有一个C ++抽象接口,如: ————-C++ Interface————— namespace cppns { class cppInterface { public: virtual bool Start(const char *pcDir) = 0; }; } ——Implementation of abstract C++ interface in same dll——— namespace cppns { class cppimp : public cppInterface private: gcroot mInternalClassAccess; public: cppimp::cppimp() { mInternalClassAccess = gcnew MyInternalCSharpClass(); } virtual bool cppimp::Start(const char *pcDir) { […]

将DLL加载到具有已知唯一公共接口的单独AppDomain中

我需要在另一个域中加载.dll(插件)。 在主应用程序中,我对插件类型一无所知,只是他们用一些方法实现了通用接口ICommonInterface。 因此,这段代码无济于事,因为我无法创建具有接口类型的实例。 AppDomain domain = AppDomain.CreateDomain(“New domain name”); //Do other things to the domain like set the security policy string pathToDll = @”C:\myDll.dll”; //Full path to dll you want to load Type t = typeof(TypeIWantToLoad); TypeIWantToLoad myObject = (TypeIWantToLoad)domain.CreateInstanceFromAndUnwrap(pathToDll, t.FullName); 我的问题是我如何在新域中加载程序集并获取实例,如果我只知道实现我想要创建的类型的接口名称。 更新:这是我的代码:MainLib.dll namespace MainLib { public interface ICommonInterface { void ShowDllName(); } } PluginWithOutException.dll […]

枚举所有没有mscoree的AppDomain

如何在不引用mscoree情况下枚举所有进程的域。 可能吗? 我从互联网上的某个地方找到了2007年的解决方案。 但它列举并清空收集。 这是代码: public static class DomainHelper { public static AppDomain[] LoadedDomains { get { var loadedDomains = new List(); var runtimeHost = new CorRuntimeHost() as ICorRuntimeHost; try { var enumeration = IntPtr.Zero; runtimeHost.EnumDomains(out enumeration); try { object nextDomain = null; runtimeHost.NextDomain(enumeration, ref nextDomain); while (nextDomain != null) { loadedDomains.Add((AppDomain) nextDomain); nextDomain = […]

自定义AppDomain和PrivateBinPath

我正在使用c#4.0和一个仅用于测试的控制台应用程序,以下代码确实给出了exception。 AppDomainSetup appSetup = new AppDomainSetup() { ApplicationName = “PluginsDomain”, ApplicationBase = AppDomain.CurrentDomain.BaseDirectory, PrivateBinPath = @”Plugins”, ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile }; AppDomain appDomain = AppDomain.CreateDomain(“PluginsDomain”, null, appSetup); AssemblyName assemblyName = AssemblyName.GetAssemblyName(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, “Plugins”, “sample.dll”)); Assembly assembly = appDomain.Load(assemblyName); //This gives an exception of File not found AppDomain.Unload(appDomain); 在我创建的AppDomain上使用Load时,我一直收到File not foundexception。 谢谢。

COM互操作是否尊重.NET AppDomain边界以进行程序集加载?

这是核心问题:我有一个在单独的AppDomain中使用COM互操作的.NET应用程序。 COM的东西似乎是将程序集加载回默认域,而不是从中调用COM内容的AppDomain。 我想知道的是:这是预期的行为,还是我做错了导致这些COM相关的程序集被加载到错误的AppDomain中? 请参阅以下情况的更详细说明…… 该应用程序由3个程序集组成: – 主EXE,应用程序的入口点。 – common.dll,只包含一个接口IController(采用IPlugin风格) – controller.dll,包含一个实现IController和MarshalByRefObject的Controller类。 此类完成所有工作并使用COM interop与另一个应用程序进行交互。 主要EXE的相关部分如下所示: AppDomain controller_domain = AppDomain.CreateDomain(“Controller Domain”); IController c = (IController)controller_domain.CreateInstanceFromAndUnwrap(“controller.dll”, “MyNamespace.Controller”); result = c.Run(); AppDomain.Unload(controller_domain); common.dll只包含以下两件事: public enum ControllerRunResult{FatalError, Finished, NonFatalError, NotRun} public interface IController { ControllerRunResult Run(); } controller.dll包含这个类(也调用COM互操作的东西): public class Controller: IController, MarshalByRefObject 首次运行应用程序时,Assembly.GetAssemblies()看起来像预期的那样,在两个AppDomain中都加载了common.dll,并且只将controller.dll加载到控制器域中。 在调用c.Run()之后,我看到与COM互操作相关的程序集已加载到默认的AppDomain中,而不是在发生COM互操作的AppDomain中。 为什么会发生这种情况? 如果你有兴趣,这里有一些背景知识: 最初这是一个1 AppDomain应用程序。 它与之接口的COM东西是一个服务器API,在长时间使用时不稳定。 […]

加载程序集时依赖于另一个域的FileNotFound

我正在尝试使用插件进行应用程序。 我有MainLib.dll,我用1方法制作了一些commnon接口(让它是ICommon )。 然后,我制作了2个.dll(插件),它们引用了MainLib.dll并在某些类中实现了ICommon 。 此外,我删除了此.dlls exept System所有引用。 然后,我创建了一个应用程序,它监视文件夹”.\\Plugins”并加载newDomain所有.dll,检查.dll中的类型是否实现了ICommon (因此该应用程序也引用了MainLib.dll)。 如果是 – 在某些列表中添加.dll的名称。 现在问题出现了 :在我尝试加载插件之前 – 我将MailLib.dll和System加载到newDomain,因为所有插件都依赖于这个.dll。 他们加载正确。 然后,我开始加载插件,在这里我有: FileNotFoundException,无法加载文件或程序集’PluginWithException,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null’或其依赖项之一。 系统找不到指定的文件。)字符串上的程序集loadedAssembly = domain.Load(Assembly.LoadFrom(asm).FullName); PluginWithException程序集只有2个依赖项–System和MainLib。 在我尝试加载PluginWithException之前,我检查了新域中的程序集,System和MainLib已加载到此域。 所以我看不到任何依赖的问题。 我阅读了这个主题,并ProxyDomain使用ProxyDomain解决方案,但exception是相同的。 我做错了什么? 这里的代码: public static List SearchPlugins(string[] names) { AppDomain domain = AppDomain.CreateDomain(“tmpDomain”); domain.Load(Assembly.LoadFrom(@”.\MainLib.dll”).FullName); domain.Load(@”System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089″); MessageBox.Show(GetAssembies(domain)); // here I can […]

C ++ DLL不会使用AppDomain卸载

我有一个使用单独的C ++ DLL的C#插件。 对该DLL的唯一引用来自插件本身。 父应用程序将所有插件加载到自己的AppDomain中,并在卸载插件时卸载此AppDomain。 我已经检查了,当我卸载插件时,我肯定会看到应用程序的内存丢失。 我还能够删除所有已加载的托管程序集。 问题是,当我尝试删除本机DLL时,我只是继续拒绝访问,直到我关闭整个应用程序。 我已经看了一段时间,但我仍然无法弄清楚为什么这个DLL留在内存中。