Scripting 有没有可能';锁定开始菜单';使用Inno设置?

Scripting 有没有可能';锁定开始菜单';使用Inno设置?,scripting,windows-7,installation,inno-setup,startmenu,Scripting,Windows 7,Installation,Inno Setup,Startmenu,我使用的是优秀的Inno安装程序,我注意到一些应用程序(通常来自Microsoft)在安装时,其启动图标在“开始”菜单(在Windows 7中)中已经高度可见(“锁定”)。我是否完全依赖于最新使用的算法,使我的图标在“开始”菜单中显示为“大”,还是有办法从安装程序中升级我的应用程序?请看一看:将内容固定到任务栏/开始菜单是有原因的。根据我的经验,我见过“开始”菜单,它的设计正是为了处理这种情况。当您看到一个新安装的程序出现在“开始”菜单上时,可能是因为该算法,而不是因为安装程序将其放置在那里 也

我使用的是优秀的Inno安装程序,我注意到一些应用程序(通常来自Microsoft)在安装时,其启动图标在“开始”菜单(在Windows 7中)中已经高度可见(“锁定”)。我是否完全依赖于最新使用的算法,使我的图标在“开始”菜单中显示为“大”,还是有办法从安装程序中升级我的应用程序?

请看一看:

将内容固定到任务栏/开始菜单是有原因的。根据我的经验,我见过“开始”菜单,它的设计正是为了处理这种情况。当您看到一个新安装的程序出现在“开始”菜单上时,可能是因为该算法,而不是因为安装程序将其放置在那里


也就是说,如果新的快捷方式没有突出显示,可能是因为安装程序提取了一个预先存在的快捷方式,并在其上保留了一个旧的时间戳,而不是使用API函数在“开始”菜单中创建快捷方式。

可以锁定程序,但不能正式锁定程序。基于在中发布的代码(使用与@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 'FreeLibrary@kernel32.dll 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;
对于取消钉扎:

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

请注意,尽管这段代码在Windows7上运行(在我测试过的Windows8.1上也可以使用任务栏锁定),但它确实是一种黑客方式,因为没有正式的方式通过编程将程序锁定到任务栏,也没有开始菜单。这是用户自己选择应该做的。

正如那篇文章中所指出的,没有用于直接固定的API是有原因的。请不要在桌面/taskbar/startmenu/etc.OMG上发垃圾邮件,你花了多少小时才弄明白?非常感谢你@今晚,我很高兴它帮助了别人!我花了不到一个小时;这只是链接线程中的重构代码:-)谢谢!:-)你能告诉我你执行代码的首选方式吗?我指的是“if PinAppTo(ExpandConstant({sys}\calc.exe'),pdTaskbar),然后…”。你在哪里做的?您是将其定义为任务还是自动执行此代码?我以前从未运行过代码,除了安装vcredit_x86运行时,我使用[Run]”文件名:“{tmp}\vcredit_x86.exe”;参数:“/q"; 检查:VCRedistNeedsInstall。这只是一个我必须运行的exe,而不是像你这样的函数。@t天哪,我从来没有被要求部署一个会将自己固定在某个地方的应用程序。这是用户首先应该自己做的事情。但如果有这样的要求,我认为任务就足够公平了(因为任务通常用于确认创建图标)。对于执行@tmighty,您可以使用。如果运行的是Windows Vista或更高版本,则返回True,否则返回False。
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);