Domanda Impostare il percorso personalizzato alle DLL di riferimento?


Ho un progetto C # (chiamalo MainProj) che fa riferimento a diversi altri progetti DLL. Aggiungendo questi progetti a MainProjI riferimenti, li costruirà e copierà le loro DLL risultanti nella directory di lavoro di MainProj.

Quello che mi piacerebbe fare è che queste DLL di riferimento si trovino in una sottodirectory di MainProjLa directory di lavoro, cioè MainProj / bin / DLLs, piuttosto che la directory di lavoro stessa.

Non sono un programmatore C # molto esperto, ma provengo dal mondo C ++, sto assumendo che un approccio sarebbe quello di rimuovere i riferimenti al progetto e caricare esplicitamente le DLL richieste per percorso e nome file (cioè in C ++, LoadLibrary). Quello che preferirei fare comunque, se c'è un modo, sarebbe quello di impostare una sorta di "percorso binario di riferimento", in modo che vengano tutti copiati automaticamente in questa sottodir quando costruisco (e quindi ci si può riferire da lì senza ho bisogno di caricare esplicitamente ciascuno). E 'possibile una cosa del genere?

In caso contrario, qual è il metodo preferito in C # per realizzare ciò che cerco (ad esempio qualcosa con Assembly.Load / Assembly.LoadFile / Assembly.LoadFrom? Qualcosa dentro AppDomain forse, o System.Environment?)


44
2017-12-12 05:55


origine


risposte:


A partire dal questa pagina (non verificato da me):

Da qualche parte nell'inizializzazione del tuo programma (prima di accedere a qualsiasi classe da un assembly di riferimento) fai questo:

AppDomain.CurrentDomain.AppendPrivatePath(@"bin\DLLs");

Modificare:  Questo articolo dice AppendPrivatePath è considerato obsoleto, ma offre anche una soluzione alternativa.

Modifica 2: Sembra che il modo più semplice e più kosher per farlo sia nel file app.config (vedi Qui):

<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <probing privatePath="bin\DLLs" />
    </assemblyBinding>
  </runtime>
</configuration>

73
2017-12-12 06:04



A partire dal Tomek rispondere a: Caricamento delle DLL dal percorso specificato in SetdllDirectory in c #

var dllDirectory = @"C:/some/path";
Environment.SetEnvironmentVariable("PATH", Environment.GetEnvironmentVariable("PATH") + ";" + dllDirectory)

Funziona perfettamente per me!


17
2018-03-21 12:16



Ecco un altro modo per procedere senza usare obsoleto AppendPrivatePath. Cattura un tipo di evento "dll associata non trovata"(quindi verrà chiamato solo se la DLL non viene trovata nella directory predefinita).

Funziona per me (.NET 3.5, non testato altre versioni)

/// <summary>
/// Here is the list of authorized assemblies (DLL files)
/// You HAVE TO specify each of them and call InitializeAssembly()
/// </summary>
private static string[] LOAD_ASSEMBLIES = { "FooBar.dll", "BarFooFoz.dll" };

/// <summary>
/// Call this method at the beginning of the program
/// </summary>
public static void initializeAssembly()
{
    AppDomain.CurrentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs args)
    {
        string assemblyFile = (args.Name.Contains(','))
            ? args.Name.Substring(0, args.Name.IndexOf(','))
            : args.Name;

        assemblyFile += ".dll";

        // Forbid non handled dll's
        if (!LOAD_ASSEMBLIES.Contains(assemblyFile))
        {
            return null;
        }

        string absoluteFolder = new FileInfo((new System.Uri(Assembly.GetExecutingAssembly().CodeBase)).LocalPath).Directory.FullName;
        string targetPath = Path.Combine(absoluteFolder, assemblyFile);

        try
        {
            return Assembly.LoadFile(targetPath);
        }
        catch (Exception)
        {
            return null;
        }
    };
}

PS: non sono riuscito a usarlo AppDomainSetup.PrivateBinPathè troppo laborioso


6
2018-05-13 12:35