Можно ли «закрепить в меню« Пуск »» с помощью Inno Setup?

Я использую отличный установщик Inno Setup и замечаю, что некоторые приложения (часто от Microsoft) устанавливаются со значком запуска, который уже хорошо виден («закреплен?») В меню «Пуск» (в Windows 7). Полностью ли я полагаюсь на последний использованный алгоритм, чтобы мой значок был «большим» в меню «Пуск», или есть способ продвинуть мое приложение с помощью установщика, пожалуйста?


person Brian Frost    schedule 27.10.2009    source источник


Ответы (3)


Прикреплять программы можно, но не официально. На основе кода, опубликованного в _ 1_ (который использует тот же способ, что и описанный в статье, на которую ссылается @Mark Redman) Я написал следующее:

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

Приведенный выше код сначала считывает заголовок пункта меню для закрепления или открепления приложений из таблицы строк библиотеки Shell32.dll. Затем подключается к оболочке Windows и к целевому приложению. path создает Folder объект, затем получает _5 _ и для этого объекта выполняет итерацию всех доступных глаголов и проверяет, совпадает ли их имя с именем, прочитанным из таблицы строк библиотеки Shell32.dll. Если это так, он вызывает действие элемента команды, вызывая _ 7_ и завершает итерацию.

Вот возможное использование приведенного выше кода для закрепления:

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

И для открепления:

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

Обратите внимание, что хотя этот код работает в Windows 7 (и закрепление панели задач также в Windows 8.1, где я его тестировал), это действительно хакерский способ, поскольку не существует официального способа программно закрепить программы на панели задач или в меню «Пуск». Это то, что пользователи должны делать по собственному выбору.

person TLama    schedule 31.07.2014
comment
OMG, сколько часов ты пытался это понять? Большое спасибо! - person tmighty; 04.02.2015
comment
@tmighty, я рад, что это кому-то помогло! И это заняло у меня меньше часа; это просто отредактированный код из связанного потока :-) - person TLama; 04.02.2015
comment
Спасибо! :-) Можете ли вы сказать мне, какой способ выполнения кода вам больше нравится? Я имею в виду, если PinAppTo (ExpandConstant ('{sys} \ calc.exe'), pdTaskbar), то .... Где вы это делаете? Вы определяете это как задачу или выполняете этот код автоматически? Я никогда раньше не запускал код, за исключением установки среды выполнения vcredist_x86, которую я запускал, используя [Выполнить] Имя файла: {tmp} \ vcredist_x86.exe; Параметры: / q; Проверьте: VCRedistNeedsInstall. Это был просто исполняемый файл, который мне пришлось запустить, а не функцию, подобную вашей. - person tmighty; 04.02.2015
comment
@tmighty, меня никогда не просили развернуть приложение, которое бы где-то закрепилось. Это в первую очередь то, что пользователи должны делать сами. Но если бы было такое требование, я думаю, что задача была бы достаточно справедливой (поскольку задачи обычно используются для подтверждения создания значков). Для выполнения I would use post install step. - person TLama; 04.02.2015
comment
Удивительный! Прикрепление моего приложения к начальному меню работает. Прикрепить его к панели задач пока не получается, но моей главной целью было меню «Пуск». Большое вам спасибо еще раз! Я постараюсь разобраться, что не так при добавлении моего приложения на панель задач. - person tmighty; 04.02.2015
comment
Панель задач тоже работала. Думаю, обновление заняло всего несколько минут. Большое спасибо! - person tmighty; 04.02.2015
comment
В Windows 7 и Window 8 он отлично работает. Однако в Windows XP я получаю сообщение об ошибке Variant is null, не могу вызвать. Ты хоть представляешь, как это исправить? - person tmighty; 05.02.2015
comment
@tmighty, вполне возможно, что в Windows XP эти имена команд хранятся в разных индексах ресурсов в библиотеке shell32.dll. Вы можете найти эти имена, если откроете (копию) библиотеки shell32.dll в каком-либо редакторе ресурсов и найдете в его таблице строковых ресурсов элемент, который соответствует элементу всплывающего меню, используемому для закрепления приложения в меню «Пуск» (конечно, есть нет для закрепления панели задач, так как это было добавлено в Vista). - person TLama; 05.02.2015
comment
Я новичок в использовании кода в Inno Setup. Как вы думаете, можно ли отредактировать свой код, чтобы я мог видеть, как пропустить закрепление панели задач для Windows до Vista? - person tmighty; 05.02.2015
comment
@tmighty, вы можете использовать this helper function. Он возвращает True, если вы используете Windows Vista или выше, в противном случае - False. - person TLama; 05.02.2015
comment
В 64-битной Windows 8.1 с Media Center это не работает. Вы случайно уже узнали, как это сделать на этой ОС? - person tmighty; 09.03.2015
comment
Я исследовал, и строку Pin to «Start» нельзя найти в Windows 8.1 с MediaCenter в user32.dll, kernel32.dll или shell32.dll. Хмммм. Понятия не имею, где еще это можно найти. - person tmighty; 10.03.2015
comment
@tmighty, боюсь, здесь я ничем не могу помочь. Мне сложно сказать, что даже если вы найдете этот пункт меню, там будут те же службы Windows Shell, что и в классических настольных версиях. - person TLama; 10.03.2015
comment
@TLama, как я могу закрепить на панели задач с аргументом? Изменить: я пробовал без аргументов сейчас, и на последней странице установщика он не может закрепить в Windows 10. Список глаголов не содержит ничего о закреплении на панели задач. Но у него есть булавка для запуска, которая мне не нужна. - person Jaex; 12.10.2015

Есть причина, по которой нет программного способа для закрепления чего-либо на панель задач / меню «Пуск». По своему опыту я видел, как в меню «Пуск» выделяются только что созданные ярлыки, и они предназначены именно для этой ситуации. Когда вы видите, что недавно установленная программа отображается в меню «Пуск», это, вероятно, связано с этим алгоритмом, а не потому, что установщик поместил ее туда.

Тем не менее, если новый ярлык не выделяется, это может быть связано с тем, что установщик извлекает уже существующий ярлык и сохраняет на нем старую метку времени, а не использует функцию API для создания ярлыка в стартовое меню.

person Josh Lee    schedule 27.10.2009

Взгляните на: http://blogs.technet.com/deploymentguys/archive/2009/04/08/pin-items-to-the-start-menu-or-windows-7-taskbar-via-script.aspx

person Mark Redman    schedule 27.10.2009
comment
и, как отмечалось в этой статье, есть причина, по которой не существует API для прямого закрепления. Пожалуйста, не спамите рабочий стол / панель задач / стартовое меню и т. Д. - person Jim Deville; 27.10.2009