当前位置:  开发笔记 > 编程语言 > 正文

如何为反射操作加载.NET程序集并随后卸载它?

如何解决《如何为反射操作加载.NET程序集并随后卸载它?》经验,为你挑选了3个好方法。

我正在编写一个工具来报告有关在我的客户端系统中的环境和区域部署的.NET应用程序的信息.

我想阅读这些程序集中的程序集属性的值.

这可以使用Assembly.ReflectionOnlyLoad,但是即使这种方法也可以保持装配.这里的问题是我无法从不同的路径加载两个具有相同名称的程序集,因此我无法比较在不同系统中部署的相同应用程序.

在这一点上,我假设解决方案将涉及使用临时AppDomains.

有人可以详细说明如何将程序集加载到另一个程序集中AppDomain,从中读取属性然后卸载AppDomain

这需要适用于文件系统上的程序集以及URL地址上的程序集.



1> Tamas Czineg..:

从System.Reflection.Assembly.ReflectionOnlyLoad(String)的MSDN文档:

仅反射上下文与其他上下文没有区别.只能通过卸载应用程序域来卸载加载到上下文中的程序集.

因此,我担心卸载程序集的唯一方法是卸载应用程序域.要创建新的AppDomain并将程序集加载到其中:

public void TempLoadAssembly()
{
    AppDomain tempDomain = AppDomain.CreateDomain("TemporaryAppDomain");
    tempDomain.DoCallBack(LoaderCallback);
    AppDomain.Unload(tempDomain);
}

private void LoaderCallback()
{
    Assembly.ReflectionOnlyLoad("YourAssembly");
    // Do your stuff here
}


AZ:否.AppDomain.DoCallback"xecutes由指定委托标识的另一个应用程序域中的代码"(MSDN).Assembly.ReflectionOnlyLoad的文档明确指出"程序集被加载到调用者应用程序域的仅反射上下文中"(同样,MSDN).这意味着程序集确实已加载到临时应用程序域.
我正在尝试做同样的事情,似乎LoaderCallback无法访问原始AppDomain中的任何内容.因此,域之间不能传递任何参数(或成员).如果您无法将所发现的信息返回到调用进程,这似乎有点无意义.

2> Drew Noakes..:

虽然不是真正关于卸载程序集,但如果您只是想获取可以使用的文件的版本号System.Diagnostics.FileVersionInfo.

var info = FileVersionInfo.GetVersionInfo(path);

FileVersionInfo 具有以下属性:

public string Comments { get; }
public string CompanyName { get; }
public int FileBuildPart { get; }
public string FileDescription { get; }
public int FileMajorPart { get; }
public int FileMinorPart { get; }
public string FileName { get; }
public int FilePrivatePart { get; }
public string FileVersion { get; }
public string InternalName { get; }
public bool IsDebug { get; }
public bool IsPatched { get; }
public bool IsPreRelease { get; }
public bool IsPrivateBuild { get; }
public bool IsSpecialBuild { get; }
public string Language { get; }
public string LegalCopyright { get; }
public string LegalTrademarks { get; }
public string OriginalFilename { get; }
public string PrivateBuild { get; }
public int ProductBuildPart { get; }
public int ProductMajorPart { get; }
public int ProductMinorPart { get; }
public string ProductName { get; }
public int ProductPrivatePart { get; }
public string ProductVersion { get; }
public string SpecialBuild { get; }



3> Artiom..:

您可以在新的AppDomain中创建一个实例,然后在该实例中执行代码。

var settings = new AppDomainSetup
{
    ApplicationBase = AppDomain.CurrentDomain.BaseDirectory,
};
var childDomain = AppDomain.CreateDomain(Guid.NewGuid().ToString(), null, settings);

 var handle = Activator.CreateInstance(childDomain,
            typeof(ReferenceLoader).Assembly.FullName,
            typeof(ReferenceLoader).FullName,
            false, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, null, CultureInfo.CurrentCulture, new object[0]);


var loader = (ReferenceLoader)handle.Unwrap();

//This operation is executed in the new AppDomain
var paths = loader.LoadReferences(assemblyPath);


AppDomain.Unload(childDomain);

这是ReferenceLoader

public class ReferenceLoader : MarshalByRefObject
{
    public string[] LoadReferences(string assemblyPath)
    {
        var assembly = Assembly.ReflectionOnlyLoadFrom(assemblyPath);
        var paths = assembly.GetReferencedAssemblies().Select(x => x.FullName).ToArray();
        return paths;
    }
}

推荐阅读
牛尾巴2010
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有