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

标签 c# .net dll inno-setup pascalscript

我试图在安装期间在 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';`

问题是设置在运行时抛出异常:

Runtime Error (at 53:207):

External exception E0434352.

我认为我必须使用 files 前缀,因为在将文件复制到 {app} 之前,该函数在 NextButtonClick 事件处理程序中被调用 目录。

MyDll.dllMySql.Data.dll 在运行时都被正确地提取到 {tmp} 目录。

我尝试了使用和不使用 loadwithalteredsearchpath 标志,结果相同。

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

如果我使用 MySql.Data 删除该部分,它工作得很好(除了它什么都不做...)

根据其他线程的建议,我一直在尝试使用 EventLogUnhandledException 在我的 .NET 代码中记录错误,但无论如何我都会遇到相同的异常(并且没有创建日志源),即使没有 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 'Init@files:MyDll.dll stdcall setuponly';

并在调用需要依赖的函数(CheckConnexion)之前调用它。


另一种解决方案可能是这样的:
Embedding DLLs in a compiled executable


顺便说一句,不需要 loadwithalteredsearchpath 标志。它对 .NET 程序集 imo 没有影响。 native DLL 依赖项需要它们:Loading DLL with dependencies in Inno Setup fails in uninstaller with "Cannot import DLL", but works in the installer .

关于c# - Inno Setup - 具有依赖项的外部 .NET DLL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45955312/

相关文章:

azure - 非托管 win32 dll 未加载到 IIS 8.5、Win Server 2012 R2、Azure 虚拟机上的 .net MVC 应用程序中

c# - 此正则表达式替换如何反转字符串?

c# - IIS认证中的 "realm"是什么,它和SSL证书参数有什么关系?

c# - 带有 RGiesecke.DllExport 的 C# DLL 中没有函数

.net - 在我执行完所有更新之前,我可以暂停重新绘制表单吗?

.net - ADFS 2.0 Web 应用程序注销

c++ - 如何将结构从 C++ 应用程序传递到 C++ Win32 DLL?

c# - 以编程方式添加 SSIS 连接 - Oracle Provider for OLE DB

c# - 多种属性合二为一?

c# - 鼠标自动化和与 Flash 应用程序交互时出现问题