我想要隐藏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, 0,'Button', '');
if WndEx > 0 then
begin
PostMessage(WndEx, BM_CLICK, 0, 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的当前官方版本并正确隐藏这两条消息?
答案 0 :(得分:0)
首先,我必须说我根本不同意这一点。但无论如何它都是一个有趣的问题,实施可能对其他更合适的案例有用。
此外,您无法避免短暂显示该消息。该解决方案可自动化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, Child: HWND; ClassName, 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, 0, 'Button', '');
if ButtonHandle > 0 then
begin
Log('Found button');
PostMessage(ButtonHandle, BM_CLICK, 0, 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, 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。