I think the biggest missing feature in Inno Setup right now is the ability to pin [Icons] to the Taskbar. Does anyone have a good Windows 10 compatible example until this functionality is added natively?
constCLSID_TaskbandPin = '{90AA3A4E-1CBA-4233-B8BB-535773D48449}'; IID_IPinnedList2 = '{BBD20037-BC0E-42F1-913F-E2936BB0EA0C}'; IID_IPinnedList3 = '{0DD79AE2-D156-45D4-9EEB-3B549769E940}'; CLSCTX_INPROC_SERVER = 1; PLMC_EXPLORER = 4; S_OK = 0; type PItemIDList = LongWord; IPinnedList2 = interface(IUnknown) '{BBD20037-BC0E-42F1-913F-E2936BB0EA0C}' procedure EnumObjects; // dummy function Modify(unpin, pin: PItemIDList): HRESULT; procedure GetChangeCount; // dummy procedure GetPinnableInfo; // dummy procedure IsPinnable; // dummy procedure Resolve; // dummy function IsPinned(pidl: PItemIDList): HRESULT; procedure GetPinnedItem; // dummy procedure GetPinnedItemForAppID; // dummy procedure ItemChangeNotify; // dummy procedure UpdateForRemovedItemsAsNecessary; // dummy end; IPinnedList3 = interface(IUnknown) '{0DD79AE2-D156-45D4-9EEB-3B549769E940}' procedure EnumObjects; // dummy procedure GetPinnableInfo; // dummy procedure IsPinnable; // dummy procedure Resolve; // dummy procedure LegacyModify; // dummy procedure GetChangeCount; // dummy function IsPinned(pidl: PItemIDList): HRESULT; procedure GetPinnedItem; // dummy procedure GetAppIDForPinnedItem; // dummy procedure ItemChangeNotify; // dummy procedure UpdateForRemovedItemsAsNecessary; // dummy procedure PinShellLink; // dummy procedure GetPinnedItemForAppID; // dummy function Modify(unpin, pin: PItemIDList; ModifyCaller: LongWord): HRESULT; end; function CoCreateInstance(rclsid: TCLSID; pUnkOuter: LongWord; dwClsContext: DWORD; riid: TIID; out ppv: IUnknown): HRESULT; external 'CoCreate...@ole32.dll stdcall'; function ILCreateFromPath(const pszPath: string): PItemIDList; external 'ILCreate...@shell32.dll stdcall'; procedure ILFree(pidl: PItemIDList); external 'ILF...@shell32.dll stdcall'; function PinToTaskbar(const AFilename: string; AIsPin: Boolean): Boolean; // AFilename : full path to executable file // AIsPin....: False - unpin from TaskBar, True - pin to TaskBar var LPIDL: PItemIDList; LUnk: IUnknown; LPinnedList2: IPinnedList2; LPinnedList3: IPinnedList3; LShellApp: Variant; LVerb: string; begin Result := False; if FileExists(AFilename) and (GetWindowsVersion > $06010000) then try LPIDL := ILCreateFromPath(AFilename); try { Windows 10 (build 1809) and above. } OleCheck(CoCreateInstance(StringToGUID(CLSID_TaskbandPin), 0, CLSCTX_INPROC_SERVER, StringToGUID(IID_IPinnedList3), LUnk)); LPinnedList3 := LUnk as IPinnedList3; except try { Windows 7, 8, 8.1 if IPinnedList2 supported. } OleCheck(CoCreateInstance(StringToGUID(CLSID_TaskbandPin), 0, CLSCTX_INPROC_SERVER, StringToGUID(IID_IPinnedList2), LUnk)); LPinnedList2 := LUnk as IPinnedList2; except { Windows 10 (build 1809) and below. } LShellApp := CreateOleObject('Shell.Application'); end; end; if AIsPin then // pin begin if LPinnedList3 <> nil then begin Result := LPinnedList3.IsPinned(LPIDL) <> S_OK; if Result then OleCheck(LPinnedList3.Modify(0, LPIDL, PLMC_EXPLORER)); end else if LPinnedList2 <> nil then begin Result := LPinnedList2.IsPinned(LPIDL) <> S_OK; if Result then OleCheck(LPinnedList2.Modify(0, LPIDL)); end else LVerb := 'taskbarpin'; end else // unpin begin if LPinnedList3 <> nil then begin Result := LPinnedList3.IsPinned(LPIDL) = S_OK; if Result then OleCheck(LPinnedList3.Modify(LPIDL, 0, PLMC_EXPLORER)); end else if LPinnedList2 <> nil then begin Result := LPinnedList2.IsPinned(LPIDL) = S_OK; if Result then OleCheck(LPinnedList2.Modify(LPIDL, 0)); end else LVerb := 'taskbarunpin'; end; if LVerb <> '' then LShellApp.Windows.Item.Document.Application .NameSpace(ExtractFileDir(AFilename)) .ParseName(ExtractFileName(AFilename)).InvokeVerb(LVerb); except Result := False; ShowExceptionMessage; finally ILFree(LPIDL); end;
end;
Hi El Sanchez,
Thank you very much I’ll give your example a try. I super love how there are three different ways to do it based on what version of Windows you’re running. Way to maintain a consistent platform Microsoft 😉.
Thanks,
Christian Blackburn, A+, Network+
Technician with Kelly OCG
From: inno...@googlegroups.com <inno...@googlegroups.com>
On Behalf Of El Sanchez
Sent: Wednesday, February 12, 2020 11:15 PM
To: innosetup <inno...@googlegroups.com>
Subject: Re: Pin to taskbar example needed that's compatible with Win10
среда, 15 января 2020 г., 0:40:04 UTC+3 пользователь christian...@intel.com написал:
--
You received this message because you are subscribed to a topic in the Google Groups "innosetup" group.
To unsubscribe from this topic, visit
https://groups.google.com/d/topic/innosetup/oskWRaFzV1I/unsubscribe.
To unsubscribe from this group and all its topics, send an email to
innosetup+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/innosetup/b8b24a4f-b3af-4fb3-aa81-3db1de855a1a%40googlegroups.com.
I would like to know if you don't have a similar code that allows you to fix it in the Start menu (Windows 10) using this same interface method?
function PinToStartMenu(const AFilename: string; AIsPin: Boolean): Boolean;// AFilename : full path to exe- or lnk-file// AIsPin : False - unpin from StartMenu, True - pin to StartMenuvar LShellApp, LFolderItem: Variant; LVerb, LnkName: string;begin Result := False; if not FileExists(AFilename) then Exit; try LShellApp := CreateOleObject('Shell.Application'); LFolderItem := LShellApp.Windows.Item.Document.Application .NameSpace(ExtractFileDir(AFilename)) .ParseName(ExtractFileName(AFilename)); { Below Windows 8. } if GetWindowsVersion < $06020000 then begin if AIsPin then LVerb := 'startpin' else LVerb := 'startunpin'; LFolderItem.InvokeVerb(LVerb); Result := True; end else { Windows 8 and above. } begin if not LFolderItem.IsLink then begin LnkName := LFolderItem.ExtendedProperty('FileDescription'); if LnkName = '' then LnkName := ExtractFileName(AFilename); LnkName := ExpandConstant('{commonprograms}\') + ChangeFileExt(LnkName, '.lnk'); if AIsPin then Result := not FileExists(LnkName) and FileExists(CreateShellLink(LnkName, '', AFilename, '', '', '', 0, SW_SHOWNORMAL)) else Result := DeleteFile(LnkName); end else begin LnkName := ExpandConstant('{commonprograms}\') + ExtractFileName(LFolderItem.Path); if AIsPin then Result := not FileExists(LnkName) and FileCopy(LFolderItem.Path, LnkName, False) else Result := DeleteFile(LnkName); end; end; except ShowExceptionMessage; end;end;--
You received this message because you are subscribed to the Google Groups "innosetup" group.
To unsubscribe from this group and stop receiving emails from it, send an email to innosetup+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/innosetup/c757b136-3c72-4835-a776-fde451ec70b5%40googlegroups.com.