J'ai un projet C # (appelez-le MainProj
) qui référence plusieurs autres projets DLL. En ajoutant ces projets aux références de MainProj
, il les construira et copiez leurs DLL résultantes dans le répertoire de travail de MainProj.
Ce que j'aimerais faire, c'est que ces DLL référencées soient situées dans un sous-répertoire du répertoire de travail de MainProj
, c'est-à-dire MainProj/bin/DLL, plutôt que dans le répertoire de travail lui-même.
Je ne suis pas un programmeur C # très expérimenté, mais venant du monde C++, je suppose qu'une approche serait de supprimer les références du projet et de charger explicitement les DLL requises par chemin et nom de fichier (c'est-à-dire en C++, LoadLibrary
). Ce que je préférerais faire cependant, s'il y a un moyen, serait de définir une sorte de "chemin binaire de référence", afin qu'ils soient tous automatiquement copiés dans ce sous-répertoire lorsque je construis (puis référencés à partir de là sans me besoin de charger explicitement chacun). Une telle chose est possible?
Sinon, quelle est la méthode préférée en C # pour accomplir ce que je recherche (c'est-à-dire quelque chose avec Assembly.Load
/Assembly.LoadFile
/Assembly.LoadFrom
? Quelque chose dans AppDomain
peut-être, ou System.Environment
?)
De cette page (non testé par moi):
Quelque part dans l'initialisation de votre programme (avant d'accéder à des classes à partir d'un assembly référencé), procédez comme suit:
AppDomain.CurrentDomain.AppendPrivatePath(@"bin\DLLs");
Modifier: Cet article dit que AppendPrivatePath est considéré comme obsolète, mais donne également une solution de contournement.
Modifier 2: Il semble que la façon la plus simple et la plus casher de le faire soit dans le fichier app.config (voir ici ):
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-Microsoft-com:asm.v1">
<probing privatePath="bin\DLLs" />
</assemblyBinding>
</runtime>
</configuration>
De Tomek répondez à: Chargement des dll à partir du chemin spécifié dans SetdllDirectory en c #
var dllDirectory = @"C:/some/path";
Environment.SetEnvironmentVariable("PATH", Environment.GetEnvironmentVariable("PATH") + ";" + dllDirectory)
Cela fonctionne parfaitement pour moi!
Voici une autre façon de procéder sans utiliser AppendPrivatePath
obsolète. Il intercepte une sorte d'événement " DLL associée non trouvée " (il ne sera donc appelé que si la DLL n'est pas trouvée dans le répertoire par défaut).
Fonctionne pour moi (.NET 3.5, pas testé d'autres versions)
/// <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: je n'ai pas réussi à utiliser AppDomainSetup.PrivateBinPath
, c'est trop laborieux.