Inno setup 使用Inno设置从任务栏、开始菜单取消应用程序的登录

Inno setup 使用Inno设置从任务栏、开始菜单取消应用程序的登录,inno-setup,Inno Setup,我正在使用Inno安装程序开发一个安装程序,目标是XP、Win7、8。我需要将应用程序图标固定到任务栏和startmenu。到目前为止,我已经能够做到这一点 现在,当用户卸载此程序时,锁定的项目应该取消锁定。我还没有找到解决这个问题的办法 请指导。您说过您使用了来自的函数。我从以下方面假设: 这真是一种令人讨厌的方式(我不相信)。现在让我们关注它的实际功能。该函数加载Shell32.dll库,并从其字符串表中读取属于将此程序锁定到任务栏功能的弹出菜单项的标题(并将其存储到filename变量中)

我正在使用Inno安装程序开发一个安装程序,目标是XP、Win7、8。我需要将应用程序图标固定到任务栏和startmenu。到目前为止,我已经能够做到这一点

现在,当用户卸载此程序时,锁定的项目应该取消锁定。我还没有找到解决这个问题的办法


请指导。

您说过您使用了来自的函数。我从以下方面假设:

这真是一种令人讨厌的方式(我不相信)。现在让我们关注它的实际功能。该函数加载
Shell32.dll
库,并从其字符串表中读取属于将此程序锁定到任务栏功能的弹出菜单项的标题(并将其存储到
filename
变量中)。然后它连接到Shell并为传递的文件夹路径(
vFolder
variable)创建对象。对于此文件夹对象,它随后创建对象(
vFolderItem
变量),并在此对象上迭代所有可用动词(
vItemVerbs
变量),并检查
名称是否与从
Shell32.dll
库读取的名称匹配。如果找到一个,它将通过方法调用操作并中断迭代

现在,如果您知道上面的代码是做什么的,那么您可以猜到执行unpin操作所需要做的唯一事情就是查找该功能的弹出菜单项的标题。我已经查看了
Shell32.dll
库的字符串表,并且从任务栏字符串中取消绑定此程序的ID为5387,因此修改上述取消绑定函数的唯一方法是更改此行:

// this magical 5386 value is the ID of the "Pin this program to taskbar"
// popup menu caption string in the Shell32.dll string table
LoadString(h, 5386, szPinName, 255);
为此:

// this magical 5387 value is the ID of the "Unpin this program from taskbar"
// popup menu caption string in the Shell32.dll string table
LoadString(h, 5387, szPinName, 255);
但我不建议这样做。并没有官方的方法将程序固定到任务栏上,因为这是留给用户决定的


作为奖励,我为上述代码编写了以下包装:

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

我能做到。下面是从startmenu和任务栏锁定和取消锁定的代码

oShell := CreateOleObject('Shell.Application');
objFolder := oShell.Namespace(ExpandConstant('{localappdata}\My_Path'));
objFolderItem := objFolder.ParseName('MyApp.exe');
colVerbs := objFolderItem.Verbs();
for i := 0 to colverbs.count() do
begin
   VerbName := lowercase(colverbs.item(i).name);
   StringChangeEx(VerbName,'&','',true);
   if (CompareText(Verbname, 'Pin to Start Menu') = 0) then
     colverbs.item(i).DoIt
   if (CompareText(Verbname, 'Pin to Taskbar') = 0) then
     colverbs.item(i).DoIt
end;

取消装订时,将比较字符串更改为“从开始菜单取消装订”和“从任务栏取消装订”。

您说过可以将图标固定到任务栏和开始菜单上。怎样?我要求建议一个相应的反向行动。除此之外,据我所知,你不能用编程的方式固定图标,所以你所说的对我来说是相当令人惊讶的…我用这个作为参考。谢谢你的解释!这是真的需要。:)这在非英语窗口上不起作用。例如,在我的系统中,那些菜单项被称为“Připnout na hlavnípanel”和“Připnout k nabídce Start”。正如你所看到的,它们都不符合你的模式。从Shell32.dll字符串表中读取这些标题在代码中占有一席之地。您是对的。。我很高兴它能运行,我迫不及待地想发布它PSo我实际上破坏了你的情绪。作为对这一点的补偿,我为您编写了更多的通用代码:-)也非常感谢您提供的通用代码!!不,我的心情没有被破坏。。我看到了你的答案,也看到了我(新手)的答案。。。我对自己感到很开心…!!::)@TLama在Windows 8.1的某些版本中,字符串似乎不再位于Shell32.exe中。我不知道他们现在到底在哪里。
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);
oShell := CreateOleObject('Shell.Application');
objFolder := oShell.Namespace(ExpandConstant('{localappdata}\My_Path'));
objFolderItem := objFolder.ParseName('MyApp.exe');
colVerbs := objFolderItem.Verbs();
for i := 0 to colverbs.count() do
begin
   VerbName := lowercase(colverbs.item(i).name);
   StringChangeEx(VerbName,'&','',true);
   if (CompareText(Verbname, 'Pin to Start Menu') = 0) then
     colverbs.item(i).DoIt
   if (CompareText(Verbname, 'Pin to Taskbar') = 0) then
     colverbs.item(i).DoIt
end;