我们的本地化团队正在尝试使用LocBaml (.NET框架版本,4.6.1)来本地化一些资源。他们不断收到“找不到文件或程序集...”的错误。所以,我查看了一下,发现x.resources.dll文件必须与x.dll位于相同的目录中。("x“只是指某个名字)。我试过了,还是会犯同样的错误。然后,我构建了一个调试版本,并下载了.NET源代码。原来在.NET内部发生了一些异常,如果我可以总结一下,它在尝试执行Assembly.Load("x")时失败了。所以我写了一个程序试图复制这种情况...
using System;
using System.Reflection;
using System.Linq;
namespace Nothing
{
class Loader
{
public static void Main(string[] args)
{
try
{
if (args.Count() == 1)
{
Assembly asm = Assembly.Load(args[0]);
Console.WriteLine($"Name of asembly: {asm.FullName}");
}
else
{
Console.WriteLine("Need to specify filename");
}
}
catch (Exception x)
{
Console.WriteLine("Exception: {0}", x);
}
}
}
}该文件被命名为AsmLoader.cs并编译为AsmLoader.exe。
在x.dll所在的目录中,我输入了\path\to\AsmLoader.exe x.dll和\path\to\AsmLoader.exe x。同样的错误,“找不到文件或程序集...”
查看了异常的堆栈跟踪,发现"codebase“是堆栈上某个函数的参数。考虑了一下,并将AsmLoader.exe复制到与x.dll相同的目录中。
已向.\AsmLoader.exe x.dll发送与try..still相同的错误。记住异常的参数只是"x“。已尝试.\AsmLoader.exe x....答对了。起作用了。对于grins,将LocBaml.exe和它的.config文件复制到同一目录,并尝试.\LocBaml x.resources.dll ...丁丁丁...成功。终于来了。
因此,现在,我将告诉本地化团队将LocBaml复制到与文件相同的目录中,一切都应该很好。
然而,我不禁觉得这可以通过代码来解决。如何对示例中的代码进行更改,使AsmLoader.exe不必与要加载的DLL位于同一目录中?我甚至更改了path环境变量,以确保AsmLoader.exe和两个x.dll目录都在path中。那不管用。
那么我需要做些什么才能让它在我的基本program...and中工作,然后也许我可以对LocBaml做同样的事情...?
发布于 2020-05-15 23:34:55
好吧,我想出了一个解决方案,将AssemblyResolve事件处理程序添加到当前应用程序域中。解决了这个简单的例子和我重建的LocBaml...
在main中,添加:
AppDomain.CurrentDomain.AssemblyResolve += LoadFromCurrentDirectory;像这样实现LoadFromCurrentDirectly:
static Assembly LoadFromCurrentDirectory(object sender, ResolveEventArgs args)
{
string name = args.Name;
bool bCheckVersion = false;
int idx = name.IndexOf(',');
if (idx != -1)
{
name = name.Substring(0, idx);
bCheckVersion = true;
}
string sCurrentDir = Directory.GetCurrentDirectory();
if (!name.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) && !name.EndsWith(".exe"))
{
string[] exts = { ".dll", ".exe" };
foreach( string ext in exts)
{
string tryPath = Path.Combine(sCurrentDir, name + ext);
if (File.Exists(tryPath))
{
name = name += ext;
break;
}
}
}
string path = Path.Combine(sCurrentDir, name);
if (!string.IsNullOrEmpty(path) && File.Exists(path))
{
Assembly assembly = Assembly.LoadFrom(path);
if (assembly != null & bCheckVersion)
{
if (assembly.FullName != args.Name)
return null;
}
return assembly;
}
else
{
var reqAsm = args.RequestingAssembly;
if (reqAsm != null)
{
string requestingName = reqAsm.GetName().FullName;
Console.WriteLine($"Could not resolve {name}, {path}, requested by {requestingName}");
}
else
{
Console.WriteLine($"Could not resolve {args.Name}, {path}");
}
}
return null;
}我确信它可以进行优化,添加一个全局目录列表,或者在搜索要加载的文件时使用路径。然而,对于我们的用例来说,工作得很好。当我将它添加到我们的LocBaml代码中时,它解决了us...also的加载问题,而不需要将en\x.resources.dll文件复制到我们的输出目录中。只要我们从输出目录运行程序,LocBaml就会完成解析。
https://stackoverflow.com/questions/61806978
复制相似问题