문제

Inno 설치 스크립트의 .NET DLL(C#으로 코딩됨)에서 함수를 호출하고 싶습니다.

나는 가지고있다:

  1. 표시했다 COM interop에 등록 프로젝트 속성의 옵션
  2. 변경 컴비저블 에서 설정 AssemblyInfo.cs 파일,
  3. ISS 스크립트에 다음 줄을 추가했습니다.

[파일]

원천:c: emp\1\MyDLL.dll;플래그:복사하지 마세요

[암호]

함수 MyFunction():끈;

external '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. Managed C++ dll을 사용하여 .NET dll로 심을 실행하고 호출을 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;

Suerte (행운을 빌어요)

이에 대해 조금 더 읽었습니다. 이제 C 스타일 함수 가져오기와 OLE 개체 만들기의 차이점을 알 수 있습니다.

다음과 같은 것이 나에게 효과적입니다.

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

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

하지만 DLL 파일을 등록해야 합니다.

DLL에서 함수를 호출하려면 명령줄 응용 프로그램을 만들어야 할 것 같습니다.

.NET dll에서 C 스타일 함수를 가져오려고 합니다. 이것은 실제로 COM 상호 운용성과 관련이 없습니다.COM interop을 사용하면 .NET 개체를 COM 개체로 활성화할 수 있지만 C/C++에서 내보낸 함수/유형으로 노출되지는 않습니다.

함수가 데이터를 반환할 필요가 없다면 함수를 호출하는 간단한 .exe를 만들어 설정에서 실행해 보는 것은 어떨까요?

또한:참조 innosetup 지원 뉴스그룹 더 나은 지원을 받을 수 있는 곳.

사용 관리되지 않는 내보내기 라이브러리 Inno 설정에서 호출할 수 있는 방식으로 C# 어셈블리에서 함수를 내보내는 것입니다.

  • C# 클래스 라이브러리에서 정적 메서드 구현
  • 추가 관리되지 않는 내보내기 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 설정 측에서:

[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.이는 "관리되지 않는 C++"에서 ".NET dll"을 호출하는 방법을 보여줍니다."관리되지 않은 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