2017-02-15 23 views
1

Я хочу скрыть первое и последнее сообщение unisntaller. Этот код работает с модифицированной версией установки INNO (Inno Setup Ультра 5.5.1.ee2), но не очень хорошо работает, чтобы скрыть первое сообщение (на короткое время появляется и исчезает):Inno Setup - Автоматическая отправка приглашений по удалению

function FindWindowEx(Parent, Child: HWND; ClassName, WindowName: PansiChar): HWND; 
    external '[email protected] 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

В Inno Setup нет класса «TTimer». Используете ли вы какую-то стороннюю сборку Inno Setup? –

+0

@MartinPrikryl Этот код работает с измененной версией inno setup (Inno Setup Ultra 5.5.1.ee2). Я использую последнюю версию Inno Setup. –

+0

@MartinPrikryl Я отредактировал мое сообщение с этой информацией. –

ответ

0

Во-первых, я должен сказать, что я не согласен с этим вообще. Но в любом случае это интересная проблема, и реализация может быть полезна для других, более подходящих случаев.

Также вы не можете избежать короткого сообщения. Решение автоматизирует пользовательский интерфейс, поэтому пользовательский интерфейс должен работать. Это одна из причин, по которым мне это не нравится.


Этот код использует 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 '[email protected] stdcall'; 
function SetTimer(hWnd, nIDEvent, uElapse, lpTimerFunc: LongWord): LongWord; 
    external '[email protected] stdcall'; 
function KillTimer(hWnd, nIDEvent: LongWord): LongWord; 
    external '[email protected] stdcall'; 

function WrapTimerProcUninstall(Callback: TTimerProc; ParamCount: Integer): LongWord; 
    external '[email protected]{%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.


Для другого подхода к проблеме см. Changing uninstall confirmation prompt.

 Смежные вопросы

  • Нет связанных вопросов^_^