40

クライアントのシステム内の環境と地域にまたがってデプロイされた .NET アプリケーションに関する情報を報告するツールを作成しています。

これらのアセンブリのアセンブリ属性の値を読みたいと思います。

これは を使用して実現できますがAssembly.ReflectionOnlyLoad、この方法でもアセンブリがロードされたままになります。ここでの問題は、異なるパスから同じ名前を持つ 2 つのアセンブリを読み込むことができないため、異なるシステムにデプロイされた同じアプリケーションを当然比較することができないことです。

この時点で、ソリューションには一時的なAppDomains の使用が含まれると想定しています。

アセンブリを別のAppDomainにロードし、そこから属性を読み取ってからアンロードする方法を誰かが詳しく説明できますかAppDomain?

これは、URL アドレスにあるアセンブリだけでなく、ファイル システム上のアセンブリにも機能する必要があります。

4

5 に答える 5

52

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
}
于 2008-10-22T11:30:39.283 に答える
10

アセンブリのアンロードについては実際にはそうではありませんが、ファイルのバージョン番号を取得しようとしているだけの場合は、を使用できます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; }
于 2009-04-09T09:19:00.510 に答える
9

新しい 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;
    }
}
于 2016-06-22T13:48:15.180 に答える
4

COM であり、ある種のラッパーを使用して .NET アプリケーションから簡単に使用できるUnmanaged Metadata APIの使用を試みることができます。

于 2008-10-22T11:33:20.777 に答える
2

アプリケーション ドメインを使用する必要があります。アセンブリをアンロードする方法は他にありません。基本的に、次のようなコードを使用する必要があります。

AppDomain tempDomain = AppDomain.CreateDomain("一時ドメイン");
tempDomain.Load(アセンブリ);
AppDomain.Unload(tempDomain);

于 2008-10-22T11:36:24.093 に答える