9

InnoSetupスクリプトから.NETDLL(C#でコード化)から関数を呼び出したい。

私は持っています:

  1. プロジェクトプロパティで[ COM相互運用機能の登録]オプションをマークし、
  2. AssemblyInfo.csファイルのComVisible設定を変更しました。
  3. 次の行をISSスクリプトに追加しました。

[ファイル]

ソース:c:\ temp \ 1 \ MyDLL.dll; フラグ:dontcopy

[コード]

関数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

残念ながら、Pascal を読むのは久しぶりです。したがって、値を取得する必要がある場合は、いくつかの可能性があります。

  1. 機能を C/C++ で記述し、関数をエクスポートします。これは確実にサポートされています。
  2. Managed 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

Unmanaged Exports ライブラリを使用して、C# アセンブリから関数をエクスポートし、Inno Setup で呼び出せるようにします。

  • 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;

以下も参照してください。

于 2017-04-10T06:57:23.560 に答える
0

.NET dll は、COM オブジェクトとして公開することにより、他のプログラミング言語から最適に呼び出すことができます。この例を見てみましょう: http://support.microsoft.com/kb/828736 . これは、「アンマネージ C++」から「.NET dll」を呼び出す方法を示しています。「管理されていない C++」を、COM クライアントとして使用できる他のプログラミング言語に置き換えることができます。

于 2008-09-15T16:33:37.490 に答える
0

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';
于 2010-08-05T17:41:24.603 に答える