Как я могу вызвать .NET DLL из сценария установки Inno?

StackOverflow https://stackoverflow.com/questions/45510

  •  09-06-2019
  •  | 
  •  

Вопрос

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

У меня есть:

  1. отметил Зарегистрируйтесь для COM-взаимодействия опция в свойствах проекта,
  2. изменил ComVisible обстановка в СборкаИнформация.cs файл,
  3. добавил эти строки в скрипт 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.

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

Это было полезно?

Решение

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

  1. Напишите функциональность на C/C++ и экспортируйте функцию, она определенно поддерживается.
  2. Используйте управляемую dll C++ для перехода к вашей dll .NET и выставьте вызов как точку интерфейса C (это должно работать, но это становится беспорядочным).
  3. Используйте .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';
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top