使用Inno Setup从任务栏,开始菜单中取消固定应用程序 [英] Unpin app from taskbar, startmenu using 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.
请指导.
推荐答案
您已经说过,您使用了 this post
:
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屋!