繁体   English   中英

如何从 Inno Setup 脚本调用 .NET DLL?

[英]How can I call a .NET DLL from an Inno Setup script?

我想从 Inno Setup 脚本的 .NET DLL(用 C# 编码)调用一个函数。

我有:

  1. 在项目属性中标记了注册 COM 互操作选项,
  2. 更改了AssemblyInfo.cs文件中的ComVisible设置,
  3. 将这些行添加到 ISS 脚本中:

[文件]

来源:c:\\temp\\1\\MyDLL.dll; 标志:不要复制

[代码]

函数 MyFunction(): 字符串;

外部'MyFunction@files:MyDLL.dll stdcall setuponly';

但我仍然收到以下错误:

运行时错误(-1:0):

无法导入 dll:C:\\DOCUME~1\\foo\\LOCALS~1\\Temp\\is-LRL3E.tmp\\MyDLL.dll。

我究竟做错了什么?

Intenta de 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;

Suerte(祝你好运)

哎呀,我的坏,自从我读过帕斯卡以来已经太久了! 所以,如果你需要获得价值,那么有几种可能性:

  1. 用C / C ++编写功能并导出功能,这是绝对支持的。
  2. 使用托管C ++ DLL来填充.NET dll,并将调用作为C接口点公开(这应该可以工作,但是它变得很乱)
  3. 使用.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中的函数。

使用Unmanaged Exports库从C#程序集中导出函数,其方式可以在Inno Setup中调用。

using RGiesecke.DllExport;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;

namespace MyNetDll
{
    public class MyFunctions
    {
        [DllExport(CallingConvention = CallingConvention.StdCall)]
        public static bool RegexMatch(
            [MarshalAs(UnmanagedType.LPWStr)]string pattern,
            [MarshalAs(UnmanagedType.LPWStr)]string input)
        {
            return Regex.Match(input, pattern).Success;
        }
    }
}

在Inno设置方面:

[Files]
Source: "MyNetDll.dll"; Flags: dontcopy

[Code]
function RegexMatch(Pattern: string; Input: string): Boolean;
    external 'RegexMatch@files:MyNetDll.dll stdcall';

现在您可以像这样使用您的函数:

if RegexMatch('[0-9]+', '123456789') then
begin
  Log('Matched');
end
  else
begin
  Log('Not matched');
end;

也可以看看:

您正在尝试从.NET dll导入C风格的函数 - 这与COM互操作无关。 COM interop允许您将.NET对象激活为COM对象,它不会将它们公开为C / C ++导出的函数/类型。

如果你的函数不需要返回任何数据,为什么不制作一个简单的.exe来调用你的函数并从你的设置中运行它?

另外:查看innosetup支持新闻组 ,您可以获得更好的支持。

尝试使用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';

通过将其作为COM对象公开,可以从任何其他编程语言中最好地调用.NET dll。 看一下这个例子: http//support.microsoft.com/kb/828736 这显示了如何从“非托管C ++”调用“.NET dll”。 您可以用任何其他编程语言替换“unamanged C ++”,它可以用作COM客户端。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM