FadeSoft Posted 3 hours ago Posted 3 hours ago I am trying to get this working but can't seem to get it or find a easier way about going about this. Attached picture for context. expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> ; ====== Define all necessary GUIDs ====== ; CLSIDs Global Const $CLSID_DestinationList = "{77f10cf0-3db5-4966-b520-b7c54fd35ed6}" Global Const $CLSID_EnumerableObjectCollection = "{2d3468c1-36a7-43b6-ac24-d3f02fd9607a}" Global Const $CLSID_ShellLink = "{00021401-0000-0000-C000-000000000046}" ; IIDs Global Const $IID_ICustomDestinationList = "{6332debf-87b5-4673-8ff5-7ca6a2ff46a8}" Global Const $IID_IObjectCollection = "{2d3468c1-36a7-43b6-ac24-d3f02fd9607a}" Global Const $IID_IObjectArray = "{92ca9dcd-5622-4bba-a805-5e9f541bd8c9}" Global Const $IID_IShellLinkW = "{000214F9-0000-0000-C000-000000000046}" Global Const $IID_IPropertyStore = "{886d8eeb-8cf2-4446-8d02-cdba1dbdcf99}" ; Property key for title Global Const $PKEY_Title_FMTID = "{F29F85E0-4FF9-1068-AB91-08002B27B3D9}" Global Const $PKEY_Title_PID = 2 ; AppUserModelID for our application Global Const $APPID = "AutoIt.JumpList.Example." & Random(1000, 9999, 1) ; Main GUI Global $hGUI = GUICreate("Jump List Example", 400, 300) GUICtrlCreateLabel("Right-click this application in the taskbar", 50, 120, 300, 30) GUICtrlSetFont(-1, 12) GUICtrlCreateLabel("Tasks: Notepad, Calculator, CMD", 50, 150, 300, 30) GUISetState(@SW_SHOW) ; Initialize COM DllCall("ole32.dll", "long", "CoInitialize", "ptr", 0) ; Set AppUserModelID for jump list _SetAppUserModelID() ; Create jump list _CreateJumpList() While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE ; Uninitialize COM DllCall("ole32.dll", "none", "CoUninitialize") Exit EndSwitch WEnd Func _SetAppUserModelID() ; Set the AppUserModelID for our process Local $aRet = DllCall("shell32.dll", "long", "SetCurrentProcessExplicitAppUserModelID", "wstr", $APPID) If @error Or $aRet[0] <> 0 Then ConsoleWrite("Warning: Failed to set AppUserModelID: " & Hex($aRet[0]) & @CRLF) Return False EndIf ConsoleWrite("AppUserModelID set to: " & $APPID & @CRLF) Return True EndFunc Func _CreateJumpList() ConsoleWrite("Creating jump list..." & @CRLF) ; Create destination list COM object Local $pDestList = 0 Local $aRet = DllCall("ole32.dll", "long", "CoCreateInstance", _ "ptr", _GUIDFromString($CLSID_DestinationList), _ "ptr", 0, _ "dword", 1, _ ; CLSCTX_INPROC_SERVER "ptr", _GUIDFromString($IID_ICustomDestinationList), _ "ptr*", 0) If @error Or $aRet[0] <> 0 Then ConsoleWrite("Failed to create DestinationList: 0x" & Hex($aRet[0], 8) & @CRLF) Return False EndIf Local $pDestList = $aRet[5] ConsoleWrite("DestinationList created at: 0x" & Hex($pDestList) & @CRLF) ; Get the vtable Local $pVTable = DllStructGetData(DllStructCreate("ptr", $pDestList), 1) ; Get BeginList method (vtable index 3) Local $pBeginList = DllStructGetData(DllStructCreate("ptr", $pVTable + 3*4), 1) ; Call BeginList Local $cMaxSlots = 0 Local $pRemovedArray = 0 Local $aRet2 = DllCallAddress("long", $pBeginList, _ "ptr", $pDestList, _ "uint*", $cMaxSlots, _ "ptr", _GUIDFromString($IID_IObjectArray), _ "ptr*", 0) If @error Or $aRet2[0] <> 0 Then ConsoleWrite("BeginList failed: 0x" & Hex($aRet2[0], 8) & @CRLF) _ReleaseObject($pDestList) Return False EndIf ConsoleWrite("BeginList succeeded. Max slots: " & $cMaxSlots & @CRLF) ; Create object collection for tasks Local $pObjCollection = 0 Local $aRet3 = DllCall("ole32.dll", "long", "CoCreateInstance", _ "ptr", _GUIDFromString($CLSID_EnumerableObjectCollection), _ "ptr", 0, _ "dword", 1, _ "ptr", _GUIDFromString($IID_IObjectCollection), _ "ptr*", 0) If @error Or $aRet3[0] <> 0 Then ConsoleWrite("Failed to create ObjectCollection: 0x" & Hex($aRet3[0], 8) & @CRLF) _ReleaseObject($pDestList) Return False EndIf Local $pObjCollection = $aRet3[5] ConsoleWrite("ObjectCollection created at: 0x" & Hex($pObjCollection) & @CRLF) ; Create and add tasks Local $bSuccess = True ; Task 1: Notepad If Not _AddTaskToCollection($pObjCollection, "Open Notepad", @WindowsDir & "\notepad.exe", "", "Launch Notepad text editor", @SystemDir & "\imageres.dll", 2) Then ConsoleWrite("Failed to add Notepad task" & @CRLF) $bSuccess = False EndIf ; Task 2: Calculator If Not _AddTaskToCollection($pObjCollection, "Open Calculator", @WindowsDir & "\system32\calc.exe", "", "Launch Calculator", @SystemDir & "\shell32.dll", 24) Then ConsoleWrite("Failed to add Calculator task" & @CRLF) $bSuccess = False EndIf ; Task 3: Command Prompt If Not _AddTaskToCollection($pObjCollection, "Open CMD", @ComSpec, "/k echo Hello from Jump List", "Launch Command Prompt", @SystemDir & "\shell32.dll", 61) Then ConsoleWrite("Failed to add CMD task" & @CRLF) $bSuccess = False EndIf If Not $bSuccess Then ConsoleWrite("Some tasks failed to add, but continuing..." & @CRLF) EndIf ; Get AddUserTasks method (vtable index 6) Local $pAddUserTasks = DllStructGetData(DllStructCreate("ptr", $pVTable + 6*4), 1) ; Add tasks to jump list Local $aRet4 = DllCallAddress("long", $pAddUserTasks, _ "ptr", $pDestList, _ "ptr", $pObjCollection) If @error Or $aRet4[0] <> 0 Then ConsoleWrite("AddUserTasks failed: 0x" & Hex($aRet4[0], 8) & @CRLF) _ReleaseObject($pObjCollection) _ReleaseObject($pDestList) Return False EndIf ConsoleWrite("Tasks added to jump list" & @CRLF) ; Get CommitList method (vtable index 4) Local $pCommitList = DllStructGetData(DllStructCreate("ptr", $pVTable + 4*4), 1) ; Commit the jump list Local $aRet5 = DllCallAddress("long", $pCommitList, _ "ptr", $pDestList) If @error Or $aRet5[0] <> 0 Then ConsoleWrite("CommitList failed: 0x" & Hex($aRet5[0], 8) & @CRLF) Else ConsoleWrite("Jump list created successfully!" & @CRLF) MsgBox(64, "Success", "Jump list created!" & @CRLF & "Pin this app to taskbar and right-click to see the custom tasks.") EndIf ; Cleanup _ReleaseObject($pObjCollection) _ReleaseObject($pDestList) Return True EndFunc Func _AddTaskToCollection($pCollection, $sTitle, $sTargetPath, $sArguments, $sDescription, $sIconPath, $iIconIndex) ConsoleWrite("Adding task: " & $sTitle & @CRLF) ; Create shell link COM object Local $pShellLink = 0 Local $aRet = DllCall("ole32.dll", "long", "CoCreateInstance", _ "ptr", _GUIDFromString($CLSID_ShellLink), _ "ptr", 0, _ "dword", 1, _ "ptr", _GUIDFromString($IID_IShellLinkW), _ "ptr*", 0) If @error Or $aRet[0] <> 0 Then ConsoleWrite("Failed to create ShellLink: 0x" & Hex($aRet[0], 8) & @CRLF) Return False EndIf Local $pShellLink = $aRet[5] ConsoleWrite("ShellLink created at: 0x" & Hex($pShellLink) & @CRLF) ; Get IShellLink vtable Local $pVTableSL = DllStructGetData(DllStructCreate("ptr", $pShellLink), 1) ; Set path (vtable index 20) Local $pSetPath = DllStructGetData(DllStructCreate("ptr", $pVTableSL + 20*4), 1) Local $aRet2 = DllCallAddress("long", $pSetPath, _ "ptr", $pShellLink, _ "wstr", $sTargetPath) If @error Or $aRet2[0] <> 0 Then ConsoleWrite("SetPath failed: 0x" & Hex($aRet2[0], 8) & @CRLF) EndIf ; Set arguments if provided If $sArguments <> "" Then Local $pSetArguments = DllStructGetData(DllStructCreate("ptr", $pVTableSL + 11*4), 1) Local $aRet3 = DllCallAddress("long", $pSetArguments, _ "ptr", $pShellLink, _ "wstr", $sArguments) If @error Or $aRet3[0] <> 0 Then ConsoleWrite("SetArguments failed: 0x" & Hex($aRet3[0], 8) & @CRLF) EndIf EndIf ; Set description Local $pSetDescription = DllStructGetData(DllStructCreate("ptr", $pVTableSL + 7*4), 1) Local $aRet4 = DllCallAddress("long", $pSetDescription, _ "ptr", $pShellLink, _ "wstr", $sDescription) If @error Or $aRet4[0] <> 0 Then ConsoleWrite("SetDescription failed: 0x" & Hex($aRet4[0], 8) & @CRLF) EndIf ; Set icon if provided If $sIconPath <> "" And FileExists($sIconPath) Then Local $pSetIconLocation = DllStructGetData(DllStructCreate("ptr", $pVTableSL + 17*4), 1) Local $aRet5 = DllCallAddress("long", $pSetIconLocation, _ "ptr", $pShellLink, _ "wstr", $sIconPath, _ "int", $iIconIndex) If @error Or $aRet5[0] <> 0 Then ConsoleWrite("SetIconLocation failed: 0x" & Hex($aRet5[0], 8) & @CRLF) EndIf Else ConsoleWrite("Icon path not found: " & $sIconPath & @CRLF) EndIf ; Try to set title using property store (optional) _SetShellLinkTitle($pShellLink, $sTitle) ; Add object to collection Local $pVTableOC = DllStructGetData(DllStructCreate("ptr", $pCollection), 1) Local $pAddObject = DllStructGetData(DllStructCreate("ptr", $pVTableOC + 6*4), 1) Local $aRet8 = DllCallAddress("long", $pAddObject, _ "ptr", $pCollection, _ "ptr", $pShellLink) _ReleaseObject($pShellLink) If @error Or $aRet8[0] <> 0 Then ConsoleWrite("AddObject failed: 0x" & Hex($aRet8[0], 8) & @CRLF) Return False EndIf ConsoleWrite("Task added successfully: " & $sTitle & @CRLF) Return True EndFunc Func _SetShellLinkTitle($pShellLink, $sTitle) ; Try to set the title property (optional - shell link will still work without it) Local $pPropertyStore = 0 Local $pVTableSL = DllStructGetData(DllStructCreate("ptr", $pShellLink), 1) ; QueryInterface for IPropertyStore (vtable index 0) Local $pQueryInterface = DllStructGetData(DllStructCreate("ptr", $pVTableSL), 1) Local $aRet = DllCallAddress("long", $pQueryInterface, _ "ptr", $pShellLink, _ "ptr", _GUIDFromString($IID_IPropertyStore), _ "ptr*", 0) If @error Or $aRet[0] <> 0 Then ; ConsoleWrite("QueryInterface for IPropertyStore failed: 0x" & Hex($aRet[0], 8) & @CRLF) Return False EndIf Local $pPropertyStore = $aRet[3] Local $pVTablePS = DllStructGetData(DllStructCreate("ptr", $pPropertyStore), 1) ; Create property key Local $tPropKey = _CreatePROPERTYKEY($PKEY_Title_FMTID, $PKEY_Title_PID) ; Create PROPVARIANT for title Local $tTitleWStr = DllStructCreate("wchar[" & StringLen($sTitle) + 1 & "]") DllStructSetData($tTitleWStr, 1, $sTitle) Local $tPropVar = DllStructCreate("word vt; word wReserved1; word wReserved2; word wReserved3; ptr pValue") DllStructSetData($tPropVar, "vt", 31) ; VT_LPWSTR DllStructSetData($tPropVar, "pValue", DllStructGetPtr($tTitleWStr)) ; SetValue method (vtable index 5) Local $pSetValue = DllStructGetData(DllStructCreate("ptr", $pVTablePS + 5*4), 1) Local $aRet2 = DllCallAddress("long", $pSetValue, _ "ptr", $pPropertyStore, _ "ptr", DllStructGetPtr($tPropKey), _ "ptr", DllStructGetPtr($tPropVar)) ; Commit (vtable index 7) If Not @error And $aRet2[0] = 0 Then Local $pCommit = DllStructGetData(DllStructCreate("ptr", $pVTablePS + 7*4), 1) DllCallAddress("long", $pCommit, "ptr", $pPropertyStore) EndIf _ReleaseObject($pPropertyStore) Return True EndFunc Func _CreatePROPERTYKEY($sFmtID, $iPID) Local $tGUID = _GUIDFromString($sFmtID) Local $tPropKey = DllStructCreate("byte[16]; dword PID") ; Copy GUID to structure DllCall("kernel32.dll", "none", "RtlMoveMemory", _ "ptr", DllStructGetPtr($tPropKey), _ "ptr", DllStructGetPtr($tGUID), _ "dword", 16) DllStructSetData($tPropKey, "PID", $iPID) Return $tPropKey EndFunc Func _GUIDFromString($sGUID) Local $tGUID = DllStructCreate("dword Data1; word Data2; word Data3; byte Data4[8]") DllCall("ole32.dll", "long", "CLSIDFromString", "wstr", $sGUID, "ptr", DllStructGetPtr($tGUID)) Return $tGUID EndFunc Func _ReleaseObject($pObject) If $pObject Then Local $pVTable = DllStructGetData(DllStructCreate("ptr", $pObject), 1) If $pVTable Then ; Release is 3rd vtable entry (index 2) Local $pRelease = DllStructGetData(DllStructCreate("ptr", $pVTable + 2*4), 1) Local $aRet = DllCallAddress("dword", $pRelease, "ptr", $pObject) Return $aRet[0] EndIf EndIf Return 0 EndFunc
Nine Posted 1 hour ago Posted 1 hour ago (edited) First the IID of ICustomDestinationList should be "{6332debf-87b5-4670-90c0-5e57b408a49e}". Using ObjCreateInterface I was able to successfully create the object. It should be easier to manage than with "CoCreateInstance". And certainly more readable. But if you insist going that path there is a number of problems with your first call, it should be something like this : Local $tGUID1 = _GUIDFromString($CLSID_DestinationList) Local $tGUID2 = _GUIDFromString($IID_ICustomDestinationList) Local $aRet = DllCall("ole32.dll", "long", "CoCreateInstance", _ "struct*", $tGUID1, _ "ptr", 0, _ "dword", 1, _ ; CLSCTX_INPROC_SERVER "struct*", $tGUID2, _ "ptr*", 0) I have a correctly returned pointer this way. That should be enough to get you started. But I strongly recommend that you go with ObjCreateInterface... edit : where did you get that code ? Is this coming from some AI ? Edited 1 hour ago by Nine “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now