Reputation: 17363
I want to call a function from a .NET DLL (coded in C#) from an Inno Setup script.
I have:
marked the Register for COM interop option in the project properties,
changed the ComVisible
setting in the AssemblyInfo.cs
file,
added these lines to the ISS script:
[Files]
Source: c:\temp\1\MyDLL.dll; Flags: dontcopy
[Code]
function MyFunction(): string;
external 'MyFunction@files:MyDLL.dll stdcall setuponly';
But I still get the following error:
Runtime Error (at -1:0):
Cannot Import dll:C:\DOCUME~1\foo\LOCALS~1\Temp\is-LRL3E.tmp\MyDLL.dll.
What am I doing wrong?
Upvotes: 12
Views: 10262
Reputation: 202534
Use the Unmanaged Exports library to export a function from a C# assembly, in a way that it can be called in Inno Setup.
DllExport
attribute to your methodusing 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;
}
}
}
On Inno Setup side:
[Files]
Source: "MyNetDll.dll"; Flags: dontcopy
[Code]
function RegexMatch(Pattern: string; Input: string): Boolean;
external 'RegexMatch@files:MyNetDll.dll stdcall';
And now you can use your function like this:
if RegexMatch('[0-9]+', '123456789') then
begin
Log('Matched');
end
else
begin
Log('Not matched');
end;
See also:
Upvotes: 3
Reputation: 9
Try using delayload, it is used for a dll that may not exist at runtime. This solve the problem.
For example:
[Files]
Source: odbccp32.dll; Flags: dontcopy
[Code]
procedure SQLConfigDataSource(hwndParent: Integer; Frequest: Integer; LpszDriver: String; lpszAttributes: String);
external 'SQLConfigDataSource@files:odbccp32.dll stdcall delayload';
Upvotes: 0
Reputation: 69
Intenta de esta manera (Try this way):
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 (good luck)
Upvotes: 6
Reputation: 4545
A .NET dll can be best called from any other programming language by exposing it as a COM object. Take a look at this example: http://support.microsoft.com/kb/828736. This shows how to call a ".NET dll" from "unmanaged C++". You can replace the "unamanged C++" by any other programming language, that can be used as a COM client.
Upvotes: 0
Reputation: 17363
I read a little bit more about it - now I can see the difference between importing a C-style function and creating an OLE object.
Something like this would work for me:
[Code]
procedure MyFunction();
var
oleObject: Variant;
begin
oleObject := CreateOleObject('MyDLL.MyDLL');
MsgBox(oleObject.MyFunction, mbInformation, mb_Ok);
end;
but it requires registering the DLL file.
I guess I will have to create a command-line application to call the functions from the DLL.
Upvotes: 4
Reputation: 11608
Oops, my bad, it's been too long since I've read pascal! So, if you need to get the value then there are a couple of possibilities:
When I last worked with InnoSetup it didn't support your scenario directly (calling .NET code from setup).
Upvotes: 5
Reputation: 11608
You're trying to import a C-style function from your .NET dll - this doesn't really have anything to do with COM interop. COM interop allows you to activate your .NET objects as COM objects, it doesn't expose them as C/C++ exported functions/types.
If your function doesn't need to return any data, why not make a simple .exe that calls your function and just run that from your setup?
Also: See the innosetup support newsgroups where you might get better support.
Upvotes: 2