加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

inno-setup – Inno Setup – 自动提交卸载提示

发布时间:2020-12-15 10:06:17 所属栏目:大数据 来源:网络整理
导读:我想要隐藏unisntaller的第一条和最后一条消息.此代码适用于inno setup(Inno Setup Ultra 5.5.1.ee2)的修改版本,但不能很好地隐藏第一条消息(短暂显示并消失): function FindWindowEx(Parent,Child: HWND; ClassName,WindowName: PansiChar): HWND; externa
我想要隐藏unisntaller的第一条和最后一条消息.此代码适用于inno setup(Inno Setup Ultra 5.5.1.ee2)的修改版本,但不能很好地隐藏第一条消息(短暂显示并消失):
function FindWindowEx(Parent,Child: HWND; ClassName,WindowName: PansiChar): HWND;
  external 'FindWindowExA@user32.dll stdcall';

const
  BM_CLICK    = $00F5;
var
  Timer: TTimer;
  msg: string;
  Wnd,WndEx: HWND;

procedure OnTimer(Sender: TObject);
begin
  Wnd:= FindWindowByWindowName(msg);
  if Wnd > 0 then
  begin
    WndEx:= FindWindowEx(Wnd,'Button','');
    if WndEx > 0 then
    begin
      PostMessage(WndEx,BM_CLICK,0);
      Timer.Enabled:= False;
    end;
  end;
end;

function InitializeUninstall:boolean;
begin
  Result := True;
  msg:= SetupMessage(msgUninstallAppFullTitle);
  StringChange(msg,'%1','{#SetupSetting('AppName')}');
  OnTimer(nil);
  Timer:= TTimer.Create(nil);
  with Timer do
  begin
    OnTimer:= @OnTimer;
    Interval:= 1;
    Enabled:= True;
  end;
end;

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
  if CurUninstallStep=usPostUninstall then
  begin
    OnTimer(nil);
    Timer:= TTimer.Create(nil);
    with Timer do
    begin
      OnTimer:= @OnTimer;
      Interval:= 1;
      Enabled:= True;
    end;
  end;
end;

如何修改此代码以正确使用Inno Setup的当前正式版本并正确隐藏这两个消息?

解决方法

首先,我必须说我根本不同意这一点.但无论如何这都是一个有趣的问题,实施可能对其他更合适的案例有用.

此外,您无法避免短暂出现该消息.该解决方案可自动化UI,因此需要UI才能工作.这是我不喜欢它的原因之一.

此代码使用InnoTools InnoCallback DLL library来实现计时器.但是使用来自卸载程序的外部DLL库是棘手的并且有其缺点.见Load external DLL for uninstall process in Inno Setup.

[Setup]
AppName=My Program

[Files]
Source: "InnoCallback.dll"; DestDir: {app}

[Code]

const
  BM_CLICK = $00F5;

type
  TTimerProc = procedure(HandleW,msg,idEvent,TimeSys: LongWord);

function FindWindowEx(Parent,WindowName: string): HWND;
  external 'FindWindowExW@user32.dll stdcall';
function SetTimer(hWnd,nIDEvent,uElapse,lpTimerFunc: LongWord): LongWord;
  external 'SetTimer@User32.dll stdcall';
function KillTimer(hWnd,nIDEvent: LongWord): LongWord;
  external 'KillTimer@User32.dll stdcall';

function WrapTimerProcUninstall(Callback: TTimerProc; ParamCount: Integer): LongWord;
  external 'wrapcallback@{%TEMP}InnoCallback.dll stdcall uninstallonly delayload';

var
  UpcomingMessage: string;  
  SubmitMessageTimer: LongWord;
  SubmitMessagePossible: Boolean;

procedure SubmitMessageProc(
  H: LongWord; Msg: LongWord; IdEvent: LongWord; Time: LongWord);
var
  WindowHandle,ButtonHandle: HWND;
begin
  { TODO: Cancel the timer,if the message does not appear within few seconds }
  WindowHandle := FindWindowByWindowName(UpcomingMessage);
  if WindowHandle > 0 then
  begin
    Log(Format('Found message window "%s"',[UpcomingMessage]));
    ButtonHandle := FindWindowEx(WindowHandle,'');
    if ButtonHandle > 0 then
    begin
      Log('Found button');
      PostMessage(ButtonHandle,0);
      KillTimer(0,SubmitMessageTimer);
      SubmitMessageTimer := 0;
    end;
  end;
end;

procedure SubmitUpcomingMessage(Msg: string);
begin
  if not SubmitMessagePossible then
  begin
    Log('Cannot submit message');
  end
    else
  begin
    if SubmitMessageTimer > 0 then
      KillTimer(0,SubmitMessageTimer);

    Log(Format('Want to automatically submit message "%s"',[Msg]));
    UpcomingMessage := Msg;
    SubmitMessageTimer :=
      SetTimer(0,100,WrapTimerProcUninstall(@SubmitMessageProc,4));
  end;
end;

function FmtSetupMessageWithAppName(const ID: TSetupMessageID): string;
begin
  Result := FmtMessage(SetupMessage(ID),['{#SetupSetting('AppName')}']);
end;

function InitializeUninstall:boolean;
begin
  Result := True;

  SubmitMessagePossible :=
    FileCopy(
      ExpandConstant('{app}InnoCallback.dll'),ExpandConstant('{%TEMP}InnoCallback.dll'),False);

  SubmitUpcomingMessage(FmtSetupMessageWithAppName(msgUninstallAppFullTitle));
end;

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
  if CurUninstallStep = usPostUninstall then
  begin
    SubmitUpcomingMessage(FmtSetupMessageWithAppName(msgUninstallAppFullTitle));
  end;
end;

该代码需要Unicode Inno Setup.

有关该问题的不同方法,请参阅Changing uninstall confirmation prompt.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读