是否可以使用 Inno Setup 来“固定到开始菜单"? [英] Is it possible to 'Pin to start menu' using Inno Setup?
问题描述
我正在使用出色的 Inno Setup 安装程序,我注意到某些应用程序(通常来自 Microsoft)在安装时其启动图标在开始菜单(在 Windows 7 中)中已经非常明显(固定?").我是完全依赖最近使用的算法来使开始菜单中的图标变大,还是有办法从安装程序中推广我的应用程序?
I'm using the excellent Inno Setup installer and I notice that some Applications (often from Microsoft) get installed with their launch icon already highly visible ('pinned?') in the start menu (in Windows 7). Am I totally reliant on the most-recently-used algorithm for my icon to be 'large' in the start menu, or is there a way of promoting my application from the installer please?
推荐答案
可以固定程序,但不是正式的.基于 this thread
(使用与@Mark Redman链接的文章中描述的方式相同的方式)我写了以下内容:
It is possible to pin programs, but not officially. Based on a code posted in this thread
(which uses the same way as described in the article linked by @Mark Redman) I wrote the following:
[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;
上述代码首先从Shell32.dll
库的字符串表中读取用于固定或取消固定应用程序的菜单项的标题.然后连接到 Windows Shell,并连接到目标应用程序.路径创建文件夹
对象,然后获取 FolderItem
对象并在此对象上迭代所有可用动词并检查它们的名称是否与从 Shell32.dll
库字符串中读取的名称匹配桌子.如果是这样,它会通过调用 DoIt
方法并退出迭代.
The above code first reads the caption of the menu item for pinning or unpinning applications from the string table of the Shell32.dll
library. Then connects to the Windows Shell, and for the target app. path creates the Folder
object, then obtains the FolderItem
object and on this object iterates all the available verbs and checks if their name matches to the one read from the Shell32.dll
library string table. If so, it invokes the verb item action by calling the DoIt
method and exits the iteration.
以下是上述代码的可能用法,用于固定:
Here is a possible usage of the above code, for pinning:
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),但它确实是一种hacky 方式,因为没有官方方法以编程方式将程序固定到任务栏,也没有开始菜单.这是用户应该自己选择的.
Please note that even though this code works on Windows 7 (and taskbar pinning also on Windows 8.1 where I've tested it), it is really hacky way, since there is no official way to programatically pin programs to taskbar, nor start menu. That's what the users should do by their own choice.
这篇关于是否可以使用 Inno Setup 来“固定到开始菜单"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!