如何从Inno Setup脚本调用.NET DLL?
时间:2020-03-05 18:48:07 来源:igfitidea点击:
我想从Inno Setup脚本从.NET DLL(用C#编码)调用函数。
我有:
- 在项目属性中标记了"注册COM互操作"选项,
- 更改了AssemblyInfo.cs文件中的ComVisible设置,
- 将这些行添加到ISS脚本中:
[Files] Source: c:\temp\MyDLL.dll; Flags: dontcopy [Code] function MyFunction(): string; external 'MyFunction@files:MyDLL.dll stdcall setuponly';
但我仍然收到以下错误:
Runtime Error (at -1:0): Cannot Import dll:C:\DOCUME~1\foo\LOCALS~1\Temp\is-LRL3E.tmp\MyDLL.dll.
我究竟做错了什么?
解决方案
回答
我们正在尝试从.NET dll导入C样式的函数,这实际上与COM互操作无关。 COM互操作允许我们将.NET对象激活为COM对象,而不会将它们公开为C / C ++导出的函数/类型。
如果函数不需要返回任何数据,为什么不制作一个简单的.exe来调用函数并只从设置中运行它呢?
另外:请参阅innosetup支持新闻组,在这里我们可以获得更好的支持。
回答
糟糕,我读过Pascal的时间已经太久了!因此,如果我们需要获取价值,那么有两种可能性:
- 绝对支持使用C / C ++编写功能并导出功能。
- 使用托管C ++ dll填充到.NET dll,并将调用公开为C接口点(这应该可以工作,但是会变得凌乱)
- 使用.exe将代码结果存储在.INI文件或者注册表或者临时文件中,并在设置代码部分中读取结果(现在已经很讨厌了)
当我上次使用InnoSetup时,它不直接支持方案(从安装程序调用.NET代码)。
回答
现在,我了解了一些更多的信息,可以看到导入C样式函数和创建OLE对象之间的区别。
这样的事情对我有用:
[Code] procedure MyFunction(); var oleObject: Variant; begin oleObject := CreateOleObject('MyDLL.MyDLL'); MsgBox(oleObject.MyFunction, mbInformation, mb_Ok); end;
但是它需要注册DLL文件。
我想我将不得不创建一个命令行应用程序以从DLL调用函数。
回答
可以通过将任何.NET dll公开为COM对象来最好地从任何其他编程语言中调用它。请看以下示例:http://support.microsoft.com/kb/828736. 这显示了如何从"非托管C ++"调用" .NET dll"。我们可以用任何其他可用作COM客户端的编程语言替换"未管理的C ++"。
回答
用于检测dotnet框架和旧版本的Innosetup脚本可能有用。
回答
Insta esta manera(尝试这种方式):
Var obj: Variant va: MyVariableType; Begin //Starting ExtractTemporaryFile('MyDll.dll'); RegisterServer(False, ExpandConstant('{tmp}\MyDll.dll'), False); obj := CreateOleObject('MyDll.MyClass'); //Using va := obj.MyFunction(); //Finishing UnregisterServer(False, ExpandConstant('{tmp}\MyDll.dll'), False); DeleteFile('{tmp}\MyDll.dll'); End;
苏尔特(祝你好运)
回答
尝试使用delayload,它用于运行时可能不存在的dll。这样就解决了问题。
例如:
[Files] Source: odbccp32.dll; Flags: dontcopy [Code] procedure SQLConfigDataSource(hwndParent: Integer; Frequest: Integer; LpszDriver: String; lpszAttributes: String); external 'SQLConfigDataSource@files:odbccp32.dll stdcall delayload';