9

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

我有:

  1. 在项目属性中标记了Register for COM interop选项,
  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。

我究竟做错了什么?

4

7 回答 7

5

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;

苏尔特(祝你好运)

于 2009-11-10T02:39:07.823 回答
4

哎呀,我的错,我已经很久没有读过帕斯卡了!因此,如果您需要获得价值,那么有几种可能性:

  1. 用 C/C++ 编写函数并导出函数,这绝对是支持的。
  2. 使用托管 C++ dll 填充到您的 .NET dll,并将调用公开为 C 接口点(这应该可以工作,但它会变得混乱)
  3. 使用 .exe 将代码的结果存储在 .INI 文件或注册表或临时文件中,并在安装代码部分读取结果(这现在很讨厌)

当我上次使用 InnoSetup 时,它不直接支持您的方案(从设置中调用 .NET 代码)。

于 2008-09-05T11:03:44.623 回答
3

我阅读了更多关于它的内容 - 现在我可以看到导入 C 样式函数和创建 OLE 对象之间的区别。

像这样的东西对我有用:

[Code]
procedure MyFunction();
var
  oleObject: Variant;
begin
  oleObject := CreateOleObject('MyDLL.MyDLL');

  MsgBox(oleObject.MyFunction, mbInformation, mb_Ok);
end;

但它需要注册 DLL 文件。

我想我将不得不创建一个命令行应用程序来调用 DLL 中的函数。

于 2008-09-05T11:44:34.303 回答
2

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

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

另外:请参阅innosetup 支持新闻组,您可能会在其中获得更好的支持。

于 2008-09-05T10:33:40.217 回答
2

使用非托管导出库从 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;

也可以看看:

于 2017-04-10T06:57:23.560 回答
0

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

于 2008-09-15T16:33:37.490 回答
0

尝试使用延迟加载,它用于运行时可能不存在的 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';
于 2010-08-05T17:41:24.603 回答