Inno Setup スクリプトから .NET DLL を呼び出すにはどうすればよいですか?
-
09-06-2019 - |
質問
Inno Setup スクリプトから .NET DLL (C# でコード化された) の関数を呼び出したいと考えています。
私は持っている:
- をマークした COM相互運用に登録する プロジェクトプロパティのオプション、
- を変えた コムビジブル の設定 アセンブリ情報.cs ファイル、
- 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 をインポートできません。
私の何が間違っているのでしょうか?
解決
おっと、悪い、パスカルを読むのは久しぶりすぎた!したがって、値を取得する必要がある場合は、いくつかの可能性があります。
- C/C++ で機能を記述し、その関数をエクスポートします。これは確実にサポートされます。
- マネージド C++ DLL を使用して .NET DLL に shim し、呼び出しを C インターフェイス ポイントとして公開します (これは機能するはずですが、面倒になります)。
- .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 サポート ニュースグループ より良いサポートが得られる可能性があります。
使用 アンマネージドエクスポートライブラリ Inno Setup で呼び出すことができる方法で、C# アセンブリから関数をエクスポートします。
- C# クラス ライブラリに静的メソッドを実装する
- を追加します。 管理されていないエクスポート 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 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」を呼び出す方法を示します。「アンマネージ C++」は、COM クライアントとして使用できる他のプログラミング言語に置き換えることができます。
実行時に存在しない可能性のある DLL に使用される、Delayload を使用してみてください。これで問題は解決します。
例えば:
[Files]
Source: odbccp32.dll; Flags: dontcopy
[Code]
procedure SQLConfigDataSource(hwndParent: Integer; Frequest: Integer; LpszDriver: String; lpszAttributes: String);
external 'SQLConfigDataSource@files:odbccp32.dll stdcall delayload';
ドットネット フレームワークと古いバージョンを検出する Innosetup スクリプト 何かの役に立つかもしれない。