Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Inno安装程序-具有依赖项的外部.NET DLL_C#_.net_Dll_Inno Setup_Pascalscript - Fatal编程技术网

C# Inno安装程序-具有依赖项的外部.NET DLL

C# Inno安装程序-具有依赖项的外部.NET DLL,c#,.net,dll,inno-setup,pascalscript,C#,.net,Dll,Inno Setup,Pascalscript,我试图在安装期间在Inno安装脚本中使用自定义DLL。我编写了一个非常简单的函数,基本上使用MySQL.NET连接器检查MySQL数据库的连接字符串(目标服务器上没有MySQL客户端)。此导出函数的代码为: 公共类DbChecker { [DllExport(“CheckConnexion”,CallingConvention.StdCall)] 公共静态int-CheckConnexion([Marshallas(UnmanagedType.LPStr)]字符串连接字符串) { 成功; 尝试

我试图在安装期间在Inno安装脚本中使用自定义DLL。我编写了一个非常简单的函数,基本上使用MySQL.NET连接器检查MySQL数据库的连接字符串(目标服务器上没有MySQL客户端)。此导出函数的代码为:

公共类DbChecker
{
[DllExport(“CheckConnexion”,CallingConvention.StdCall)]
公共静态int-CheckConnexion([Marshallas(UnmanagedType.LPStr)]字符串连接字符串)
{
成功;
尝试
{
MySqlConnection=newmysqlconnection(connexionString);
connection.Open();
connection.Close();
成功=0;
}
捕获(例外)
{
成功=1;
}
回归成功;
}
}
该函数在Inno设置中以这种方式导入:

[文件]
来源:“..\..\MyDll\bin\x86\Release\*”;标志:dontcopy;

[代码]
函数CheckConnexion(connexionString:AnsiString):整数;
外部的CheckConnexion@files:MyDll.dll,MySql.Data.dll stdcall setuponly loadwithalteredsearchpath'`
问题是安装程序在运行时引发异常:

运行时错误(53:207):

外部异常E0434352

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

运行时,
MyDll.dll
MySql.Data.dll
都被正确地提取到
{tmp}
目录中

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

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

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

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


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

可能有更好的方法,但这样就可以了

实现一个初始化函数(
Init
此处),该函数设置在主(执行)程序集路径中查找程序集的处理程序:

[DllExport(“Init”,CallingConvention.StdCall)]
公共静态void Init()
{
AppDomain currentDomain=AppDomain.currentDomain;
currentDomain.AssemblyResolve+=新的ResolveEventHandler(MyResolveEventHandler);
}
私有静态程序集MyResolveEventHandler(对象发送方、ResolveEventArgs args args)
{
字符串位置=Assembly.getExecutionGassembly().location;
AssemblyName=新的AssemblyName(args.name);
字符串path=path.Combine(path.GetDirectoryName(location),name.name+“.dll”);
if(File.Exists(path))
{
返回Assembly.LoadFrom(路径);
}
返回null;
}
将其导入Inno安装程序:

procedure Init();外部的Init@files:MyDll.dll stdcall setuponly';
并在调用需要依赖项的函数之前调用它(
CheckConnexion


另一种解决方案可能是:



顺便说一句,不需要使用
loadwithalteredsearchpath
标志。它对.NET程序集imo没有影响。它们是本机DLL依赖项所必需的:。

我发现了一些其他东西,可能对任何在本页上遇到障碍的人都有帮助

在我的场景中,我使用DllExport从InnoSetup调用了几个C#方法。在其中一个方法中,我调用另一个方法。这导致Inno抛出“外部异常E0434352”

如果我将代码移动到InnoSetup未调用的方法,则一切正常

所以

…导致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引起的,所以我将放弃直接的嘲笑,并将我失去的早晨归咎于整个社会。(或者说我是这方面的新手。)

这是[DllExport]的致命弱点。使用try/catch是不够的,这样的代码也很可能失败,因为抖动检测到了非常基本的问题。例如,FileNotFoundException。在代码执行try/catch之前运行多少次都无济于事。考虑使用调试器超前,选择项目中的安装程序>属性>调试窗口。
[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
}