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

我有:

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

[文件]

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

[代码]

函数 MyFunction():细绳;

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

但我仍然收到以下错误:

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

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

我究竟做错了什么?

有帮助吗?

解决方案

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

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

当我上次使用 InnoSetup 时,它不直接支持您的场景(从安装程序调用 .NET 代码)。

其他提示

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;

苏尔特(祝你好运)

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

像这样的东西对我有用:

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

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

但它需要注册DLL文件。

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

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

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

还:请参阅 innosetup 支持新闻组 您可能会得到更好的支持。

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

[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 公开为 COM 对象,可以从任何其他编程语言调用它。看一下这个例子: http://support.microsoft.com/kb/828736. 。这展示了如何从“非托管C++”调用“.NET dll”。您可以用任何其他可用作 COM 客户端的编程语言来替换“未管理的 C++”。

尝试使用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';
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top