2009-10-27 11 views
7

Korzystam z doskonałego instalatora Inno Setup i zauważam, że niektóre aplikacje (często z Microsoft) są instalowane z ikoną uruchamiania, która jest już bardzo widoczna ("przypięta?") W menu startowym (w systemie Windows 7). Czy jestem całkowicie uzależniony od ostatnio używanego algorytmu, aby moja ikona była "duża" w menu startowym, czy jest jakiś sposób na promowanie mojej aplikacji z instalatora?Czy możliwe jest "Przypnij do menu startowego" za pomocą Inno Setup?

Odpowiedz

6

Jest powód jest no programmatic way rzeczy przypiąć do paska zadań/menu start. Z mojego doświadczenia wynika, że ​​widziałem menu startowe highlight newly-created shortcuts, które zaprojektowano tak, aby obsługiwać dokładnie tę sytuację. Gdy pojawi się nowo zainstalowany program w menu startowym, jest to prawdopodobnie spowodowane tym algorytmem, a nie dlatego, że instalator umieścił go w tym menu.

Powiedział, że jeśli nowy skrót robi nie zostaną podświetlone, to może być, ponieważ instalator wypakowuje wcześniej istniejącego skrótu i ​​zachowuje starą znacznik czasu na nim, a nie przy użyciu funkcji API do tworzenia skrótów w menu startowe.

6

Możliwe jest przypinanie programów, ale nie jest to oficjalnie. Na podstawie kodu zamieszczonych w this thread (który wykorzystuje ten sam sposób, jak opisano w artykule połączonych @Mark Redman) Napisałem następujący:

[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; 

Powyższy kod najpierw odczytuje podpis pozycji menu lub do przypinania odpinanie aplikacji z tabeli ciągów biblioteki Shell32.dll. Następnie łączy się ze skorupą systemu Windows i docelową aplikacją. Ścieżka tworzy obiekt Folder, a następnie uzyskuje obiekt FolderItem i na tym obiekcie iteruje wszystkie dostępne czasowniki i sprawdza, czy ich nazwa jest zgodna z tą odczytaną z tabeli ciągów biblioteki bibliotecznej . Jeśli tak, wywołuje działanie elementu czasownika, wywołując metodę DoIt i zamyka tę iterację.

Tutaj jest możliwe korzystanie z powyższym kodem, na przypinanie:

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); 

I odpiąć:

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); 

Należy pamiętać, że chociaż ten kod działa na Windows 7 (i paska zadań pinningu również w systemie Windows 8.1, gdzie testowałem), jest to naprawdę hacky, ponieważ nie ma oficjalnego sposobu programowego przypinania programów do paska zadań, ani uruchamiania menu. To właśnie użytkownicy powinni robić według własnego wyboru.

+1

OMG, ile godzin próbowałeś to rozgryźć? Dziękuję bardzo! – tmighty

+0

@tmighty, cieszę się, że pomogło komuś! Zajęło mi to mniej niż godzinę; to tylko refaktoryzowany kod z połączonego wątku :-) – TLama

+0

Dziękuję! :-) Czy możesz mi podać preferowany sposób wykonywania kodu? Mam na myśli "if PinAppTo (ExpandConstant ('{sys} \ calc.exe'), pdTaskbar), a następnie ...". Gdzie to robisz? Czy definiujesz to jako zadanie, czy też wykonujesz ten kod automatycznie? Nigdy wcześniej nie uruchamiałem kodu z wyjątkiem instalacji środowiska uruchomieniowego vcredist_x86, które uruchomiłem przy użyciu polecenia [Uruchom] "Nazwa pliku:" {tmp} \ vcredist_x86.exe "; Parametry:"/q "; Sprawdź: VCRedistNeedsInstall. To był tylko exe, który musiał biec, a nie jak twoja. – tmighty

Powiązane problemy