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

cl25kdpy  于 2023-01-18  发布在  .NET
关注(0)|答案(7)|浏览(285)

我想从Inno Setup脚本调用. NET DLL(用C#编写)中的函数。
我有:
1.在项目属性中标记了 * 注册COM互操作 * 选项,
1.更改了AssemblyInfo.cs文件中的ComVisible设置,
1.已将以下行添加到ISS脚本:

[Files]
Source: c:\temp\1\MyDLL.dll; Flags: dontcopy
[Code]
function MyFunction(): string;
    external 'MyFunction@files:MyDLL.dll stdcall setuponly';

但我仍然得到以下错误:
运行时错误(在-1:0):
无法导入动态链接库:C:\文档~1\foo\LOCALS~1\临时文件\is-LRL3E.tmp\我的DLL.dll。
我哪里做错了?

lztngnrs

lztngnrs1#

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(好运)

nx7onnlm

nx7onnlm2#

哎呀,我的错,我已经很久没有读过pascal了!所以,如果你需要得到这个值,那么有几种可能性:
1.用C/C编写函数并导出函数,这是绝对支持的。
1.使用托管C
dll填充到.NET dll,并将调用公开为C接口点(这应该可以,但会变得很混乱)
1.使用.exe将代码的结果存储在.INI文件或注册表或临时文件中,并在安装代码部分读取结果(这现在相当令人讨厌)
当我上次使用InnoSetup时,它不直接支持您的场景(从安装程序调用.NET代码)。

wnrlj8wa

wnrlj8wa3#

我读了一些关于它的东西-现在我可以看到导入C风格函数和创建OLE对象之间的区别了。
像这样的事情对我来说很有用:

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

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

但需要注册DLL文件。
我想我必须创建一个命令行应用程序来调用DLL中的函数。

iih3973s

iih3973s4#

使用Unmanaged Exports library从C#程序集中导出函数,以便可以在Inno Setup中调用该函数。

  • 在C#类库中实现静态方法
  • Unmanaged Exports NuGet包添加到项目中
  • 将项目的“平台目标”设置为“x86”
  • DllExport属性添加到方法中
  • 如果需要,为函数参数定义封送处理(特别是必须定义字符串参数的封送处理)。
  • 构建
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;

另见:

vfwfrxfs

vfwfrxfs5#

您正在尝试从.NET dll导入一个C风格的函数-这实际上与COM互操作没有任何关系。COM互操作允许您将.NET对象作为COM对象激活,它不会将它们作为C/C++导出函数/类型公开。
如果你的函数不需要返回任何数据,为什么不创建一个简单的.exe来调用你的函数,然后从你的设置中运行它呢?
另外:请参阅innosetup support newsgroups,在那里您可能会获得更好的支持。

dffbzjpn

dffbzjpn6#

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

xmd2e60i

xmd2e60i7#

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

相关问题