2009-10-27 16 views
7

Sto utilizzando l'ottimo programma di installazione di Inno Setup e noto che alcune applicazioni (spesso di Microsoft) vengono installate con l'icona di avvio già altamente visibile ("appuntata?") Nel menu di avvio (in Windows 7). Sono totalmente dipendente dall'algoritmo usato di recente per far sì che la mia icona sia "grande" nel menu di avvio, oppure esiste un modo per promuovere la mia applicazione dall'installatore, per favore?E 'possibile "Pin to start menu" usando Inno Setup?

risposta

6

C'è un motivo c'è no programmatic way al pin cose alla barra delle applicazioni/menu di avvio. Nella mia esperienza, ho visto il menu di avvio highlight newly-created shortcuts, ed è progettato per gestire esattamente questa situazione. Quando vedi un programma appena installato comparire nel menu di avvio, è probabilmente a causa dell'algoritmo e non perché l'installatore lo ha collocato lì.

Detto, se un nuovo collegamento non non apparirà evidenziato, è possibile che il programma di installazione estrae una preesistente collegamento e conserva una vecchia timestamp su di esso, piuttosto che utilizzare la funzione API per creare un collegamento nella menu iniziale.

6

È possibile aggiungere programmi, ma non ufficialmente. Sulla base di un codice scritto in this thread (che utilizza allo stesso modo come descritto nell'articolo collegato da @ Mark Redman) Ho scritto il seguente:

[Code] 
#ifdef UNICODE 
    #define AW "W" 
#else 
    #define AW "A" 
#endif 

const 
    // these constants are not defined in Windows 
    SHELL32_STRING_ID_PIN_TO_TASKBAR = 5386; 
    SHELL32_STRING_ID_PIN_TO_STARTMENU = 5381; 
    SHELL32_STRING_ID_UNPIN_FROM_TASKBAR = 5387; 
    SHELL32_STRING_ID_UNPIN_FROM_STARTMENU = 5382; 

type 
    HINSTANCE = THandle; 
    HMODULE = HINSTANCE; 

    TPinDest = (
    pdTaskbar, 
    pdStartMenu 
); 

function LoadLibrary(lpFileName: string): HMODULE; 
    external 'LoadLibrary{#AW}@kernel32.dll stdcall'; 
function FreeLibrary(hModule: HMODULE): BOOL; 
    external '[email protected] stdcall'; 
function LoadString(hInstance: HINSTANCE; uID: UINT; 
    lpBuffer: string; nBufferMax: Integer): Integer; 
    external 'LoadString{#AW}@user32.dll stdcall'; 

function TryGetVerbName(ID: UINT; out VerbName: string): Boolean; 
var 
    Buffer: string; 
    BufLen: Integer; 
    Handle: HMODULE; 
begin 
    Result := False; 

    Handle := LoadLibrary(ExpandConstant('{sys}\Shell32.dll')); 
    if Handle <> 0 then 
    try 
    SetLength(Buffer, 255); 
    BufLen := LoadString(Handle, ID, Buffer, Length(Buffer)); 

    if BufLen <> 0 then 
    begin 
     Result := True; 
     VerbName := Copy(Buffer, 1, BufLen); 
    end; 
    finally 
    FreeLibrary(Handle); 
    end; 
end; 

function ExecVerb(const FileName, VerbName: string): Boolean; 
var 
    I: Integer; 
    Shell: Variant; 
    Folder: Variant; 
    FolderItem: Variant; 
begin 
    Result := False; 

    Shell := CreateOleObject('Shell.Application'); 
    Folder := Shell.NameSpace(ExtractFilePath(FileName)); 
    FolderItem := Folder.ParseName(ExtractFileName(FileName)); 

    for I := 1 to FolderItem.Verbs.Count do 
    begin 
    if FolderItem.Verbs.Item(I).Name = VerbName then 
    begin 
     FolderItem.Verbs.Item(I).DoIt; 
     Result := True; 
     Exit; 
    end; 
    end; 
end; 

function PinAppTo(const FileName: string; PinDest: TPinDest): Boolean; 
var 
    ResStrID: UINT; 
    VerbName: string; 
begin 
    case PinDest of 
    pdTaskbar: ResStrID := SHELL32_STRING_ID_PIN_TO_TASKBAR; 
    pdStartMenu: ResStrID := SHELL32_STRING_ID_PIN_TO_STARTMENU; 
    end; 
    Result := TryGetVerbName(ResStrID, VerbName) and ExecVerb(FileName, VerbName); 
end; 

function UnpinAppFrom(const FileName: string; PinDest: TPinDest): Boolean; 
var 
    ResStrID: UINT; 
    VerbName: string; 
begin 
    case PinDest of 
    pdTaskbar: ResStrID := SHELL32_STRING_ID_UNPIN_FROM_TASKBAR; 
    pdStartMenu: ResStrID := SHELL32_STRING_ID_UNPIN_FROM_STARTMENU; 
    end; 
    Result := TryGetVerbName(ResStrID, VerbName) and ExecVerb(FileName, VerbName); 
end; 

Il codice di cui sopra si legge prima la didascalia della voce di menu per pinning o sbloccare le applicazioni dalla tabella di stringhe della libreria Shell32.dll. Quindi si connette alla shell di Windows e all'app di destinazione. percorso crea l'oggetto Folder, quindi ottiene l'oggetto FolderItem e su questo oggetto esegue l'iterazione di tutti i verbi disponibili e controlla se il loro nome corrisponde a quello letto dalla tabella di stringhe libreria Shell32.dll. In tal caso, invoca l'azione dell'elemento verbo chiamando il metodo DoIt ed esce dall'iterazione.

Ecco un possibile utilizzo del codice di cui sopra, per appuntare:

if PinAppTo(ExpandConstant('{sys}\calc.exe'), pdTaskbar) then 
    MsgBox('Calc has been pinned to the taskbar.', mbInformation, MB_OK); 
if PinAppTo(ExpandConstant('{sys}\calc.exe'), pdStartMenu) then 
    MsgBox('Calc has been pinned to the start menu.', mbInformation, MB_OK); 

E per unpinning:

if UnpinAppFrom(ExpandConstant('{sys}\calc.exe'), pdTaskbar) then 
    MsgBox('Calc is not pinned to the taskbar anymore.', mbInformation, MB_OK); 
if UnpinAppFrom(ExpandConstant('{sys}\calc.exe'), pdStartMenu) then 
    MsgBox('Calc is not pinned to the start menu anymore.', mbInformation, MB_OK); 

Si prega di notare che, anche se questo codice funziona su Windows 7 (e pinning barra delle applicazioni anche su Windows 8.1 dove l'ho testato), è davvero un modo hacky, dal momento che non esiste un modo ufficiale per programmare i programmi sulla barra delle applicazioni, né avviare il menu. Questo è ciò che gli utenti dovrebbero fare di loro scelta.

+1

OMG, quante ore hai provato a capirlo? Grazie mille! – tmighty

+0

@tmighty, sono contento che abbia aiutato qualcuno! E mi ci è voluto meno di un'ora; è solo un codice refactored dal thread collegato :-) – TLama

+0

Grazie! :-) Puoi dirmi il tuo modo preferito di eseguire il tuo codice? Intendo "se PinAppTo (ExpandConstant ('{sys} \ calc.exe'), pdTaskbar) quindi ...". Dove lo fai? Lo definisci come un'attività o esegui questo codice automaticamente? Non ho mai eseguito un codice prima di aver installato i runtime di vcredist_x86 che ho eseguito usando [Esegui] "Nome file:" {tmp} \ vcredist_x86.exe "; Parametri:"/q "; Verifica: VCRedistNeedsInstall. Questo era solo un exe dovevo eseguire, non una funzione come la tua. – tmighty

Problemi correlati