Frage

Ich möchte eine Funktion aufrufen aus .NET-DLL (in C# gecodet) aus einem Inno-Setup-Skript.

Ich habe:

  1. markiert die Für COM-interop registrieren option in den Projekteigenschaften
  2. geändert ComVisible Einstellung in die AssemblyInfo.cs Datei,
  3. diese Zeilen, um der ISS-Skript:

[Files]

Quelle:c: emp\1\MyDLL.dll;Flags:dontcopy

[Code]

function MyFunction():string;

externe 'MyFunction@files:MyDLL.dll stdcall setuponly';

aber ich bekomme immer noch den folgenden Fehler:

Runtime Error (at -1:0):

Nicht-Import-dll:C:\DOCUME~1\foo\LOCALS~1 emp\is-LRL3E.tmp\MyDLL.dll.

Was mache ich falsch?

War es hilfreich?

Lösung

Oops, mein schlecht, es ist zu lange, seitdem ich gelesen habe, pascal!Also, wenn Sie brauchen, um den Wert, dann gibt es ein paar Möglichkeiten:

  1. Schreiben Sie die Funktionalität in C/C++ und exportieren, die Funktion,, dass ist definitiv unterstützt.
  2. Verwenden Sie eine Verwaltete C++ - dll shim zu Ihr .NET-dll, und setzen Sie den Anruf wie ein C-interface point (dies sollte funktionieren, aber es ist immer chaotisch)
  3. Verwenden .exe-Datei zu speichern das Ergebnis Ihres Codes in einer .INI-Datei oder in der registry oder in einer temporären Datei und Lesen Sie das Ergebnis in das setup-code-Abschnitt (dies ist jetzt richtig böse)

Als ich zuletzt gearbeitet mit InnoSetup es nicht Unterstützung Ihr Szenario direkt aufrufen .NET-code aus setup).

Andere Tipps

Intenta de esta manera (Versuchen Sie es so):

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 (Glück)

Ich lese ein wenig darüber - ich kann jetzt den Unterschied zwischen importieren von C-style-Funktion und erstellen eines OLE-Objekts.

So etwas wäre für mich arbeiten:

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

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

aber es erfordert die Registrierung der DLL-Datei.

Ich denke, ich werde haben, um eine Kommandozeilen-Anwendung zum aufrufen der Funktionen aus der DLL.

Sie versuchen, importieren Sie eine C-style-Funktion von Ihrem .NET dll - dies hat nicht wirklich etwas zu tun mit COM-interop.COM-interop ermöglicht Ihnen die Aktivierung Ihres .NET-Objekte als COM-Objekte, nicht aussetzen, Sie als C/C++ exportierten Funktionen/Typen.

Wenn Ihr die Funktion nicht braucht, um wieder alle Daten, warum machen Sie nicht einen einfachen .exe-Datei, ruft die Funktion und führen Sie einfach, dass Sie von Ihrem setup?

Auch:Siehe die innosetup-support-newsgroups wo erhalten Sie möglicherweise eine bessere Unterstützung.

Verwenden Sie die Nicht verwaltete Exporte Bibliothek so exportieren Sie eine Funktion aus einer C# - assembly, in einer Weise, dass es genannt werden kann, in der Inno Setup.

  • Implementieren Sie eine statische Methode in C# - Klassenbibliothek
  • Fügen Sie die Nicht Verwaltete Exporte NuGet-Paket zu Ihrem Projekt
  • Set Plattform-Ziel von Ihrem Projekt x86
  • Fügen Sie die DllExport Attribut zur Methode
  • Wenn erforderlich, definieren Sie einen Marshalling für die Funktion der Argumente (insbesondere Marshalling von string-Argumente definiert werden).
  • Bauen
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;
        }
    }
}

Auf Inno-Setup Seite:

[Files]
Source: "MyNetDll.dll"; Flags: dontcopy

[Code]
function RegexMatch(Pattern: string; Input: string): Boolean;
    external 'RegexMatch@files:MyNetDll.dll stdcall';

Und jetzt können Sie Ihre Funktion wie folgt:

if RegexMatch('[0-9]+', '123456789') then
begin
  Log('Matched');
end
  else
begin
  Log('Not matched');
end;

Siehe auch:

Ein .NET dll kann am besten sein, genannt von jeder anderen Programmiersprache, indem Sie es als ein COM-Objekt.Werfen Sie einen Blick auf dieses Beispiel: http://support.microsoft.com/kb/828736.Dies zeigt, wie einen Anruf ".NET-dll" von "nicht verwaltete C++".Sie können ersetzen die "unamanged C++" von jeder anderen Programmiersprache, die verwendet werden können, wie ein COM-client.

Versuchen Sie es mit delayload, es ist verwendet für eine dll, die nicht existieren kann zur Laufzeit.Diese lösen die problem.

Zum Beispiel:

[Files]
Source: odbccp32.dll; Flags: dontcopy

[Code]
procedure SQLConfigDataSource(hwndParent: Integer; Frequest: Integer; LpszDriver: String; lpszAttributes: String);
external 'SQLConfigDataSource@files:odbccp32.dll stdcall delayload';
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top