我正在编写一个工具来报告有关在我的客户端系统中的环境和区域部署的.NET应用程序的信息.
我想阅读这些程序集中的程序集属性的值.
这可以使用Assembly.ReflectionOnlyLoad
,但是即使这种方法也可以保持装配.这里的问题是我无法从不同的路径加载两个具有相同名称的程序集,因此我无法比较在不同系统中部署的相同应用程序.
在这一点上,我假设解决方案将涉及使用临时AppDomain
s.
有人可以详细说明如何将程序集加载到另一个程序集中AppDomain
,从中读取属性然后卸载AppDomain
?
这需要适用于文件系统上的程序集以及URL地址上的程序集.
从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 }
虽然不是真正关于卸载程序集,但如果您只是想获取可以使用的文件的版本号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; }
您可以在新的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; } }