Как я могу вызвать .NET DLL из сценария установки Inno?
-
09-06-2019 - |
Вопрос
Я хочу вызвать функцию из библиотеки .NET DLL (закодированной на C#) из сценария установки Inno.
У меня есть:
- отметил Зарегистрируйтесь для COM-взаимодействия опция в свойствах проекта,
- изменил ComVisible обстановка в СборкаИнформация.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++ и экспортируйте функцию, она определенно поддерживается.
- Используйте управляемую dll C++ для перехода к вашей dll .NET и выставьте вызов как точку интерфейса 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.
Вы пытаетесь импортировать функцию в стиле C из вашей dll .NET — на самом деле это не имеет ничего общего с COM-взаимодействием.COM-взаимодействие позволяет активировать объекты .NET как COM-объекты, но не представляет их как экспортированные функции/типы C/C++.
Если вашей функции не нужно возвращать какие-либо данные, почему бы не создать простой .exe-файл, который вызывает вашу функцию, и просто запускать его из вашей установки?
Также:См. группы новостей поддержки innosetup где вы можете получить лучшую поддержку.
Использовать Библиотека неуправляемого экспорта для экспорта функции из сборки C# таким образом, чтобы ее можно было вызвать в Inno Setup.
- Реализация статического метода в библиотеке классов C#.
- Добавить Неуправляемый экспорт Пакет NuGet в ваш проект
- Набор Цель платформы вашего проекта в х86
- Добавить
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:
[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.Здесь показано, как вызвать «.NET dll» из «неуправляемого C++».Вы можете заменить «неуправляемый C++» любым другим языком программирования, который можно использовать в качестве COM-клиента.
Попробуйте использовать задержку, она используется для 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';
Скрипт Innosetup для обнаружения платформы dotnet и старой версии может быть чем-то полезен.