Inno设置之间通过Pipe进行的进程间通信无法创建管道

时间:2015-07-07 10:27:30

标签: inno-setup communication named-pipes interprocess

我想将一个巨大的Inno设置分成更小的包,这些包将他们的进度和状态分配给" master"建立。子设置应称为静默/隐藏,以便只有一个窗口在前面,并将所有其他窗口的进度集成到一个(总)进度条中。 我试图通过Windows管道系统进行相互通信,但即使创建命名管道也会失败。我已经使用了" \\。\ pipe \ SetupMsPipe123"并且在调试时它在给定变量中正确显示。甚至可以像" \\\\。\\ pipe \\ SetupMsPipe123"失败。 函数的返回值似乎是INVALID_HANDLE_VALUE,但Inno变量似乎只保存8字节句柄值的4个字节。 可能是变量之间的类型转换有问题。

(更新了TLama的建议)

[Code]   {BOTH}
type
#ifdef UNICODE
    #define AW "W"
#else
    #define AW "A"
#endif
#define DefPipeName  "\\.\pipe\SetupMsPipe123"
var
    mhPipeHandle:   THandle;
    msPipeName  :   string;
type LPSECURITY_ATTRIBUTES = Cardinal; function CreateNamedPipe(lpName: string; dwOpenMode, dwPipeMode, nMaxInstances, nOutBufferSize, nInBufferSize, nDefaultTimeOut: DWORD; lpSecurityAttributes: LPSECURITY_ATTRIBUTES): THandle;
  external 'CreateNamedPipe{#AW}@kernel32.dll stdcall';
function WaitNamedPipe(lpNamedPipeName: string; nTimeOut: DWORD): Boolean;
  external 'WaitNamedPipe{#AW}@kernel32 stdcall';
function ConnectNamedPipe(hNamedPipe: THandle; lpOverlapped: LongWord): Boolean;
  external 'ConnectNamedPipe@kernel32 stdcall';
function DisconnectNamedPipe(hNamedPipe: THandle): Boolean;
  external 'DisconnectNamedPipe@kernel32 stdcall';
function CreateFile(lpFileName: string; dwDesiredAccess,dwShareMode: DWORD; lpSecurityAttributes: LPSECURITY_ATTRIBUTES; dwCreationDisposition,dwFlagsAndAttributes: DWORD; hTemplateFile: THandle): LongWord;
  external 'CreateFile{#AW}@kernel32 stdcall';
function ReadFile(hFile: THandle; lpBuffer: string; nNumberOfBytesToRead: DWORD; var lpNumberOfBytesRead: LongWord; var lpOverlapped: LongWord): Boolean;
  external 'ReadFile@kernel32 stdcall';
function WriteFile(hFile: THandle; lpBuffer: string; nNumberOfBytesToWrite: DWORD; var lpNumberOfBytesWritten: LongWord; var lpOverlapped: LongWord): Boolean;
  external 'WriteFile@kernel32 stdcall';
function CloseHandle(hObject: THandle): Boolean;
  external 'CloseHandle@kernel32 stdcall';
function GetLastError(): DWORD;
  external 'GetLastError@kernel32 stdcall';

[Code]   {MASTER}
procedure InitializeWizard();
var 
  lcbProgress: longword;
  lcbFilename: longword;
  bStat:       Boolean;
  lpPipename:  string;
begin
  msPipeName := ExpandConstant('{#DefPipeName}');
  mhPipeHandle := dllCreateNamedPipe(msPipeName, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE or PIPE_NOWAIT, 2, 1024, 1024, 60000, 0);
  if mhPipeHandle <> INVALID_HANDLE_VALUE then begin    
    bStat := dllConnectNamedPipe(mhPipeHandle, 0);
  end;
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
  iProgressInner: integer;
  bStat:          Boolean;
  acReadBuffer:   string;
  dwBufLen:       DWORD;
  dwBytesRead:    DWORD;
  dwOverlapped:   DWORD;
begin
  SetLength(acReadBuffer, 1024);
  if CurStep = ssInstall then begin
    Exec('setupInner.exe', '', '', SW_SHOW, ewNoWait, ResultCode);
    while (iProgressInner<100) do begin
      bStat := ReadFile(mhPipeHandle, acReadBuffer, Length(acReadBuffer), dwBytesRead, dwOverlapped);
      iProgressInner := StrToInt(acReadBuffer);
      WizardForm.Caption:='Progress: ' + IntToStr(iProgressInner);
      WizardForm.Refresh();
      Sleep (1000)     
    end;
  end;
end;

procedure DeinitializeSetup();
begin 
  DisconnectNamedPipe(mhPipeHandle);
  CloseHandle(mhPipeHandle);
end;

[code]  {Slave}
function InitializeSetup(): Boolean;
var
  bStat:          Boolean;
  lpOutBuffer:    LongWord;
  nOutBufferSize: DWORD;
  lpBytesRead:    LongWord;
begin
  msPipeName := ExpandConstant('{#DefPipeName}');
  bStat := WaitNamedPipe(msPipeName, 60000);
  mhPipeHandle := CreateFile(msPipeName, GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  Result := true;
end;

procedure CurInstallProgressChanged(CurProgress, MaxProgress: Integer);
var                   
  iProgress:      integer;
  bStat:          Boolean;
  acWriteBuffer:  String;
  dwBufLen:       DWORD;
  dwWritten:      DWORD;
  dwOverlapped:   DWORD;
  sTemp:          String;
begin
  sTemp := IntToStr(CurProgress);    
  while Length(sTemp) < 3 do begin
    sTemp := '0' + sTemp;
  end;
  acWriteBuffer := sTemp;
// Here the exception occurs !!! 
  bStat := WriteFile(mhPipeHandle, acWriteBuffer,    Length(acWriteBuffer), dwWritten, dwOverlapped); 
end;

0 个答案:

没有答案