Jak załadować a.NET montaż do operacji odbicia, a następnie rozładowanie?

Piszę narzędzie do raportowania informacji o aplikacjach. NET wdrożonych w różnych środowiskach i regionach w systemach mojego klienta.

Chciałbym przeczytać wartości atrybutów assembly w tych Assembly.

Można to osiągnąć za pomocą Assembly.ReflectionOnlyLoad, jednak nawet takie podejście utrzymuje załadowany zespół. Problem polega na tym, że nie mogę załadować dwóch zestawów o tej samej nazwie z różnych ścieżek, więc oczywiście nie mogę porównać tej samej aplikacji wdrożonej w różnych systemy.

W tym momencie zakładam, że rozwiązanie będzie polegało na użyciu tymczasowychAppDomains.

Czy ktos moze sprecyzowac jak wgrac montaz do innego AppDomain, odczytac z niego atrybuty a nastepnie wyladowac AppDomain?

To musi działać dla zestawów w systemie plików, jak również tych pod adresami URL.

Author: Tshepang, 2008-10-22

5 answers

Z dokumentacji MSDN systemu.Odbicie.Montaż.ReflectionOnlyLoad (String) :

Kontekst tylko refleksji nie jest różni się od innych kontekstów. Zespoły, które są ładowane do kontekst może być rozładowany tylko przez rozładowanie domeny aplikacji.

Obawiam się więc, że jedynym sposobem rozładowania zestawu jest rozładowanie domeny aplikacji. Aby utworzyć nową AppDomain i załadować do niej zespoły:

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

private void LoaderCallback()
{
    Assembly.ReflectionOnlyLoad("YourAssembly");
    // Do your stuff here
}
 48
Author: Tamas Czinege,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-22 11:38:32

Chociaż nie chodzi o rozładowywanie zestawów, jeśli po prostu próbujesz uzyskać numer wersji pliku, możesz użyć System.Diagnostics.FileVersionInfo.

var info = FileVersionInfo.GetVersionInfo(path);

FileVersionInfo ma następujące właściwości:

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; }
 9
Author: Drew Noakes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-09 09:19:00

Możesz spróbować użyć Unmanaged metadata API , który jest COM i może być łatwo używany z aplikacji. Net z jakimś opakowaniem.

 4
Author: Ilya Ryzhenkov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-22 11:33:20

Musisz użyć domen aplikacji, nie ma innego sposobu na rozładowanie zestawu. Zasadniczo musisz użyć kodu w ten sposób:


AppDomain tempDomain = AppDomain.CreateDomain("Temp Domain");
tempDomain.Load(assembly);
AppDomain.Unload(tempDomain);

 3
Author: Albert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-22 11:36:24

Możesz utworzyć instancję w Nowej AppDomain i wykonać kod w tej instancji.

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);

Tutaj jest 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;
    }
}
 2
Author: Artiom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-22 13:48:15