Inno安装程序 - 依赖关系的外部.NET DLL
我想在安装期间在Inno安装脚本中使用自定义DLL。我写了一个非常简单的函数,它基本上使用MySQL .NET连接器检查MySQL数据库的连接字符串(目标服务器上没有MySQL客户端)。这个导出函数的代码是:Inno安装程序 - 依赖关系的外部.NET DLL
public class DbChecker
{
[DllExport("CheckConnexion", CallingConvention.StdCall)]
public static int CheckConnexion([MarshalAs(UnmanagedType.LPStr)] string connexionString)
{
int success;
try
{
MySqlConnection connection = new MySqlConnection(connexionString);
connection.Open();
connection.Close();
success = 0;
}
catch (Exception)
{
success = 1;
}
return success;
}
}
功能导入这样的Inno Setup的:
[Files]
Source: "..\..\MyDll\bin\x86\Release\*"; Flags: dontcopy;
和
[Code]
function CheckConnexion(connexionString: AnsiString): Integer;
external '[email protected]:MyDll.dll,MySql.Data.dll stdcall setuponly loadwithalteredsearchpath';`
的问题是,设置抛出异常的运行时间:
运行时错误(at 53:207):
外部异常E0434352。
我想我必须使用files
前缀,因为函数被调用在NextButtonClick
事件处理程序,之前的文件复制到{app}
目录。
在运行时将MyDll.dll
和MySql.Data.dll
都正确提取到{tmp}
目录。
我试着用和不用loadwithalteredsearchpath
标志都有相同的结果。
我发现这个错误代码是一个通用的.NET运行时错误代码。
如果我删除使用MySql.Data
它工作完全正常(除了它什么也不做......)
诚如其他线程上我一直在试图将错误使用EventLog
我的.NET代码的一部分和UnhandledException
,但是无论什么(也没有创建日志源),我都有相同的异常,即使没有MySQL部分也是如此。我在我的电脑上检查了EventLog权限。
看来,只要我使用其他任何“基本”C#代码(每当我尝试加载另一个DLL)时,都会抛出异常。
有可能是一种更好的方式,但是这样做。
实现一个初始化函数(Init
这里),设置了AppDomain.AssemblyResolve
处理程序查找一个装配在主(执行)程序集的路径:
[DllExport("Init", CallingConvention.StdCall)]
public static void Init()
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);
}
private static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
{
string location = Assembly.GetExecutingAssembly().Location;
AssemblyName name = new AssemblyName(args.Name);
string path = Path.Combine(Path.GetDirectoryName(location), name.Name + ".dll");
if (File.Exists(path))
{
return Assembly.LoadFrom(path);
}
return null;
}
其导入到Inno Setup的:
procedure Init(); external '[email protected]:MyDll.dll stdcall setuponly';
在调用需要依赖项的函数之前调用它(CheckConnexion
)。
另一种解决方案可能是这样的:
Embedding DLLs in a compiled executable
顺便说一句,没有必要为loadwithalteredsearchpath
标志。它对.NET组件imo没有影响。
CheckConnexion在NextButtonClick事件处理程序中调用。 如果我没有使用'MySql.Data'的第二个函数,它正在工作。纯粹的参考似乎不是问题。 – tvarnier
使用'File.WriteAllLines',调用没有引用'MySql.Data'的函数,记录并正确返回。使用'MySql.Data'的人在没有记录任何东西的情况下仍然以相同的方式失败。 – tvarnier
由于引用,'MySql.Data' dll被复制到'MyDll'的bin目录中。整个目录导入到我的原始文章中描述的'[files]'部分。 我可以在运行时看到在Inno-Setup临时目录中提取的'MySql.Data.dll'和'MyDll.dll'。 – tvarnier