Inno Setup - 具有依赖项的外部.NET DLL

问题描述 投票:3回答:2

我想在安装过程中在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.dllMySql.Data.dll都在运行时正确提取到{tmp}目录。

无论有没有loadwithalteredsearchpath旗帜我都尝试过相同的结果。

我发现这个错误代码是一个通用的.NET运行时错误代码。

如果我使用MySql.Data删除部件,它的工作完全正常(除了它什么也没做......)

正如其他线程所建议的那样,我一直在尝试使用EventLogUnhandledException在我的.NET代码中记录错误,但无论是什么(并且没有创建日志源),我都有相同的异常,即使没有MySQL部分也是如此。我检查了计算机上的EventLog权限。

似乎只要我使用“基本”C#代码(每当我尝试加载另一个DLL)时,抛出异常。

c# .net dll inno-setup pascalscript
2个回答
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
投票

我找到了其他可能对任何绊到这个页面的人有帮助的东西。

在我的场景中,我有几个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造成的,所以我会放弃直接的嘲笑,并把我整个社会归咎于失去的早晨。 (或者我自己是这个东西的新手。)

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.