如何从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';