2009-10-27 20 views
7

Estoy usando el excelente instalador Inno Setup y veo que algunas aplicaciones (a menudo de Microsoft) se instalan con su icono de inicio ya muy visible ('¿anclado?') En el menú de inicio (en Windows 7). ¿Debo confiar totalmente en el algoritmo utilizado más recientemente para que mi ícono sea "grande" en el menú de inicio, o hay alguna forma de promocionar mi aplicación desde el instalador, por favor?¿Es posible 'Pin para iniciar el menú' usando Inno Setup?

Respuesta

6

Hay una razón que hay no programmatic way al pin cosas a la barra de tareas/menú de inicio. En mi experiencia, he visto el menú de inicio highlight newly-created shortcuts, y está diseñado para manejar exactamente esta situación. Cuando ve un programa recién instalado aparecer en el menú de inicio, es probablemente debido a ese algoritmo y no porque el instalador lo colocó allí.

Dicho esto, si un nuevo acceso directo hace no aparecerá resaltada, puede ser debido a que el instalador extrae un pre-existente de acceso directo y conserva una vieja marca de tiempo en él, en lugar de utilizar la función de API para crear un acceso directo en el menu de inicio.

6

Es posible fijar programas, pero no oficialmente. Sobre la base de un código escrito en this thread (que utiliza de la misma manera como se describe en el artículo enlazado por @ Marcos Redman) escribí lo siguiente:

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

El código anterior primero lee el título del elemento de menú para fijar o Desenredando las aplicaciones de la tabla de cadenas de la biblioteca Shell32.dll. Luego se conecta al Shell de Windows y a la aplicación de destino. ruta crea el objeto Folder, luego obtiene el objeto FolderItem y en este objeto itera todos los verbos disponibles y comprueba si su nombre coincide con la lectura de la tabla de cadena de la biblioteca Shell32.dll. Si es así, invoca la acción del elemento verbal llamando al método DoIt y sale de la iteración.

Aquí es posible el uso del código de arriba, para fijar:

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

Y para desclavar:

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

Tenga en cuenta que a pesar de que este código funciona en Windows 7 (y la fijación barra de tareas también en Windows 8.1, donde lo he probado), es muy raro, ya que no hay forma oficial de fijar programas a la barra de tareas, ni iniciar el menú. Eso es lo que los usuarios deberían hacer por su propia elección.

+1

Dios mío, ¿cuántas horas trataste de resolver eso? Muchas gracias! – tmighty

+0

@tmighty, ¡me alegra que haya ayudado a alguien! Y me llevó menos de una hora; es solo un código refactorizado del hilo enlazado :-) – TLama

+0

¡Gracias! :-) ¿Puede decirme su forma preferida de ejecutar su código? Me refiero a "si PinAppTo (ExpandConstant ('{sys} \ calc.exe'), pdTaskbar) entonces ...". ¿Dónde haces eso? ¿Lo defines como una tarea o ejecutas este código automáticamente? Nunca ejecuté un código antes, excepto para instalar los runtimes vcredist_x86 que ejecuté usando [Ejecutar] "Nombre de archivo:" {tmp} \ vcredist_x86.exe "; Parámetros:"/q "; Verificar: VCRedistNeedsInstall. Esto fue solo un exe que tuvo que funcionar, no una función como la suya. – tmighty

Cuestiones relacionadas