我有一个简单的可执行文件,我想使用dll。我已添加它作为参考。我创建了一个app.config文件,因为dll最终不会出现在可执行文件目录中。如果我从IDE执行我的程序,一切都很好,b / c dll在本地复制它,但只要我拉出我的可执行文件就崩溃了。我的融合日志意味着它无法找到指定的文件。
我的Main()方法:
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);
Assembly assembly = null;
String dllLocation = @"C:\BMS_ACTD\bin\DX\Tools\BmsReplayAnalysis.dll";
IToolsInterface myProgram = null; //from ToolsInterface.dll
try
{
assembly = Assembly.LoadFrom(dllLocation);
}
catch
{
}
foreach (Type myType in assembly.GetTypes())
{
if (myType.GetInterface(typeof(IToolsInterface).FullName) != null)
{
myProgram = (IToolsInterface)assembly.CreateInstance(myType.Namespace + "." + myType.Name, true);
myProgram.RunTool();
break;
}
}
这是我的配置文件:
<runtime>
<dependentAssembly>
<assemblyIdentity name="ToolsInterface" publicKeyToken="null" culture="neutral" />
<codeBase version="1.0.0.0" href="file://C:/BMS_ACTD/bin/DX/Globals/ToolsInterface.dll"/>
</dependentAssembly>
</runtime>
我不想担心做强命名。我只有1个版本的dll,这就是我所关心的。
这里是fusionlog的摘录:
The operation failed.
Bind result: hr = 0x80070002. The system cannot find the file specified.
Assembly manager loaded from: C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
Running under executable C:\Users\greenj\Desktop\BmsReplayLauncher.exe
--- A detailed error log follows.
=== Pre-bind state information ===
LOG: User = BMS-JMGREEN\greenj
LOG: DisplayName = ToolsInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
(Fully-specified)
LOG: Appbase = file:///C:/Users/greenj/Desktop/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = BmsReplayLauncher.exe
Calling assembly : BmsReplayLauncher, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Users\greenj\Desktop\BmsReplayLauncher.exe.Config
LOG: Using host configuration file:
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/Users/greenj/Desktop/ToolsInterface.DLL.
LOG: Attempting download of new URL file:///C:/Users/greenj/Desktop/ToolsInterface/ToolsInterface.DLL.
LOG: Attempting download of new URL file:///C:/Users/greenj/Desktop/ToolsInterface.EXE.
LOG: Attempting download of new URL file:///C:/Users/greenj/Desktop/ToolsInterface/ToolsInterface.EXE.
LOG: All probing URLs attempted and failed.
答案 0 :(得分:2)
如果您尝试从不在应用程序EXE位置的文件夹或子文件夹中的文件夹加载.net,那么事情总是变得棘手。我建议尝试两件事。首先,使用<probing>
属性指定查找自定义DLL的位置,请参阅此answer,而不是您执行此操作的方式。
其次,如果不起作用,请尝试使用AppDomain.AssemblyResolve event而不是使用配置文件。然后,您可以从任何地方加载程序集。
编辑:Jay Walker指出..NET 4及更高版本已更改AssemblyResolve,因此如果DLL不在自定义文件夹中,则返回null以保留默认行为。
以下是AssemblyResolve的一些示例代码:
Assembly currentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
if (args.Name == THE_DLL_I_WANT_TO_CUSTOM_LOAD)
{
// Load from our custom path
string finalPath = null;
try
{
finalPath = MyCustomPath + args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll";
return Assembly.LoadFrom(finalPath);
}
catch ()
{
}
}
// Not our custom, use the default loading
return null;
}
答案 1 :(得分:0)
引用<codebase>
的MSDN:
如果程序集具有强名称,则代码库设置可以位于本地Intranet或Internet上的任何位置。如果程序集是专用程序集,则代码库设置必须是相对于应用程序目录的路径。
您的程序集没有任何强名称,因此您无法通过指定完整路径来使用此指令。对您的程序集进行签名(使用Visual Studio需要三次单击)或使用AresAvatar建议的AssemblyResolve
。