我想加载到一个新的AppDomain一些具有复杂引用树的程序集(MyDll.dll - > Microsoft.Office.Interop.Excel.dll - > Microsoft.Vbe.Interop.dll - > Office.dll - > stdole.dll)
据我所知,当加载程序集时AppDomain,它的引用不会自动加载,我必须手动加载它们.所以当我这样做时:
string dir = @"SomePath"; // different from AppDomain.CurrentDomain.BaseDirectory
string path = System.IO.Path.Combine(dir, "MyDll.dll");
AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
setup.ApplicationBase = dir;
AppDomain domain = AppDomain.CreateDomain("SomeAppDomain", null, setup);
domain.Load(AssemblyName.GetAssemblyName(path));
Run Code Online (Sandbox Code Playgroud)
得到了FileNotFoundException:
无法加载文件或程序集"MyDll,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null"或其依赖项之一.该系统找不到指定的文件.
我认为关键部分是其依赖性之一.
好的,我之前做过 domain.Load(AssemblyName.GetAssemblyName(path));
foreach (AssemblyName refAsmName in Assembly.ReflectionOnlyLoadFrom(path).GetReferencedAssemblies())
{
domain.Load(refAsmName);
}
Run Code Online (Sandbox Code Playgroud)
但FileNotFoundException又一次,在另一个(参考)集会上.
如何递归加载所有引用?
在加载根程序集之前是否必须创建引用树?如何在不加载程序集的情况下获取程序集的引用?
我知道至少在这里已经提出了这个问题.
但是没有一个令人满意的答案,至少对我没有.关于与非托管代码的互操作,有很多关于编组的讨论,但是从一个线程到另一个线程的编组呢,就像我们在.NET中必须做的那样.
这让我问,什么是编组,真的吗?当您给出编组的定义时,您将如何定义它以便解释互操作性的情况,以及您在线程之间"编组"的情况?
.net multithreading definition language-interoperability marshalling
我需要在运行时加载的程序集中执行一个方法.现在我想在方法调用后卸载那些已加载的程序集.我知道我需要一个新的AppDomain,所以我可以卸载库.但在这里,出现了问题.
要加载的程序集是我的插件框架中的插件.他们根本没有切入点.我所知道的是它们包含一些实现给定接口的类型.旧的非AppDomain代码看起来像这样(稍微缩短):
try
{
string path = Path.GetFullPath("C:\library.dll");
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
Assembly asm = Assembly.LoadFrom(path);
Type[] types = asm.GetExportedTypes();
foreach (Type t in types)
{
if ((t.GetInterface("IStarter") != null) && !t.IsAbstract)
{
object tempObj = Activator.CreateInstance(t);
MethodInfo info = t.GetMethod("GetParameters");
if (info != null)
{
return info.Invoke(tempObj, null) as string;
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(String.Format("Damn '{0}'.", ex.Message), "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
if (args.Name.StartsWith("MyProject.View,"))
{
string path = Path.GetFullPath("C:\view.dll"));
return …Run Code Online (Sandbox Code Playgroud) 好的,在运行时解析如何在正在运行的应用程序中加载DLL之后(参见我之前的帖子),我注意到在新加载的DLL中插入的断点没有被命中.
情况
我有一个服务器应用程序,我想避免每次我更改动态加载的DLL时终止/重新运行(通过反射)
目标
这是我想要做的事情(我知道这本身可能不可能):
问题
我注意到当在调试模式下启动Application.exe时,附加到Application.exe的调试器无法访问从另一个AppDomain加载的代码(我想如果我只是直接从可执行文件启动Application.exe,则没有让VS调试器调试任何东西的方法,包括新加载的DLL)
可能的解决方法
一个变通方法(丑陋的)解决方案是将DLL的"注入"分离到一个单独的可执行文件中运行的应用程序,然后由VS调试器监视
我承认我有点困惑.任何有效,干净的想法?
所以我正在创建 dll 类型文件,运行它们,然后我想删除它们。
然而,当我尝试删除它们时,我得到一个异常,因为它声称它们仍在被另一个进程使用。
我假设用于创建文件的代码没有正确处理资源以允许删除文件,这是我创建文件的代码。
if (!Directory.Exists(PathToRobots + Generation))
{
Directory.CreateDirectory(PathToRobots + Generation);
}
File.WriteAllText(Path.Combine(PathToRobots + Generation, NameSpace + GetRobotName() + robotNumber + ".cs"), code);
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters()
{
GenerateInMemory = false,
GenerateExecutable = false, // True = EXE, False = DLL
IncludeDebugInformation = true,
OutputAssembly = Path.Combine(FileName + ".dll") // Compilation name
};
parameters.ReferencedAssemblies.Add(@"robocode.dll");
CompilerResults results = provider.CompileAssemblyFromSource(parameters, code);
if (results.Errors.HasErrors)
{
StringBuilder sb = new StringBuilder();
foreach (CompilerError error in results.Errors) …Run Code Online (Sandbox Code Playgroud) 在 MVC 控制器中,我用来AssemblyLoadContext.Default.LoadFromAssemblyPath(pathToDll);加载程序集。我想在运行时删除或替换给定的 .dll 文件。这是不可能的,因为该文件没有被释放。有什么方法可以处理.dll 文件吗?有一些使用该类AppDomain的解决方案,但在 ASP.NET Core 中不可用。
背景:用户可以上传包含给定接口实现的自定义 .dll 文件。用户还应该能够替换他的文件。我在控制器中使用以下代码来访问实现:
var conventions = new ConventionBuilder();
conventions
.ForTypesDerivedFrom<IPluginContract>()
.Export<IPluginContract>()
.Shared();
var configuration = new ContainerConfiguration().WithAssembliesInPath(path, conventions);
using (var container = configuration.CreateContainer())
{
var plugins = container.GetExports<IPluginContract>();
return plugins;
}
Run Code Online (Sandbox Code Playgroud)
和
public static ContainerConfiguration WithAssembliesInPath(
this ContainerConfiguration configuration,
string path, AttributedModelProvider conventions,
SearchOption searchOption = SearchOption.TopDirectoryOnly)
{
var fileNames = Directory
.GetFiles(path, "*.dll", searchOption);
List<Assembly> assemblies = new List<Assembly>();
foreach (string relativePath in fileNames)
{ …Run Code Online (Sandbox Code Playgroud) 我开发了一些USB通信的定制设备。我使用这个 USB dll 让事情变得更容易:
非常好的库,但有一个小错误。例如,如果我向 USB 设备发送某些内容,而设备没有响应(这不是正确的命令等),则该 dll 工具箱等待命令响应到无穷大!
现在,如果几秒钟后没有进一步响应,我想添加一些超时。
我现在使用带有布尔状态响应的方法,我知道读取是否成功。
var readreport = _choosendevice.ReadReport();
Run Code Online (Sandbox Code Playgroud)
后来我需要“readreport”变量,因为里面(readreport.Data)是接受数据。
我的问题是如何将这一行实现到一些超时命令中?我已经找到了错误的解决方案,但对我不起作用(错误修复链接)。
如有任何问题请询问。如果问题没有以正确的方式提出,抱歉,因为我是 C# 初学者。谢谢!求助
c# ×6
.net ×4
appdomain ×2
reflection ×2
asp.net-core ×1
assemblies ×1
definition ×1
file ×1
marshalling ×1
mmc ×1
timeout ×1