通过回调从Inno安装程序调用C#DLL
我有一个正在运行的Inno安装脚本,我使用它 这个DLL包装了我的一个过程,这样就可以将它传递给C#DLL 我不想使用这个DLL,我想直接调用导出的C#方法并将回调过程传递给它 我的问题是: 如何将Inno设置过程(通过回调从Inno安装程序调用C#DLL,c#,dll,callback,inno-setup,dllexport,C#,Dll,Callback,Inno Setup,Dllexport,我有一个正在运行的Inno安装脚本,我使用它 这个DLL包装了我的一个过程,这样就可以将它传递给C#DLL 我不想使用这个DLL,我想直接调用导出的C#方法并将回调过程传递给它 我的问题是: 如何将Inno设置过程(@mycallback)传递到我的C#DLL,以便将其用作我的委托/非托管函数指针 正如我所说,这段代码可以工作,但我希望使用尽可能少的外部DLL 这是我的密码: Inno设置脚本 类型 TTimerProc=过程(); TProgressCallback=过程(进度:整数);
@mycallback
)传递到我的C#DLL,以便将其用作我的委托
/非托管函数指针
正如我所说,这段代码可以工作,但我希望使用尽可能少的外部DLL
这是我的密码:
Inno设置脚本
类型
TTimerProc=过程();
TProgressCallback=过程(进度:整数);
函数WrapProgressProc(callback:TProgressCallback;paramcount:integer):长单词;
外部的wrapcallback@files:innocallback.dll stdcall';
函数测试(回调:longword):字符串;
外部的Test@files:ExposeTestLibrary.dll stdcall';
变量
endProgram:布尔型;
过程mycallback(进度:整数);
开始
MsgBox(IntToStr(进度),MB信息,MB_OK);
如果进度>15,则
开始
endProgram:=真;
结束
结束;
函数初始化设置:布尔;
变量
项目名称:长单词;
回调:长词;
味精:长词;
msg2:宽字符串;
开始
endProgram:=假;
progCallBack:=WrapProgressProc(@mycallback,1)//我们的proc有1个参数
测试(程序调用);
结果:=真;
结束;
这是我的C#代码
public class TestClass
{
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void ReportProgress(uint progress);
public static ReportProgress m_reportProgess;
static uint m_iProgress;
[DllExport("Test", CallingConvention = CallingConvention.StdCall)]
static int Test(ReportProgress rProg)
{
m_iProgress = 0;
m_reportProgess = rProg;
System.Timers.Timer pTimer = new System.Timers.Timer();
pTimer.Elapsed += aTimer_Elapsed;
pTimer.Interval = 1000;
pTimer.Enabled = true;
GC.KeepAlive(pTimer);
return 0;
}
static void aTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
m_iProgress++;
m_reportProgess(m_iProgress);
}
}
此答案在Inno Setup 6中不再有效。请参阅我的(@MartinPrikryl)答案以获取最新的解决方案。 无法停止使用包装InnoCallback库,因为您无法在Inno Setup中使用您选择的调用约定定义回调过程,也无法在C#库中使用
寄存器调用约定(Delphi编译器特有的约定)定义回调
由于这个限制,您必须使用一个外部库,它将来自Inno安装程序的回调方法包装到一个函数中,该函数具有您的库可以使用的调用约定(InnoCallback为此使用stdcall
)
因此,如果您使用支持Delphi的register
调用约定的语言编写库,那么您所要求的将是可能的。出于好奇,您可以在Delphi中编写,例如:
库MyLib;
类型
TMyCallback=对象的过程(IntParam:Integer;StrParam:WideString);
过程回调(回调:TMyCallback);stdcall;
开始
回调(123,‘你好!’);
结束;
出口
回调;
开始
结束。
然后在Inno设置中(无任何包装库):
[设置]
AppName=我的程序
AppVersion=1.5
DefaultDirName={pf}\My程序
[档案]
资料来源:“MyLib.dll”;标志:dontcopy
[代码]
类型
TMyCallback=过程(IntParam:Integer;StrParam:WideString);
过程回调(回调:TMyCallback);
外部的CallMeBack@files:mylib.dll stdcall';
过程MyCallback(IntParam:Integer;StrParam:WideString);
开始
MsgBox(格式('IntParam:%d;StrParam:%s',[IntParam,StrParam]),
MB信息,MB_OK);
结束;
程序初始化;
开始
CallMeBack(@MyCallback);
结束;
使用Inno Setup 6,内置的函数与InnoTools InnoCallback库中的WrapCallback
函数的作用相同
因此,您现在可以执行以下操作:
Test(CreateCallback(@mycallback));
我刚看到你拿到了inno安装金徽章。恭喜:)Inno安装程序6.0.3的更新:InnoCallback库完全停止工作,本机CreateCallback()现在是唯一的选项。