使用Inno Setup从任务栏,开始菜单中取消固定应用程序 [英] Unpin app from taskbar, startmenu using Inno Setup

查看:88
本文介绍了使用Inno Setup从任务栏,开始菜单中取消固定应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用面向XP,Win7、8的Inno Setup开发安装程序.我需要将应用程序图标固定在任务栏和开始菜单上.到目前为止,我已经能够做到这一点.

I am developing an installer using Inno Setup targeting XP, Win7, 8. I need the app icon to be pinned to taskbar and the startmenu. So far I have been able to do that.

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

Now, when the user uninstalls this program, the pinned items should be unpinned. I haven't managed to find a solution to this.

请指导.

推荐答案

您已经说过,您使用了

You've said that you have used a function from this link. I assume the one from this post:

procedure zylPinAppToTaskbar(strPath, strApp: string);  
var  
  vShell, vFolder, vFolderItem, vItemVerbs: Variant;  
  vPath, vApp: Variant;
  i: Integer;
  sItem: String;
  h: LongInt;
  szPinName: String;
  filenameEnd : Integer;
  filename    : String;
  strEnd    : String;
begin 
  SetLength(szPinName, 255);
  h := LoadLibrary(ExpandConstant('{sys}\Shell32.dll'));
  LoadString(h, 5386, szPinName, 255);
  FreeLibrary(h);
  strEnd := #0;
  filenameEnd := Pos(strEnd, szPinName);
  filename := Copy(szPinName, 1, filenameEnd - 1);
  if (Length(filename) > 0) then  //WinXp or lower, no pin taskbar function
  begin
    vShell := CreateOleObject('Shell.Application');
    vPath := strPath;
    vFolder := vShell.NameSpace(vPath);
    vApp := strApp;
    vFolderItem := vFolder.ParseName(vApp);
    vItemVerbs := vFolderItem.Verbs;

  for i := 1 to vItemVerbs.Count do
  begin
    sItem := vItemVerbs.Item(i).Name;

    if (sItem = filename) then
    begin
      // 63 63 72 75 6E 2E 63 6F 6D
      vItemVerbs.Item(i).DoIt;
      break;
     end;
    end;
  end;
end;

那真的是很古怪的方式(我不会依赖).现在让我们集中讨论它的实际作用.该函数加载Shell32.dll库,并从其字符串表中读取属于将此程序插入任务栏功能的弹出菜单项的标题(并将其存储到filename变量中).然后,它连接到Shell并创建传递的文件夹路径的Folder 对象(vFolder变量).然后,为该文件夹对象创建 FolderItem 对象(vFolderItem变量),并在此对象上迭代所有可用动词(vItemVerbs变量),并检查Name是否与从Shell32.dll库中读取的一个相匹配.如果找到一个,它将通过

That's really hacky way (which I wouldn't rely on). Let's focus now on what it actually does. The function loads the Shell32.dll library and reads from its string table the caption of the popup menu item that belongs to the Pin this program to taskbar feature (and stores it into the filename variable). Then it connects to Shell and creates the Folder object for the passed folder path (vFolder variable). For this folder object it then creates the FolderItem object (vFolderItem variable) and on this object iterates all the available verbs (vItemVerbs variable) and checks if the Name matches the one read from the Shell32.dll library. If it finds one, it invokes the action by the DoIt method and breaks the iteration.

现在,如果您知道上述代码的作用,则可以猜测执行取消固定操作所需要做的唯一一件事就是找到该功能的弹出菜单项的标题.我已经查看了Shell32.dll库的字符串表,并且从任务栏取消固定此程序字符串的ID为5387,因此,修改上述功能以取消固定的唯一操作就是更改此行: /p>

Now if you know what the above code does, you can guess that the only thing you need to do to perform the unpin action is finding the caption of the popup menu item for that feature. I've looked into the string table of the Shell32.dll library and the Unpin this program from taskbar string has ID 5387, so the only thing to modify the above function for unpinning is changing this line:

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

但是我不建议这样做.没有将程序固定到任务栏的官方方法,因为这是保留给用户决定的.

But I do not recommend that way. There is no official way to pin program to taskbar because that's been reserved for the user to decide.

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

As a bonus, I wrote the following wrapper for the above code:

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

这篇关于使用Inno Setup从任务栏,开始菜单中取消固定应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆