Wie kann ich es nenne, ein .NET DLL aus einem Inno-Setup-Skript?
-
09-06-2019 - |
Frage
Ich möchte eine Funktion aufrufen aus .NET-DLL (in C# gecodet) aus einem Inno-Setup-Skript.
Ich habe:
- markiert die Für COM-interop registrieren option in den Projekteigenschaften
- geändert ComVisible Einstellung in die AssemblyInfo.cs Datei,
- 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?
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:
- Schreiben Sie die Funktionalität in C/C++ und exportieren, die Funktion,, dass ist definitiv unterstützt.
- 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)
- 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';
Innosetup-Skript zu erkennen, dotnet-framework und alte version vielleicht von einigem nutzen sein.