Как я могу вызвать .NET DLL из сценария установки Inno? - PullRequest
9 голосов
/ 05 сентября 2008

Я хочу вызвать функцию из .NET DLL (кодируется на C #) из сценария установки Inno.

У меня есть:

  1. помеченный Регистр для COM-взаимодействия в свойствах проекта,
  2. изменил параметр ComVisible в файле AssemblyInfo.cs ,
  3. добавил следующие строки в скрипт ISS:

[Files]

Источник: c: \ temp \ 1 \ MyDLL.dll; Флаги: dontcopy

[Код]

function MyFunction (): string;

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

но я все еще получаю следующую ошибку:

Ошибка времени выполнения (при -1: 0):

Не удается импортировать dll: C: \ DOCUME ~ 1 \ foo \ LOCALS ~ 1 \ Temp \ is-LRL3E.tmp \ MyDLL.dll.

Что я делаю не так?

Ответы [ 8 ]

5 голосов
/ 10 ноября 2009

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;

Suerte (удачи)

4 голосов
/ 05 сентября 2008

Ой, плохо, прошло слишком много времени с тех пор, как я читал паскаль! Итак, если вам нужно получить значение, тогда есть пара возможностей:

  1. Напишите функциональность на C / C ++ и экспортируйте функцию, которая определенно поддерживается.
  2. Используйте Managed C ++ dll, чтобы перейти к вашей .NET dll, и представить вызов как точку интерфейса C (это должно работать, но это становится грязным)
  3. Используйте .exe для сохранения результата вашего кода в файле .INI или в реестре или во временном файле и считайте результат в разделе кода установки (это теперь правильно)

Когда я в последний раз работал с InnoSetup, он не поддерживал ваш сценарий напрямую (вызов кода .NET из программы установки).

3 голосов
/ 05 сентября 2008

Я прочитал немного больше об этом - теперь я вижу разницу между импортом функции стиля C и созданием объекта OLE.

Что-то вроде этого будет работать для меня:

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

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

но требует регистрации DLL-файла.

Полагаю, мне нужно будет создать приложение командной строки для вызова функций из DLL.

2 голосов
/ 10 апреля 2017

Используйте библиотеку Неуправляемый экспорт , чтобы экспортировать функцию из сборки C # таким образом, чтобы ее можно было вызывать в Inno Setup.

  • Реализация статического метода в библиотеке классов C #
  • Добавьте пакет Unmanaged Exports 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;

Смотри также:

2 голосов
/ 05 сентября 2008

Вы пытаетесь импортировать функцию C-стиля из вашей .NET DLL - это не имеет никакого отношения к COM-взаимодействию. COM-взаимодействие позволяет вам активировать ваши .NET-объекты как COM-объекты, но не отображать их как экспортированные функции / типы C / C ++.

Если вашей функции не нужно возвращать какие-либо данные, почему бы не создать простой .exe-файл, который вызывает вашу функцию и просто запустить его из настроек?

Также: см. группы новостей поддержки innosetup , где вы можете получить лучшую поддержку.

0 голосов
/ 05 августа 2010

Попробуйте использовать задержку загрузки, она используется для 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';
0 голосов
/ 14 января 2009
0 голосов
/ 15 сентября 2008

.NET dll лучше всего вызывать из любого другого языка программирования, представив его как объект COM. Взгляните на этот пример: http://support.microsoft.com/kb/828736. Здесь показано, как вызвать «.NET dll» из «неуправляемого C ++». Вы можете заменить «unamanged C ++» на любой другой язык программирования, который можно использовать в качестве COM-клиента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...