我正在尝试在安装期间在Inno Setup脚本中使用自定义DLL。我写了一个非常简单的函数,它基本上使用MySQL .NET连接器检查MySQL数据库的连接字符串(目标服务器上没有MySQL客户端)。此导出函数的代码是:
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 'CheckConnexion@files:MyDll.dll,MySql.Data.dll stdcall setuponly loadwithalteredsearchpath';`
问题是安装程序在运行时抛出异常:
运行时错误(53:207):
外部异常E0434352。
我认为我必须使用files
前缀,因为在将文件复制到NextButtonClick
目录之前,会在{app}
事件处理程序中调用该函数。
MyDll.dll
和MySql.Data.dll
都在运行时正确提取到{tmp}
目录。
我尝试使用和不使用loadwithalteredsearchpath
标志并使用相同的结果。
我发现此错误代码是一般的.NET运行时错误代码。
如果我使用MySql.Data
移除部件,它的效果非常好(除了它什么都不做......)
正如其他线程所建议的那样,我一直在尝试使用EventLog
和UnhandledException
在我的.NET代码中记录错误,但无论如何我都有相同的异常(并且没有创建日志源),即使没有MySQL部分。我在计算机上检查了EventLog权限。
似乎只要我使用“基本”C#代码(每当我尝试加载另一个DLL)时,就会抛出异常。
答案 0 :(得分:5)
可能有更好的方法,但这样做。
实现一个初始化函数(此处为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设置:
procedure Init(); external 'Init@files:MyDll.dll stdcall setuponly';
在调用需要依赖项的函数(CheckConnexion
)之前调用它。
另一种解决方案可能是这样的:
Embedding DLLs in a compiled executable
顺便说一下,不需要loadwithalteredsearchpath
标志。它对.NET程序集imo没有影响。
答案 1 :(得分:0)
我发现了其他可能对绊倒此页面的人有用的东西。
在我的场景中,我有几种C#方法,可以使用DllExport从InnoSetup调用。在其中一种方法中,我称另一种方法。这导致Inno抛出“外部异常E0434352”。
如果我将代码移至InnoSetup未调用的方法,则一切正常。
所以...
[DllExport("Fu", CallingConvention = CallingConvention.StdCall)]
public static int Fu()
{
// Stuff
}
[DllExport("Bar", CallingConvention = CallingConvention.StdCall)]
public static int Bar()
{
Fu();
}
...导致InnoSetup哭泣,但是:
[DllExport("Fu", CallingConvention = CallingConvention.StdCall)]
public static int Fu()
{
LocalFu();
}
private static int LocalFu()
{
// Stuff
}
[DllExport("Bar", CallingConvention = CallingConvention.StdCall)]
public static int Bar()
{
// Stuff
LocalFu();
// Other stuff
}
...很好。
我不知道这是由Inno还是DllExport引起的,所以对于我迷失的早晨,我将放弃直接嘲笑和整个社会的责任。 (或者我本人是这个东西的新手。)