标签: assembly-loading

COM互操作程序集加载顺序

我的Outlook插件遇到了非常奇怪的程序集引用问题和加载问题.这是细节(长篇大论:)):

我有一个旧的Outlook插件,使用.Net 1.1编写和构建.在其自己的应用程序域中使用非托管填充程序加载插件.即使用户的计算机上没有1.1,也可以使用.Net 2.0.

该插件使用由VS 2003针对Outlook 2000创建的自定义Outlook互操作程序集,并在该重建之后进行强名称(就像我的插件一样).

在addin项目中,我只引用了这个自定义互操作程序集,没有引用官方MS互操作程序集.

当这个插件在Outlook 2007和.Net 2.0环境中使用时,官方MS互操作程序集安装在GAC中,由于某种原因,我看到插件加载并使用它们.

在Connect类的代码中,我有一个using指令:

using Outlook;
Run Code Online (Sandbox Code Playgroud)

这是我的自定义互操作程序集的命名空间.

在Connect ctor中,我有这些代码行(为了测试目的而添加):

Assembly.LoadFrom(PATHTOMYASSEMBLY + "Interop.Outlook.dll");
Type type = typeof(Outlook.ApplicationClass);
logger.Debug("Outlook.Application full type is: {0}", type.AssemblyQualifiedName);
Run Code Online (Sandbox Code Playgroud)

这输出:

Outlook.Application完整类型是:Outlook.ApplicationClass,Interop.Outlook,Version = 9.0.0.0,Culture = neutral,PublicKeyToken = 4cfbdc5349cf59d8

这正是我所期望的.

问题是,当调用OnConnection(对象应用程序,Extensibility.ext_ConnectMode connectMode,对象addInInst,ref System.Array自定义)时,我在日志中看到(我有一个当前域的AssemblyLoad事件的钩子)MS interop程序集也被加载:

private void app_domain_AssemblyLoad(object sender, AssemblyLoadEventArgs args)
{
    Assembly loadedAssembly = args.LoadedAssembly;
    logger.Debug("Assembly {0} is loaded from: {1}", loadedAssembly.FullName, loadedAssembly.GlobalAssemblyCache ? "GAC" : loadedAssembly.Location);
}
Run Code Online (Sandbox Code Playgroud)

输出:

程序集Microsoft.Office.Interop.Outlook,Version = 12.0.0.0,Culture = neutral,PublicKeyToken = 71e9bce111e9429c从以下位置加载:GAC

我的OnConnection方法如下所示:

public void OnConnection(object application, …
Run Code Online (Sandbox Code Playgroud)

.net outlook interop gac assembly-loading

6
推荐指数
1
解决办法
2750
查看次数

由于x86 - x64 - MSIL差异,TeamCity NUnit运行器失败

我有一堆项目的解决方案,其中一些也有测试项目.这些都是为Any CPU平台编译的.

在TeamCity中,我有一个NUnit 2.6.4的构建配置,我在其上指定Platform: auto (MSIL)Version: 4.0.

当我运行构建时,测试失败并显示以下消息:

NUnit error running tests in 'C:\BuildAgent\work\a58fc6cd9bf63032\JsonApi.Tests\obj\Release\JsonApi.Tests.dll' assembly
Loading assembly is compiled for v4.0.30319, MSIL
NUnit runner runtime is v4.0.30319, x64
Run Code Online (Sandbox Code Playgroud)

更奇怪的是,当我刚刚关闭"最近运行最近失败的测试"(并且没有改变其他任何东西)时,我反而得到了以下内容:

NUnit error running tests in 'C:\BuildAgent\work\a58fc6cd9bf63032\JsonApi.Owin.Tests\obj\Release\JsonApi.Owin.Tests.dll' assembly
Loading assembly is compiled for v4.0.30319, MSIL
NUnit runner runtime is v4.0.30319, x86
Run Code Online (Sandbox Code Playgroud)

请注意,在一种情况下,跑步者是x86,而在另一种情况下,跑步者是x64.在这两种情况下,它们都是否成功加载为MSIL编译的程序集.

我假设我的构建设置已经关闭,但是什么?

teamcity nunit assembly-loading

6
推荐指数
1
解决办法
1852
查看次数

如何调试程序集加载 - ConfigurationErrorsException

我有一个在本地运行良好的应用程序,但在部署时我看到错误:

Exception information: 
    Exception type: ConfigurationErrorsException 
    Exception message: Could not load file or assembly 'FluentMigrator.Runner' or one of its dependencies. An attempt was made to load a program with an incorrect format.
    at System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective)
    at System.Web.Configuration.CompilationSection.LoadAllAssembliesFromAppDomainBinDirectory()
    at System.Web.Configuration.AssemblyInfo.get_AssemblyInternal()
    at System.Web.Compilation.BuildManager.GetReferencedAssemblies(CompilationSection compConfig)
    at System.Web.Compilation.BuildManager.CallPreStartInitMethods()
    at System.Web.Hosting.HostingEnvironment.Initialize(ApplicationManager appManager, IApplicationHost appHost, IConfigMapPathFactory configMapPathFactory, HostingEnvironmentParameters hostingParameters, PolicyLevel policyLevel, Exception appDomainCreationException)
Run Code Online (Sandbox Code Playgroud)

我已经尝试通过程序集绑定日志查看器查看程序集绑定日志,但即使打开它我没有获得比上面的堆栈跟踪更多的信息,日志似乎保持为空.它抱怨的组件存在,并且它的表面上存在所有依赖组件.我还可以做些什么来调试我服务器上的错误?

.net debugging assembly-loading

5
推荐指数
1
解决办法
1477
查看次数

在LoadFrom加载上下文中WPF资源加载失败

我有一个WPF程序集,我在本地代码的互操作场景中使用LoadFrom加载上下文,如下所示:

AppDomain.CreateInstanceFrom("c:\mydlls\mywpfstuff.dll", "myclass")
Run Code Online (Sandbox Code Playgroud)

请注意,mydlls与可执行文件所在的文件夹不同.这适用于我也加载的常规非ui .NET dll,但是当我尝试这样做时,我得到一个错误.我附加了AppDomain.CurrentDomain.AssemblyResolve事件处理程序并获取无法加载的事件.ResolveEventArgs中的Name是"mywpfstuff.resources",RequestingAssembly是空的.我没有名为"mywpfstuff.resources"的文件,也无法弄清楚如何解决这个问题.

触发错误的代码行是InitializeComponent(); 在我的主用户控件构造函数中调用.

在我看来,内部XAML(BAML?)机制试图加载一些资源,但使用标准的Load上下文而不是LoadFrom上下文.

有没有办法解决这个问题,最好是让WPF使用LoadFrom上下文,或者如果不可能如何手动解决程序集?

c# wpf xaml assembly-loading

5
推荐指数
1
解决办法
424
查看次数

来自DocumentFormat.OpenXml的程序集加载错误

使用Microsoft ClosedXmlDocumentFormat.OpenXmlNuGet实用程序包时出现错误。更新了这些NuGet程序包(从2.7.2版到2.8.1版)后,现在出现以下异常:

异常System.IO.FileLoadException:无法加载文件或程序集'DocumentFormat.OpenXml,版本= 2.7.2.0,区域性=中性,PublicKeyToken = 8fb06cb64d019a17'或其依赖项之一。找到的程序集的清单定义与程序集引用不匹配。(来自HRESULT的异常:0x80131040)

当我查看解决方案项目中的相关程序集时,它引用了正确的版本(2.8.1)。查看NuGet程序包管理器,没有对旧版2.7.2的引用(4个项目对新版2.8.1的引用)。在任何有关版本2.7.2的项目引用中,我都找不到任何提及。正在执行的应用程序文件夹中的文件也是正确的文件(2.8.1)(通过查看项目属性窗口的详细信息选项卡)。在我的解决方案中的其他地方,对旧版本号的引用(显然是导致此异常的地方)可以找到吗?

附加信息:我已经grep在执行此操作的应用程序目录(包括子目录)中的所有文件(包括二进制文件)上执行了操作,并且2.7.2找不到字符串。

另外,当我在Visual Studio中调试此程序时,它不会抛出异常。但是,当我在部署的构建文件夹中运行它时,我得到FileLoadException。

.net assembly-loading closedxml

5
推荐指数
1
解决办法
2259
查看次数

如何在 .NET Core 中卸载程序集/使其可收集?

如何在 .NET Core 中卸载程序集?

注意:
.NET Core 不支持 AppDomain。

背景:
我必须动态评估用户生成的 VisualBasic 表达式。
为此,我使用 Roslyn 动态编译表达式。
我从 Roslyn 编译器生成的字节数组加载生成的程序集。
然后我创建一个实现抽象类的实例(因此我不必使用反射)。然后我调用抽象类的方法EvaluateExpression。
完成此操作后,我想卸载已加载的程序集(否则,我将享受内存泄漏的乐趣)。
因此,我在计算表达式后立即卸载程序集:

Parameters.AbstractEvaluator x = RoslynExpressionEvaluator.CreateEvaluator(expression, report.Code);
object value = x.EvaluateExpression();
x.LoadContext.Unload();
Run Code Online (Sandbox Code Playgroud)

(loadContext在生成时保存在抽象类中)

到目前为止一切正常,但是在x.LoadContext.Unload();,我得到

System.InvalidOperationException:“无法卸载不可收集的 AssemblyLoadContext。”

有可能解决这个问题吗?
如何使组件成为收藏品?
另外,我注意到我可以加载具有相同类名的程序集(如您所见,代码中没有命名空间)
这在多线程环境(又名网络)中表现如何?
我可以无限地加载动态生成的类的不同版本,直到机器用完 RAM 而没有出现故障吗?
或者为什么当加载同一个类两次时这会起作用?

using Microsoft.CodeAnalysis.Operations;

namespace ReportTester
{


    public static class RoslynExpressionEvaluator
    {
        // a utility method that creates Roslyn compilation
        // for the passed code. 
        // The compilation references the collection of 
        // passed "references" arguments …
Run Code Online (Sandbox Code Playgroud)

c# code-generation expression-evaluation assembly-loading roslyn

5
推荐指数
1
解决办法
4961
查看次数

将InMemory编译的程序集加载到当前域中

我正在使用CSharpCodeProvider编译程序集,我将CompileParameters GenerateInMemory属性设置为,true因为我不想创建物理文件.

在编译之后,我可以采取CompilerResults并执行以下操作: -

 object x = cr.CompiledAssembly.CreateInstance("MyGeneratedClass");
 Console.WriteLine(x);
Run Code Online (Sandbox Code Playgroud)

我得到了预期的输出,CreateInstance已经有效了.

但是,我需要能够在AppDomain没有组装知识的情况下访问当前类型.我需要做这样的事情: -

 Type t = Type.GetType("MyGeneratedClass");
 object x = Activator.CreateInstance(t);
Run Code Online (Sandbox Code Playgroud)

问题在于此代码t最终为空.现在我怀疑虽然程序集已编译但未加载.我似乎无法找到将此程序集加载到域中,以便可以解析其类型名称.

任何人都可以开导我吗?

c# compiler-construction assemblies assembly-loading

4
推荐指数
2
解决办法
2830
查看次数

创建或寻找 fuslogvw.exe 的替代品,又名 Fusion Assembly Binding Log Viewer

程序集绑定日志查看器有很多错误(例如,它通常不会清空日志)并且功能相当缺乏(搜索、排序、过滤几乎都可用)。

所以我想知道是否

  • 存在现有的替代方案
  • 在全球范围内挂钩 assemblyresolve 事件是可能的,所以我可以自己做这件事
  • 微软已经在某处发布了源代码,我们可以分叉它

如果没有第二个选项,我知道您可以相对简单地创建 CLR Host 实现(尽管并非平凡),但如果您需要的只是比现有 Fusion 日志查看器更细粒度的控制,那么它似乎有点过大了。

请注意,我已经看到了这个答案,但这似乎并没有回答这个问题。


回复一些评论:

我知道程序集重定向、事件AssemblyResolveAssemblyLoad事件,但第一个只能用作最后的手段(探测链中的最后一个),第二个只会在加载程序集后触发。两者都不能用于除您自己的进程之外的其他进程,也不能显示整个探测过程。

我注意到,使用 RyuJIT 时,由于编译和加载编译后的 IL 的方式不同,一些绑定看起来略有不同,顺序也不同。虽然我已经能够研究和解决具有约束力的问题,但我非常不喜欢fuslogvw.exe它是一种耗时的(尽管是一种有用的)工具。因此,我开始寻找更好的工具来监控探测过程(但毫无结果)。

.net c# clr fusion assembly-loading

4
推荐指数
1
解决办法
711
查看次数

AppDomain.Load()的有趣错误

我试图找到一种在运行时编译程序集并加载它们的方法.基本意图是将它们存储在不在光盘上的数据库中.所以我写了一些代码,但看到了一个有趣的情况.这是我的代码:

//SumLib
namespace SumLib
{
    public class SumClass
    {
        public static int Sum(int a, int b)
        {
            return a + b;
        }
    }
}


// Console app
class Program
{

    public static void AssemblyLoadEvent(object sender, AssemblyLoadEventArgs args)
    {

        object[] tt = { 3, 6 };
        Type typ = args.LoadedAssembly.GetType("SumLib.SumClass");
        MethodInfo minfo = typ.GetMethod("Sum");
        int x = (int)minfo.Invoke(null, tt);
        Console.WriteLine(x);
    }

    static void Main(string[] args)
    {

        AppDomain apd = AppDomain.CreateDomain("newdomain", AppDomain.CurrentDomain.Evidence, AppDomain.CurrentDomain.SetupInformation);
        apd.AssemblyLoad += new AssemblyLoadEventHandler(AssemblyLoadEvent);

        FileStream fs = new FileStream("Sumlib.dll", …
Run Code Online (Sandbox Code Playgroud)

.net c# load appdomain assembly-loading

3
推荐指数
1
解决办法
1696
查看次数

AssemblyLoadContext 是否隔离静态变量?

公告告诉我们:

程序集卸载能力是 AssemblyLoadContext 的一项新功能。从 API 的角度来看,这项新功能在很大程度上是透明的,仅通过几个新 API 公开。它允许卸载加载器上下文,释放实例化类型、静态字段和程序集本身的所有内存。应用程序应该能够通过这种机制永远加载和卸载程序集而不会出现内存泄漏。

此外,这个设计说明提到了“静态”。

我试过这个简单的测试:

static void Main()
{
    Proxy.X = 15;
    var alc = new AssemblyLoadContext("MyTest", true);
    var asm = alc.LoadFromAssemblyName(typeof(Program).Assembly.GetName());
    var proxy = (Proxy)asm.CreateInstance(typeof(Proxy).FullName);
    Console.WriteLine(proxy.Increment());
}

class Proxy
{
    public static int X;
    public int Increment() => ++X;
}
Run Code Online (Sandbox Code Playgroud)

它输出“16”,这意味着隔离不起作用。

我的目标是对可以抛出异常的类静态成员进行单元测试。通常的测试可以通过触发类型初始值设定项来影响彼此的行为,因此我需要以尽可能便宜的方式隔离它们。测试应在 .NET Core 3.0 上运行。

这样做是否正确,并且可以提供AssemblyLoadContext帮助?

c# static assembly-loading .net-assembly .net-core-3.0

3
推荐指数
1
解决办法
572
查看次数

IKVM.Reflection在运行时为Windows应用商店应用程序发出IL?

我看到一个帖子IKVM.Reflection由Marc Gravell,这里是我的发现在IKVM 用户指南:

使用IKVM.NET有两种主要方式:

  • 动态:在此模式下,Java类和jar直接用于在.NET运行时上执行Java应用程序.Java字节码即时转换为CIL,无需进一步的步骤.此模式支持完整的Java类加载器模型.
  • 静态地说:......

我想用它在WinRT应用程序中发出和执行IL.有什么根本问题可以解决这个问题吗?像Microsoft的政策,或阻止从IKVM执行(可能修补的)Reflection&IL Emitting代码的技术限制?

如果这不可能,是否有任何选项在运行时加载程序集(假设我在外部服务器上发出它们并从那里下载到本地应用程序文件夹)?

il ikvm reflection.emit assembly-loading windows-runtime

2
推荐指数
1
解决办法
499
查看次数