WilliamasKumeliukas Posted September 9, 2021 Share Posted September 9, 2021 (edited) impossible to convert GetRef function from VBScript to AutoIt. Edited September 24, 2021 by Melba23 Reset title as thread is now alive again Sorry if it's quite challenging to understand me sometimes, there is 2 possible reasons to this: Spoiler #1. I am a native French speaker and learned English mainly from chatting with others players in online games. #2. I have a developmental disorder mainly affecting my social abilities, way of thinking, understanding stuffs and explaining myself in which it can seem ironic of seeing me here, but I been working on getting better every days for an dozens of years now ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Do not like my dirty code? It's fine, but in my opinion, the dirty codes are unique and I believe it's a good glimpse of how the mind of the person who wrote it thinks, and that, that's what I call a psychological deduction step by step in all its splendor. ~WilliamasKumeliukas Link to comment Share on other sites More sharing options...
JockoDundee Posted September 17, 2021 Share Posted September 17, 2021 On 9/9/2021 at 9:47 AM, WilliamasKumeliukas said: impossible to convert GetRef function from VBScript to AutoIt. why not: Func GetRef($sFunc) Return Execute($sFunc) EndFunc Earthshine and Skysnake 2 Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
WilliamasKumeliukas Posted September 22, 2021 Author Share Posted September 22, 2021 (edited) On 9/17/2021 at 5:47 PM, JockoDundee said: why not: Func GetRef($sFunc) Return Execute($sFunc) EndFunc It return as Unknown Type and triggers COM Error handler when It expect to return as Object Type when I use your function If you didn't read my first post before I removed the contents within it, I can repost it again Regards, ~WilliamasKumeliukas Edited September 22, 2021 by WilliamasKumeliukas Sorry if it's quite challenging to understand me sometimes, there is 2 possible reasons to this: Spoiler #1. I am a native French speaker and learned English mainly from chatting with others players in online games. #2. I have a developmental disorder mainly affecting my social abilities, way of thinking, understanding stuffs and explaining myself in which it can seem ironic of seeing me here, but I been working on getting better every days for an dozens of years now ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Do not like my dirty code? It's fine, but in my opinion, the dirty codes are unique and I believe it's a good glimpse of how the mind of the person who wrote it thinks, and that, that's what I call a psychological deduction step by step in all its splendor. ~WilliamasKumeliukas Link to comment Share on other sites More sharing options...
Earthshine Posted September 22, 2021 Share Posted September 22, 2021 (edited) first off, you need to understand what GetRef actually does https://www.vbsedit.com/html/f9643b79-b4a1-4f70-9017-2b2e2f01ef3a.asp#:~:text=The GetRef function allows you,available for its various objects. then you need to code to those requirements. read this https://www.oreilly.com/library/view/vbscript-in-a/0596004885/re109.html if you are comparing to VBA, that isn't supported in VBA, only VBScript so, do you have an DHTML page you wish do do things with/on? why are you deleting your posts? Edited September 22, 2021 by Earthshine My resources are limited. You must ask the right questions Link to comment Share on other sites More sharing options...
JockoDundee Posted September 22, 2021 Share Posted September 22, 2021 23 minutes ago, WilliamasKumeliukas said: If you didn't read my first post before I removed the contents within it, I can repost it again No, I had only read it after it was declared impossible and subject changed to “removed”. Please repost. Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
Earthshine Posted September 22, 2021 Share Posted September 22, 2021 interesting to see the actual use case for such a thing My resources are limited. You must ask the right questions Link to comment Share on other sites More sharing options...
WilliamasKumeliukas Posted September 22, 2021 Author Share Posted September 22, 2021 (edited) 1 hour ago, Earthshine said: first off, you need to understand what GetRef actually does https://www.vbsedit.com/html/f9643b79-b4a1-4f70-9017-2b2e2f01ef3a.asp#:~:text=The GetRef function allows you,available for its various objects. then you need to code to those requirements. read this https://www.oreilly.com/library/view/vbscript-in-a/0596004885/re109.html if you are comparing to VBA, that isn't supported in VBA, only VBScript so, do you have an DHTML page you wish do do things with/on? why are you deleting your posts? This script download Windows Updates asynchronously and track progress You can also explore methods / properties / etc from a object browser by loading this dll : (C:\Windows\SysWOW64\wuAPI.dll) I know how to do it in VBScript, but I don't know what I am missing or doing wrong in AutoIt 😕 GetRef is used to accomplish this: link (Note: I can provide both full scripts if the following snippets arent helping much) In VBScript, It is used like this: Function Download(Byval hCollection) Dim Result Set Downloader = updateSession.CreateUpdateDownloader() Downloader.Updates = hCollection Set DownloadJob = Downloader.BeginDownload(GetRef("Download_OnProgressChanged"), GetRef("Download_OnCompleted"), "") If Not Err.Number = 0 Then WScript.StdOut.WriteLine "Error " & Err.Number & ": " & Err.Description End If Do Until DownloadJob.IsCompleted WScript.Sleep 1000 Loop Set Download = Downloader.EndDownload(DownloadJob) End Function Sub Download_OnProgressChanged(ByVal hDownloadJob, ByVal hArguments) WScript.StdOut.WriteLine "Activity=""Processing Windows Updates on " & strComputerName & """ Status=""Downloading updates"" Percentage=" & hArguments.Progress.PercentComplete End Sub Sub Download_OnCompleted(ByVal hInstallJob, ByVal hArguments) WScript.StdOut.WriteLine "Activity=""Processing Windows Updates on " & strComputerName & """ Status=""Downloading updates"" Percentage=100" End Sub in AutoIt I try reproducing the same like this: expandcollapse popupGlobal $oMyError = ObjEvent("AutoIt.Error","MyErrFunc") Func GetRef($sFunc) Return Execute($sFunc) EndFunc Func Download($hCollection) Dim $Result $Downloader = $updateSession.CreateUpdateDownloader() $Downloader.Updates = $hCollection Do $DownloadJob = $Downloader.BeginDownload( GetRef("Download_OnProgressChanged"), GetRef("Download_OnCompleted"), "") If Not $oMyError.Number = 0 Then c("Error " & $oMyError.Number & ": " & $oMyError.Description) EndIf Until $DownloadJob.IsCompleted Sleep(1000) $Download = $Downloader.EndDownload($DownloadJob) EndFunc ;==>Download Func Download_OnProgressChanged($hDownloadJob, $hArguments) c("Downloading update = " & $hArguments.Progress.PercentComplete) EndFunc ;==>Download_OnProgressChanged Func Download_OnCompleted($hDownloadJob, $hArguments) c("Downloading update = 100%") EndFunc ;==>Download_OnCompleted Func MyErrFunc() $count += 1 If $count = 3 Then Exit ; limited to 3 errors and exit to prevent spam (for debug purposes) $HexNumber=hex($oMyError.number,8) Msgbox(0,"COM Test","We intercepted a COM Error !" & @CRLF & @CRLF & _ "err.description is: " & @TAB & $oMyError.description & @CRLF & _ "err.windescription:" & @TAB & $oMyError.windescription & @CRLF & _ "err.number is: " & @TAB & $HexNumber & @CRLF & _ "err.lastdllerror is: " & @TAB & $oMyError.lastdllerror & @CRLF & _ "err.scriptline is: " & @TAB & $oMyError.scriptline & @CRLF & _ "err.source is: " & @TAB & $oMyError.source & @CRLF & _ "err.helpfile is: " & @TAB & $oMyError.helpfile & @CRLF & _ "err.helpcontext is: " & @TAB & $oMyError.helpcontext _ ) SetError(1) ; to check for after this function returns Endfunc I hope it will clarify things much better and If your unsure and you want to do tests before post, I can attach both full scripts as I said earlier. Sincerely, WK Edited September 22, 2021 by WilliamasKumeliukas Clarifying a bit more Sorry if it's quite challenging to understand me sometimes, there is 2 possible reasons to this: Spoiler #1. I am a native French speaker and learned English mainly from chatting with others players in online games. #2. I have a developmental disorder mainly affecting my social abilities, way of thinking, understanding stuffs and explaining myself in which it can seem ironic of seeing me here, but I been working on getting better every days for an dozens of years now ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Do not like my dirty code? It's fine, but in my opinion, the dirty codes are unique and I believe it's a good glimpse of how the mind of the person who wrote it thinks, and that, that's what I call a psychological deduction step by step in all its splendor. ~WilliamasKumeliukas Link to comment Share on other sites More sharing options...
Earthshine Posted September 22, 2021 Share Posted September 22, 2021 (edited) no, you didn't make anything clearer are you trying to bind to events in a browser? WHAT are you trying to do explicitly, there may be a better way. you would have to see the code for getref to know how to do it in other languages, if it's possible in autoit even. i still think you don't understand the GetRef function. It returns a Long. looking at your implementation that isn't going to work. Return Value A Long containing a reference to procname. Description Returns a reference to a sub or function. This reference can be used for such purposes as binding to events or defining callback functions. Rules at a Glance GetRef can be used whenever a function or procedure reference is expected. When using GetRef to define event handlers for events, the Set keyword is required. For example, the code required to bind the Window.OnLoad event to a procedure named ShowGreetingDialog is: Set Window.OnLoad = GetRef("ShowGreetingDialog") Edited September 22, 2021 by Earthshine My resources are limited. You must ask the right questions Link to comment Share on other sites More sharing options...
WilliamasKumeliukas Posted September 22, 2021 Author Share Posted September 22, 2021 (edited) I want to search, download and install windows updates by Creating Object "Microsoft.Update.Session" 21 hours ago, Earthshine said: no, you didn't make anything clearer are you trying to bind to events in a browser? No, I'm not trying to interact or bind to events in a browser, unless Microsoft.Update.Session object is? Edited September 23, 2021 by WilliamasKumeliukas Sorry if it's quite challenging to understand me sometimes, there is 2 possible reasons to this: Spoiler #1. I am a native French speaker and learned English mainly from chatting with others players in online games. #2. I have a developmental disorder mainly affecting my social abilities, way of thinking, understanding stuffs and explaining myself in which it can seem ironic of seeing me here, but I been working on getting better every days for an dozens of years now ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Do not like my dirty code? It's fine, but in my opinion, the dirty codes are unique and I believe it's a good glimpse of how the mind of the person who wrote it thinks, and that, that's what I call a psychological deduction step by step in all its splendor. ~WilliamasKumeliukas Link to comment Share on other sites More sharing options...
WilliamasKumeliukas Posted September 22, 2021 Author Share Posted September 22, 2021 31 minutes ago, Earthshine said: no, you didn't make anything clearer are you trying to bind to events in a browser? WHAT are you trying to do explicitly, there may be a better way. you would have to see the code for getref to know how to do it in other languages, if it's possible in autoit even. i still think you don't understand the GetRef function. It returns a Long. looking at your implementation that isn't going to work. Indeed im stuck with a missing specification which I didn't had to specify with vbs code Sorry if it's quite challenging to understand me sometimes, there is 2 possible reasons to this: Spoiler #1. I am a native French speaker and learned English mainly from chatting with others players in online games. #2. I have a developmental disorder mainly affecting my social abilities, way of thinking, understanding stuffs and explaining myself in which it can seem ironic of seeing me here, but I been working on getting better every days for an dozens of years now ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Do not like my dirty code? It's fine, but in my opinion, the dirty codes are unique and I believe it's a good glimpse of how the mind of the person who wrote it thinks, and that, that's what I call a psychological deduction step by step in all its splendor. ~WilliamasKumeliukas Link to comment Share on other sites More sharing options...
Earthshine Posted September 22, 2021 Share Posted September 22, 2021 (edited) maybe you should look into using WebDriver UDF that is supported here for browser automation that or UIAutomation Edited September 22, 2021 by Earthshine My resources are limited. You must ask the right questions Link to comment Share on other sites More sharing options...
LarsJ Posted September 22, 2021 Share Posted September 22, 2021 Since there is good integration between VBScript and AutoIt, why not run the VBScript code directly (as a VBScript), and then pass data between VBScript and an AutoIt script as needed through ROT objects. Danyfirex 1 Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
Danyfirex Posted September 24, 2021 Share Posted September 24, 2021 Hello. If you want to use BeginDownload you would probably need to use ObjectFromTag function(search on forum) then create those two objects IDownloadProgressChangedCallback (onProgressChanged) and IDownloadCompletedCallback(onCompleted) and pass the interface pointers to the function. LarsJ suggestion will be the easier probably better. Saludos Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
JockoDundee Posted September 24, 2021 Share Posted September 24, 2021 FWIW, I think my GetRef() is solid. It returns a bona-fide function pointer when given a valid string. Just like it does in VBS. The problem, IMO, is replicating what the VBS Set command does in creating a casted object pointer. I’m nowhere near as knowledgeable about the COM stuff as others that have already commented, so I’ll leave it to them Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
WilliamasKumeliukas Posted September 24, 2021 Author Share Posted September 24, 2021 On 9/22/2021 at 3:53 PM, LarsJ said: Since there is good integration between VBScript and AutoIt, why not run the VBScript code directly (as a VBScript), and then pass data between VBScript and an AutoIt script as needed through ROT objects. I will take a look onto this, thank you! 13 hours ago, Danyfirex said: Hello. If you want to use BeginDownload you would probably need to use ObjectFromTag function(search on forum) then create those two objects IDownloadProgressChangedCallback (onProgressChanged) and IDownloadCompletedCallback(onCompleted) and pass the interface pointers to the function. LarsJ suggestion will be the easier probably better. Saludos Thanks for the suggestion! I will check for both suggestion Regards, WilliamasKumeliukas Sorry if it's quite challenging to understand me sometimes, there is 2 possible reasons to this: Spoiler #1. I am a native French speaker and learned English mainly from chatting with others players in online games. #2. I have a developmental disorder mainly affecting my social abilities, way of thinking, understanding stuffs and explaining myself in which it can seem ironic of seeing me here, but I been working on getting better every days for an dozens of years now ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Do not like my dirty code? It's fine, but in my opinion, the dirty codes are unique and I believe it's a good glimpse of how the mind of the person who wrote it thinks, and that, that's what I call a psychological deduction step by step in all its splendor. ~WilliamasKumeliukas Link to comment Share on other sites More sharing options...
Popular Post Danyfirex Posted September 24, 2021 Popular Post Share Posted September 24, 2021 Hello. Here is the Implementation of ISearchCompletedCallback If You understand how it works you will be able to implement BeginDownload required Interface callbacks. expandcollapse popup#include <WinAPICom.au3> Global Const $S_OK = 0x00000000 Global Const $E_NOINTERFACE = 0x80004002 Global Const $sIID_IUnknown = "{00000000-0000-0000-C000-000000000046}" Global Const $sIID_SearchCompletedCallback = "{88AEE058-D4B0-4725-A2F1-814A67AE964C}" Global Const $tagIUnknown = "QueryInterface hresult(ptr;ptr*);" & _ "AddRef dword();" & _ "Release dword();" Global Const $tagIDispatch = $tagIUnknown & _ "GetTypeInfoCount hresult(dword*);" & _ "GetTypeInfo hresult(dword;dword;ptr*);" & _ "GetIDsOfNames hresult(struct*;struct*;dword;dword;struct*);" & _ "Invoke hresult(uint;struct*;dword;word;struct*;struct*;ptr;uint*);" Global $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc") _Test() Exit Func _Test() _WinAPI_CoInitialize($COINIT_APARTMENTTHREADED) Local $oMUS = ObjCreate("Microsoft.Update.Session") Local $oSearch = $oMUS.CreateUpdateSearcher() Local $oCompleted, $tCompleted Local $dtagISearchCompletedCallback = "Invoke hresult(idispatch;ptr);" $oCompleted = __ObjectFromTag("__MyInterface_", $dtagISearchCompletedCallback, $tCompleted, Default, $sIID_SearchCompletedCallback) ;~ $oCompleted = __ObjectFromTag("__MyInterface_", $dtagISearchCompletedCallback, $tCompleted) Local $AsyncState = "Danyfirex Loves AutoIt" Local $sCriteria = "IsInstalled=0 or IsHidden=1 or IsPresent=1" ;Create Cast ObjectTag IUpdateSearcher Local $sTagSearch = $tagIDispatch & _Dummy("A", "", 8) & "BeginSearch hresult(bstr;ptr;variant;idispatch*);" & "EndSearch hresult(idispatch;idispatch*);" Local $oSearchCast = ObjCreateInterface($oSearch, "{8f45abf1-f9ae-4b95-a933-f0f66e5056ea}", $sTagSearch, False) Local $oJob = 0 ;~ $oJob = $oSearch.BeginSearch($sCriteria, $oCompleted, $Variant) ;this will not work $oSearchCast.BeginSearch($sCriteria, $oCompleted(), $AsyncState, $oJob) ;casted to make it work ConsoleWrite("$oJob.AsyncState: " & $oJob.AsyncState & @CRLF) While Not $oJob.IsCompleted Sleep(100) WEnd MsgBox(0, "ISearchCompletedCallback Invoke Reached", "Print Updates Title & Exit") Local $oSearchResult = 0 $oSearchCast.EndSearch($oJob, $oSearchResult) For $oUpdate In $oSearchResult.Updates ConsoleWrite(">" & $oUpdate.Title & @CRLF) Next $oSearchCast = 0 $oSearch = 0 $oMUS = 0 EndFunc ;==>_Test Func _Dummy($Name, $Parameters = "", $iTimes = 1) Local $sTag = "" For $i = 1 To $iTimes $sTag &= "DM_" & $Name & $i & " hresult(" & $Parameters & ");" Next Return $sTag EndFunc ;==>_Dummy Func __ObjectFromTag($sFunctionPrefix, $tagInterface, ByRef $tInterface, $bIsUnknown = Default, $sIID = "{00000000-0000-0000-C000-000000000046}") ; last param is IID_IUnknown by default If $bIsUnknown = Default Then $bIsUnknown = True Local $sInterface = $tagInterface ; copy interface description Local $tagIUnknown = "QueryInterface hresult(ptr;ptr*);" & _ "AddRef dword();" & _ "Release dword();" ; Adding IUnknown methods If $bIsUnknown Then $tagInterface = $tagIUnknown & $tagInterface ; Below line is really simple even though it looks super complex. It's just written weird to fit in one line, not to steal your attention Local $aMethods = StringSplit(StringTrimRight(StringReplace(StringRegExpReplace(StringRegExpReplace($tagInterface, "\w+\*", "ptr"), "\h*(\w+)\h*(\w+\*?)\h*(\((.*?)\))\h*(;|;*\z)", "$1\|$2;$4" & @LF), ";" & @LF, @LF), 1), @LF, 3) Local $iUbound = UBound($aMethods) Local $sMethod, $aSplit, $sNamePart, $aTagPart, $sTagPart, $sRet, $sParams, $hCallback ; Allocation $tInterface = DllStructCreate("int RefCount;int Size;ptr Object;ptr Methods[" & $iUbound & "];int_ptr Callbacks[" & $iUbound & "];ulong_ptr Slots[16]") ; 16 pointer sized elements more to create space for possible private props If @error Then Return SetError(1, 0, 0) For $i = 0 To $iUbound - 1 $aSplit = StringSplit($aMethods[$i], "|", 2) If UBound($aSplit) <> 2 Then ReDim $aSplit[2] $sNamePart = $aSplit[0] ; Replace COM types by matching dllcallback types $sTagPart = StringReplace(StringReplace(StringReplace(StringReplace($aSplit[1], "object", "idispatch"), "hresult", "long"), "bstr", "ptr"), "variant", "ptr") $sMethod = $sFunctionPrefix & $sNamePart $aTagPart = StringSplit($sTagPart, ";", 2) $sRet = $aTagPart[0] $sParams = StringReplace($sTagPart, $sRet, "", 1) $sParams = "ptr" & $sParams $hCallback = DllCallbackRegister($sMethod, $sRet, $sParams) DllStructSetData($tInterface, "Methods", DllCallbackGetPtr($hCallback), $i + 1) ; save callback pointer DllStructSetData($tInterface, "Callbacks", $hCallback, $i + 1) ; save callback handle Next DllStructSetData($tInterface, "RefCount", 1) ; initial ref count is 1 DllStructSetData($tInterface, "Size", $iUbound) ; number of interface methods DllStructSetData($tInterface, "Object", DllStructGetPtr($tInterface, "Methods")) ; Interface method pointers Return ObjCreateInterface(DllStructGetPtr($tInterface, "Object"), $sIID, $sInterface, $bIsUnknown) ; pointer that's wrapped into object EndFunc ;==>__ObjectFromTag Func __DeleteObjectFromTag(ByRef $tInterface) For $i = 1 To DllStructGetData($tInterface, "Size") DllCallbackFree(DllStructGetData($tInterface, "Callbacks", $i)) Next $tInterface = 0 EndFunc ;==>__DeleteObjectFromTag Func __MyInterface_QueryInterface($pSelf, $pRIID, $pObj) ; Ret: long Par: ptr;ptr* Local $sIID = StringFromGUID2($pRIID) If $sIID = $sIID_IUnknown Then DllStructSetData(DllStructCreate("ptr", $pObj), 1, $pSelf) Return $S_OK ElseIf $sIID = $sIID_SearchCompletedCallback Then DllStructSetData(DllStructCreate("ptr", $pObj), 1, $pSelf) Return $S_OK Else Return $E_NOINTERFACE EndIf EndFunc ;==>__MyInterface_QueryInterface Func StringFromGUID2($pGUID) Local $aReturn = DllCall('ole32.dll', 'int', 'StringFromGUID2', 'struct*', $pGUID, 'wstr', '', 'int', 65536) If @error Or Not $aReturn[0] Then Return SetError(@error + 20, @extended, '') Return SetExtended($aReturn[0], $aReturn[2]) EndFunc ;==>StringFromGUID2 Func __MyInterface_AddRef($pSelf) Return 1 EndFunc ;==>__MyInterface_AddRef Func __MyInterface_Release($pSelf) Return 1 EndFunc ;==>__MyInterface_Release Volatile Func __MyInterface_Invoke($pSelf, $oSearchJob, $pISearchCompletedCallbackArgs) ConsoleWrite("Invoke" & @CRLF) ConsoleWrite("Invoke - oSearchJob.AsyncState: " & $oSearchJob.AsyncState & @CRLF) Return $S_OK EndFunc ;==>__MyInterface_Invoke ; User's COM error function. Will be called if COM error occurs Func _ErrFunc($oError) ; Do anything here. ConsoleWrite(@ScriptName & " (" & $oError.scriptline & ") : ==> COM Error intercepted !" & @CRLF & _ @TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & _ @TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & _ @TAB & "err.description is: " & @TAB & $oError.description & @CRLF & _ @TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & _ @TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _ @TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _ @TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _ @TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _ @TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF) EndFunc ;==>_ErrFunc Saludos LarsJ, JockoDundee, mLipok and 2 others 5 Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
Danyfirex Posted September 27, 2021 Share Posted September 27, 2021 Hello. It's me again. Just to leave a whole example. expandcollapse popup#RequireAdmin #include <WinAPICom.au3> #include <Debug.au3> #include <Array.au3> Global Const $S_OK = 0x00000000 Global Const $E_NOINTERFACE = 0x80004002 Global Const $sIID_IUnknown = "{00000000-0000-0000-C000-000000000046}" Global Const $sIID_ISearchCompletedCallback = "{88AEE058-D4B0-4725-A2F1-814A67AE964C}" Global Const $sIID_IDownloadCompletedCallback = "{77254866-9F5B-4C8E-B9E2-C77A8530D64B}" Global Const $sIID_IDownloadProgressChangedCallback = "{8C3F1CDD-6173-4591-AEBD-A56A53CA77C1}" Global Const $tagIUnknown = "QueryInterface hresult(ptr;ptr*);" & _ "AddRef dword();" & _ "Release dword();" Global Const $tagIDispatch = $tagIUnknown & _ "GetTypeInfoCount hresult(dword*);" & _ "GetTypeInfo hresult(dword;dword;ptr*);" & _ "GetIDsOfNames hresult(struct*;struct*;dword;dword;struct*);" & _ "Invoke hresult(uint;struct*;dword;word;struct*;struct*;ptr;uint*);" Global $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc") Global $g_aSelectedRows = 0 _Test() Exit Func _Test() _WinAPI_CoInitialize($COINIT_APARTMENTTHREADED) Local Const $sCriteria = "Type='Software' and IsInstalled=0" Local $oMUS = ObjCreate("Microsoft.Update.Session") Local $oSearcher = $oMUS.CreateUpdateSearcher() Local $oCompleted, $tCompleted, $dtagISearchCompletedCallback = "InvokeSCC hresult(idispatch;ptr);" $oCompleted = __ObjectFromTag("__MyInterface_", $dtagISearchCompletedCallback, $tCompleted) ;Create Cast Tag IUpdateSearcher Local $sTagSearcher = $tagIDispatch & _Dummy("A", "", 8) & "BeginSearch hresult(bstr;ptr;variant;idispatch*);" & "EndSearch hresult(idispatch;idispatch*);" Local $oSearcherCast = ObjCreateInterface($oSearcher, "{8F45ABF1-F9AE-4B95-A933-F0F66E5056EA}", $sTagSearcher, False) Local $AsyncState = "Danyfirex Loves AutoIt" Local $oJob = 0 ;~ $oJob = $oSearcher.BeginSearch($sCriteria, $oCompleted, $Variant) ;this will not work $oSearcherCast.BeginSearch($sCriteria, $oCompleted(), $AsyncState, $oJob) ;casted to make it work While Not $oJob.IsCompleted ;wait search Sleep(100) WEnd Local $oSearchResult = 0 $oSearcherCast.EndSearch($oJob, $oSearchResult) Local $aUpdates[$oSearchResult.Updates.Count][5] Local $oCustomUpdateCollection = $oSearchResult.Updates.Copy $oCustomUpdateCollection.Clear Local $iCount = 0 For $oUpdate In $oSearchResult.Updates $aUpdates[$iCount][0] = $oUpdate.Title $aUpdates[$iCount][1] = $oUpdate.Description $aUpdates[$iCount][2] = ByteSuffix($oUpdate.MaxDownloadSize) $aUpdates[$iCount][3] = $oUpdate.MaxDownloadSize $aUpdates[$iCount][4] = $oUpdate $iCount += 1 Next _ArraySort($aUpdates, 0, 0, 0, 3) _DebugArrayDisplay($aUpdates, "Select Some Updates for Download Click ""Run User Func""", "|0:3", 0, Default, "Title|Description|Size|Size Bytes", Default, _GetSelected) If $g_aSelectedRows[0] = 0 Then Return MsgBox(0, "Info", "No Updates Selected. Script will Exit...") EndIf ;Create Update Collection For $i = 1 To $g_aSelectedRows[0] ConsoleWrite("Add Update: " & $aUpdates[$g_aSelectedRows[$i]][0] & @CRLF) $oCustomUpdateCollection.Add($aUpdates[$g_aSelectedRows[$i]][4]) Next Local $oDownloader = $oMUS.CreateUpdateDownloader() $oDownloader.Updates = $oCustomUpdateCollection Local $sTagDownloader = $tagIDispatch & _Dummy("A", "", 8) & "BeginDownload hresult(ptr;ptr;variant;idispatch*);Download hresult();EndDownload hresult(idispatch;idispatch*);" Local $oDownloaderCast = ObjCreateInterface($oDownloader, "{68F1C6F9-7ECC-4666-A464-247FE12496C3}", $sTagDownloader, False) Local $oDownloadProgress, $tDownloadProgress, $dtagIDownloadProgressChangedCallback = "Invoke_DPCC hresult(idispatch;idispatch);" $oDownloadProgress = __ObjectFromTag("__MyInterface_", $dtagIDownloadProgressChangedCallback, $tDownloadProgress) Local $oDownloadCompleted, $tDownloadCompleted, $dtagIDownloadCompletedCallback = "Invoke_DCC hresult(idispatch;ptr);" $oDownloadCompleted = __ObjectFromTag("__MyInterface_", $dtagIDownloadCompletedCallback, $tDownloadCompleted) Local $AsyncState = "Danyfirex Loves AutoIt Download" Local $oDownloadJob = 0 ;~ $oDownloader.BeginDownload($oDownloadProgress(), $oDownloadCompleted(), $AsyncState, $oDownloadJob) ;this will not work $oDownloaderCast.BeginDownload($oDownloadProgress(), $oDownloadCompleted(), $AsyncState, $oDownloadJob) ;casted to make it work ProgressOn("Downloading Updates", "Download Started...") While Not $oDownloadJob.IsCompleted Sleep(100) WEnd Sleep(2000) ProgressOff() Local $oDownloadResult = 0 $oDownloaderCast.EndDownload($oDownloadJob, $oDownloadResult) If $oDownloadResult.ResultCode = 2 Then MsgBox(0, "Info", "Download Completed.") Else MsgBox(0, "Info", "Download Failed.") EndIf $oDownloader = 0 $oDownloaderCast = 0 $oSearcherCast = 0 $oSearcher = 0 $oMUS = 0 EndFunc ;==>_Test Func _GetSelected($aArray, $aSelected) $g_aSelectedRows = $aSelected If $g_aSelectedRows[0] = 0 Then MsgBox(0, "", "Select one/more items. Click ""Run User Func""") Else Send("{ESC}") EndIf EndFunc ;==>_GetSelected Func ByteSuffix($iBytes) Local $iIndex = 0, $aArray = [' bytes', ' KB', ' MB', ' GB', ' TB', ' PB', ' EB', ' ZB', ' YB'] While $iBytes > 1023 $iIndex += 1 $iBytes /= 1024 WEnd Return Round($iBytes) & $aArray[$iIndex] EndFunc ;==>ByteSuffix Func _Dummy($Name, $Parameters = "", $iTimes = 1) Local $sTag = "" For $i = 1 To $iTimes $sTag &= "DM_" & $Name & $i & " hresult(" & $Parameters & ");" Next Return $sTag EndFunc ;==>_Dummy Func __ObjectFromTag($sFunctionPrefix, $tagInterface, ByRef $tInterface, $bIsUnknown = Default, $sIID = "{00000000-0000-0000-C000-000000000046}") ; last param is IID_IUnknown by default If $bIsUnknown = Default Then $bIsUnknown = True Local $sInterface = $tagInterface ; copy interface description Local $tagIUnknown = "QueryInterface hresult(ptr;ptr*);" & _ "AddRef dword();" & _ "Release dword();" ; Adding IUnknown methods If $bIsUnknown Then $tagInterface = $tagIUnknown & $tagInterface ; Below line is really simple even though it looks super complex. It's just written weird to fit in one line, not to steal your attention Local $aMethods = StringSplit(StringTrimRight(StringReplace(StringRegExpReplace(StringRegExpReplace($tagInterface, "\w+\*", "ptr"), "\h*(\w+)\h*(\w+\*?)\h*(\((.*?)\))\h*(;|;*\z)", "$1\|$2;$4" & @LF), ";" & @LF, @LF), 1), @LF, 3) Local $iUbound = UBound($aMethods) Local $sMethod, $aSplit, $sNamePart, $aTagPart, $sTagPart, $sRet, $sParams, $hCallback ; Allocation $tInterface = DllStructCreate("int RefCount;int Size;ptr Object;ptr Methods[" & $iUbound & "];int_ptr Callbacks[" & $iUbound & "];ulong_ptr Slots[16]") ; 16 pointer sized elements more to create space for possible private props If @error Then Return SetError(1, 0, 0) For $i = 0 To $iUbound - 1 $aSplit = StringSplit($aMethods[$i], "|", 2) If UBound($aSplit) <> 2 Then ReDim $aSplit[2] $sNamePart = $aSplit[0] ; Replace COM types by matching dllcallback types $sTagPart = StringReplace(StringReplace(StringReplace(StringReplace($aSplit[1], "object", "idispatch"), "hresult", "long"), "bstr", "ptr"), "variant", "ptr") $sMethod = $sFunctionPrefix & $sNamePart $aTagPart = StringSplit($sTagPart, ";", 2) $sRet = $aTagPart[0] $sParams = StringReplace($sTagPart, $sRet, "", 1) $sParams = "ptr" & $sParams $hCallback = DllCallbackRegister($sMethod, $sRet, $sParams) DllStructSetData($tInterface, "Methods", DllCallbackGetPtr($hCallback), $i + 1) ; save callback pointer DllStructSetData($tInterface, "Callbacks", $hCallback, $i + 1) ; save callback handle Next DllStructSetData($tInterface, "RefCount", 1) ; initial ref count is 1 DllStructSetData($tInterface, "Size", $iUbound) ; number of interface methods DllStructSetData($tInterface, "Object", DllStructGetPtr($tInterface, "Methods")) ; Interface method pointers Return ObjCreateInterface(DllStructGetPtr($tInterface, "Object"), $sIID, $sInterface, $bIsUnknown) ; pointer that's wrapped into object EndFunc ;==>__ObjectFromTag Func __DeleteObjectFromTag(ByRef $tInterface) For $i = 1 To DllStructGetData($tInterface, "Size") DllCallbackFree(DllStructGetData($tInterface, "Callbacks", $i)) Next $tInterface = 0 EndFunc ;==>__DeleteObjectFromTag Func __MyInterface_QueryInterface($pSelf, $pRIID, $pObj) ; Ret: long Par: ptr;ptr* Local $sIID = StringFromGUID2($pRIID) If $sIID = $sIID_IUnknown Then DllStructSetData(DllStructCreate("ptr", $pObj), 1, $pSelf) Return $S_OK ElseIf $sIID = $sIID_ISearchCompletedCallback Then DllStructSetData(DllStructCreate("ptr", $pObj), 1, $pSelf) Return $S_OK ElseIf $sIID = $sIID_IDownloadCompletedCallback Then DllStructSetData(DllStructCreate("ptr", $pObj), 1, $pSelf) Return $S_OK ElseIf $sIID = $sIID_IDownloadProgressChangedCallback Then DllStructSetData(DllStructCreate("ptr", $pObj), 1, $pSelf) Return $S_OK Else Return $E_NOINTERFACE EndIf EndFunc ;==>__MyInterface_QueryInterface Func __MyInterface_AddRef($pSelf) Return 1 EndFunc ;==>__MyInterface_AddRef Func __MyInterface_Release($pSelf) Return 1 EndFunc ;==>__MyInterface_Release Volatile Func __MyInterface_Invoke_SCC($pSelf, $oSearchJob, $pISearchCompletedCallbackArgs) ;~ ConsoleWrite("InvokeSCC - oSearchJob.AsyncState: " & $oSearchJob.AsyncState & @CRLF) Return $S_OK EndFunc ;==>__MyInterface_Invoke_SCC Volatile Func __MyInterface_Invoke_DCC($pSelf, $oDownloadJob, $pIDownloadCompletedCallbackArgs) ;~ ConsoleWrite("InvokeDCC - $oDownloadJob.AsyncState: " & $oDownloadJob.AsyncState & @CRLF) ProgressSet(100, "Download Completed...", "Download Completed.") Return $S_OK EndFunc ;==>__MyInterface_Invoke_DCC Volatile Func __MyInterface_Invoke_DPCC($pSelf, $oDownloadJob, $oDownloadProgressChangedCallbackArgs) ;~ ConsoleWrite("InvokeDPCC" & @CRLF) Local $iCurrentPercent = $oDownloadProgressChangedCallbackArgs.Progress.CurrentUpdatePercentComplete ProgressSet($iCurrentPercent, "(" & $iCurrentPercent & "%) " & $oDownloadJob.Updates($oDownloadProgressChangedCallbackArgs.Progress.CurrentUpdateIndex).Title, _ "Downloading Updates (" & $oDownloadProgressChangedCallbackArgs.Progress.CurrentUpdateIndex + 1 & "/" & $oDownloadJob.Updates.Count & ")") Return $S_OK EndFunc ;==>__MyInterface_Invoke_DPCC Func StringFromGUID2($pGUID) Local $aReturn = DllCall('ole32.dll', 'int', 'StringFromGUID2', 'struct*', $pGUID, 'wstr', '', 'int', 65536) If @error Or Not $aReturn[0] Then Return SetError(@error + 20, @extended, '') Return SetExtended($aReturn[0], $aReturn[2]) EndFunc ;==>StringFromGUID2 ; User's COM error function. Will be called if COM error occurs Func _ErrFunc($oError) ; Do anything here. ConsoleWrite(@ScriptName & " (" & $oError.scriptline & ") : ==> COM Error intercepted !" & @CRLF & _ @TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & _ @TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & _ @TAB & "err.description is: " & @TAB & $oError.description & @CRLF & _ @TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & _ @TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _ @TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _ @TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _ @TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _ @TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF) EndFunc ;==>_ErrFunc Saludos mLipok and WilliamasKumeliukas 2 Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
mLipok Posted September 27, 2021 Share Posted September 27, 2021 (edited) uff... now I know why my computer do not want to install recent update Because I do not have 100GB free space on my SSD Edited September 27, 2021 by mLipok Danyfirex 1 Signature beginning:* Please remember: "AutoIt"..... * Wondering who uses AutoIt and what it can be used for ? * Forum Rules ** ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Code * for other useful stuff click the following button: Spoiler Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST API * ErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) * Show_Macro_Values.au3 * My contribution to others projects or UDF based on others projects: * _sql.au3 UDF * POP3.au3 UDF * RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF * SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane * Useful links: * Forum Rules * Forum etiquette * Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * Wiki: * Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX IE Related: * How to use IE.au3 UDF with AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskScheduler * IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related: * How to get reference to PDF object embeded in IE * IE on Windows 11 * I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions * EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *I also encourage you to check awesome @trancexx code: * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuff * OnHungApp handler * Avoid "AutoIt Error" message box in unknown errors * HTML editor * winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/ "Homo sum; humani nil a me alienum puto" - Publius Terentius Afer"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming" , be and \\//_. Anticipating Errors : "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty." Signature last update: 2023-04-24 Link to comment Share on other sites More sharing options...
mLipok Posted September 27, 2021 Share Posted September 27, 2021 (edited) Here is little modified script (compatibility with Au3Check) : expandcollapse popup;~ https://www.autoitscript.com/forum/topic/206615-convert-getref-function-from-vbscript-to-autoit/?tab=comments#comment-1489832 #RequireAdmin #include <WinAPICom.au3> #include <Debug.au3> #include <Array.au3> Global Const $S_OK = 0x00000000 Global Const $E_NOINTERFACE = 0x80004002 Global Const $sIID_IUnknown = "{00000000-0000-0000-C000-000000000046}" Global Const $sIID_ISearchCompletedCallback = "{88AEE058-D4B0-4725-A2F1-814A67AE964C}" Global Const $sIID_IDownloadCompletedCallback = "{77254866-9F5B-4C8E-B9E2-C77A8530D64B}" Global Const $sIID_IDownloadProgressChangedCallback = "{8C3F1CDD-6173-4591-AEBD-A56A53CA77C1}" Global Const $tagIUnknown = "QueryInterface hresult(ptr;ptr*);" & _ "AddRef dword();" & _ "Release dword();" Global Const $tagIDispatch = $tagIUnknown & _ "GetTypeInfoCount hresult(dword*);" & _ "GetTypeInfo hresult(dword;dword;ptr*);" & _ "GetIDsOfNames hresult(struct*;struct*;dword;dword;struct*);" & _ "Invoke hresult(uint;struct*;dword;word;struct*;struct*;ptr;uint*);" Global $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc") Global $g_aSelectedRows = 0 _Test() Exit Func _Test() _WinAPI_CoInitialize($COINIT_APARTMENTTHREADED) Local Const $sCriteria = "Type='Software' and IsInstalled=0" Local $oMUS = ObjCreate("Microsoft.Update.Session") Local $oSearcher = $oMUS.CreateUpdateSearcher() Local $oCompleted, $tCompleted, $dtagISearchCompletedCallback = "InvokeSCC hresult(idispatch;ptr);" $oCompleted = __ObjectFromTag("__MyInterface_", $dtagISearchCompletedCallback, $tCompleted) ;Create Cast Tag IUpdateSearcher Local $sTagSearcher = $tagIDispatch & _Dummy("A", "", 8) & "BeginSearch hresult(bstr;ptr;variant;idispatch*);" & "EndSearch hresult(idispatch;idispatch*);" Local $oSearcherCast = ObjCreateInterface($oSearcher, "{8F45ABF1-F9AE-4B95-A933-F0F66E5056EA}", $sTagSearcher, False) Local $AsyncState = "Danyfirex Loves AutoIt" Local $oJob = 0 ;~ $oJob = $oSearcher.BeginSearch($sCriteria, $oCompleted, $Variant) ;this will not work $oSearcherCast.BeginSearch($sCriteria, $oCompleted(), $AsyncState, $oJob) ;casted to make it work While Not $oJob.IsCompleted ;wait search Sleep(100) WEnd Local $oSearchResult = 0 $oSearcherCast.EndSearch($oJob, $oSearchResult) Local $aUpdates[$oSearchResult.Updates.Count][5] Local $oCustomUpdateCollection = $oSearchResult.Updates.Copy $oCustomUpdateCollection.Clear Local $iCount = 0 For $oUpdate In $oSearchResult.Updates $aUpdates[$iCount][0] = $oUpdate.Title $aUpdates[$iCount][1] = $oUpdate.Description $aUpdates[$iCount][2] = ByteSuffix($oUpdate.MaxDownloadSize) $aUpdates[$iCount][3] = $oUpdate.MaxDownloadSize $aUpdates[$iCount][4] = $oUpdate $iCount += 1 Next _ArraySort($aUpdates, 0, 0, 0, 3) _DebugArrayDisplay($aUpdates, "Select Some Updates for Download Click ""Run User Func""", "|0:3", 0, Default, "Title|Description|Size|Size Bytes", Default, _GetSelected) If $g_aSelectedRows[0] = 0 Then Return MsgBox(0, "Info", "No Updates Selected. Script will Exit...") EndIf ;Create Update Collection For $i = 1 To $g_aSelectedRows[0] ConsoleWrite("Add Update: " & $aUpdates[$g_aSelectedRows[$i]][0] & @CRLF) $oCustomUpdateCollection.Add($aUpdates[$g_aSelectedRows[$i]][4]) Next Local $oDownloader = $oMUS.CreateUpdateDownloader() $oDownloader.Updates = $oCustomUpdateCollection Local $sTagDownloader = $tagIDispatch & _Dummy("A", "", 8) & "BeginDownload hresult(ptr;ptr;variant;idispatch*);Download hresult();EndDownload hresult(idispatch;idispatch*);" Local $oDownloaderCast = ObjCreateInterface($oDownloader, "{68F1C6F9-7ECC-4666-A464-247FE12496C3}", $sTagDownloader, False) Local $oDownloadProgress, $tDownloadProgress, $dtagIDownloadProgressChangedCallback = "Invoke_DPCC hresult(idispatch;idispatch);" $oDownloadProgress = __ObjectFromTag("__MyInterface_", $dtagIDownloadProgressChangedCallback, $tDownloadProgress) Local $oDownloadCompleted, $tDownloadCompleted, $dtagIDownloadCompletedCallback = "Invoke_DCC hresult(idispatch;ptr);" $oDownloadCompleted = __ObjectFromTag("__MyInterface_", $dtagIDownloadCompletedCallback, $tDownloadCompleted) $AsyncState = "Danyfirex Loves AutoIt Download" Local $oDownloadJob = 0 ;~ $oDownloader.BeginDownload($oDownloadProgress(), $oDownloadCompleted(), $AsyncState, $oDownloadJob) ;this will not work $oDownloaderCast.BeginDownload($oDownloadProgress(), $oDownloadCompleted(), $AsyncState, $oDownloadJob) ;casted to make it work ProgressOn("Downloading Updates", "Download Started...") While Not $oDownloadJob.IsCompleted Sleep(100) WEnd Sleep(2000) ProgressOff() Local $oDownloadResult = 0 $oDownloaderCast.EndDownload($oDownloadJob, $oDownloadResult) If $oDownloadResult.ResultCode = 2 Then MsgBox(0, "Info", "Download Completed.") Else MsgBox(0, "Info", "Download Failed.") EndIf $oDownloader = 0 $oDownloaderCast = 0 $oSearcherCast = 0 $oSearcher = 0 $oMUS = 0 EndFunc ;==>_Test Func _GetSelected($aArray, $aSelected) #forceref $aArray $g_aSelectedRows = $aSelected If $g_aSelectedRows[0] = 0 Then MsgBox(0, "", "Select one/more items. Click ""Run User Func""") Else Send("{ESC}") EndIf EndFunc ;==>_GetSelected Func ByteSuffix($iBytes) Local $iIndex = 0, $aArray = [' bytes', ' KB', ' MB', ' GB', ' TB', ' PB', ' EB', ' ZB', ' YB'] While $iBytes > 1023 $iIndex += 1 $iBytes /= 1024 WEnd Return Round($iBytes) & $aArray[$iIndex] EndFunc ;==>ByteSuffix Func _Dummy($Name, $Parameters = "", $iTimes = 1) Local $sTag = "" For $i = 1 To $iTimes $sTag &= "DM_" & $Name & $i & " hresult(" & $Parameters & ");" Next Return $sTag EndFunc ;==>_Dummy Func __ObjectFromTag($sFunctionPrefix, $tagInterface, ByRef $tInterface, $bIsUnknown = Default, $sIID = "{00000000-0000-0000-C000-000000000046}") ; last param is IID_IUnknown by default If $bIsUnknown = Default Then $bIsUnknown = True Local $sInterface = $tagInterface ; copy interface description Local $tagIUnknown = "QueryInterface hresult(ptr;ptr*);" & _ "AddRef dword();" & _ "Release dword();" ; Adding IUnknown methods If $bIsUnknown Then $tagInterface = $tagIUnknown & $tagInterface ; Below line is really simple even though it looks super complex. It's just written weird to fit in one line, not to steal your attention Local $aMethods = StringSplit(StringTrimRight(StringReplace(StringRegExpReplace(StringRegExpReplace($tagInterface, "\w+\*", "ptr"), "\h*(\w+)\h*(\w+\*?)\h*(\((.*?)\))\h*(;|;*\z)", "$1\|$2;$4" & @LF), ";" & @LF, @LF), 1), @LF, 3) Local $iUbound = UBound($aMethods) Local $sMethod, $aSplit, $sNamePart, $aTagPart, $sTagPart, $sRet, $sParams, $hCallback ; Allocation $tInterface = DllStructCreate("int RefCount;int Size;ptr Object;ptr Methods[" & $iUbound & "];int_ptr Callbacks[" & $iUbound & "];ulong_ptr Slots[16]") ; 16 pointer sized elements more to create space for possible private props If @error Then Return SetError(1, 0, 0) For $i = 0 To $iUbound - 1 $aSplit = StringSplit($aMethods[$i], "|", 2) If UBound($aSplit) <> 2 Then ReDim $aSplit[2] $sNamePart = $aSplit[0] ; Replace COM types by matching dllcallback types $sTagPart = StringReplace(StringReplace(StringReplace(StringReplace($aSplit[1], "object", "idispatch"), "hresult", "long"), "bstr", "ptr"), "variant", "ptr") $sMethod = $sFunctionPrefix & $sNamePart $aTagPart = StringSplit($sTagPart, ";", 2) $sRet = $aTagPart[0] $sParams = StringReplace($sTagPart, $sRet, "", 1) $sParams = "ptr" & $sParams $hCallback = DllCallbackRegister($sMethod, $sRet, $sParams) DllStructSetData($tInterface, "Methods", DllCallbackGetPtr($hCallback), $i + 1) ; save callback pointer DllStructSetData($tInterface, "Callbacks", $hCallback, $i + 1) ; save callback handle Next DllStructSetData($tInterface, "RefCount", 1) ; initial ref count is 1 DllStructSetData($tInterface, "Size", $iUbound) ; number of interface methods DllStructSetData($tInterface, "Object", DllStructGetPtr($tInterface, "Methods")) ; Interface method pointers Return ObjCreateInterface(DllStructGetPtr($tInterface, "Object"), $sIID, $sInterface, $bIsUnknown) ; pointer that's wrapped into object EndFunc ;==>__ObjectFromTag Func __DeleteObjectFromTag(ByRef $tInterface) For $i = 1 To DllStructGetData($tInterface, "Size") DllCallbackFree(DllStructGetData($tInterface, "Callbacks", $i)) Next $tInterface = 0 EndFunc ;==>__DeleteObjectFromTag Func __MyInterface_QueryInterface($pSelf, $pRIID, $pObj) ; Ret: long Par: ptr;ptr* Local $sIID = StringFromGUID2($pRIID) If $sIID = $sIID_IUnknown Then DllStructSetData(DllStructCreate("ptr", $pObj), 1, $pSelf) Return $S_OK ElseIf $sIID = $sIID_ISearchCompletedCallback Then DllStructSetData(DllStructCreate("ptr", $pObj), 1, $pSelf) Return $S_OK ElseIf $sIID = $sIID_IDownloadCompletedCallback Then DllStructSetData(DllStructCreate("ptr", $pObj), 1, $pSelf) Return $S_OK ElseIf $sIID = $sIID_IDownloadProgressChangedCallback Then DllStructSetData(DllStructCreate("ptr", $pObj), 1, $pSelf) Return $S_OK Else Return $E_NOINTERFACE EndIf EndFunc ;==>__MyInterface_QueryInterface Func __MyInterface_AddRef($pSelf) #forceref $pSelf Return 1 EndFunc ;==>__MyInterface_AddRef Func __MyInterface_Release($pSelf) #forceref $pSelf Return 1 EndFunc ;==>__MyInterface_Release Volatile Func __MyInterface_Invoke_SCC($pSelf, $oSearchJob, $pISearchCompletedCallbackArgs) #forceref $pSelf, $oSearchJob, $pISearchCompletedCallbackArgs ;~ ConsoleWrite("InvokeSCC - oSearchJob.AsyncState: " & $oSearchJob.AsyncState & @CRLF) Return $S_OK EndFunc ;==>__MyInterface_Invoke_SCC Volatile Func __MyInterface_Invoke_DCC($pSelf, $oDownloadJob, $pIDownloadCompletedCallbackArgs) #forceref $pSelf, $oDownloadJob, $pIDownloadCompletedCallbackArgs ;~ ConsoleWrite("InvokeDCC - $oDownloadJob.AsyncState: " & $oDownloadJob.AsyncState & @CRLF) ProgressSet(100, "Download Completed...", "Download Completed.") Return $S_OK EndFunc ;==>__MyInterface_Invoke_DCC Volatile Func __MyInterface_Invoke_DPCC($pSelf, $oDownloadJob, $oDownloadProgressChangedCallbackArgs) #forceref $pSelf ;~ ConsoleWrite("InvokeDPCC" & @CRLF) Local $iCurrentPercent = $oDownloadProgressChangedCallbackArgs.Progress.CurrentUpdatePercentComplete ProgressSet($iCurrentPercent, "(" & $iCurrentPercent & "%) " & $oDownloadJob.Updates($oDownloadProgressChangedCallbackArgs.Progress.CurrentUpdateIndex).Title, _ "Downloading Updates (" & $oDownloadProgressChangedCallbackArgs.Progress.CurrentUpdateIndex + 1 & "/" & $oDownloadJob.Updates.Count & ")") Return $S_OK EndFunc ;==>__MyInterface_Invoke_DPCC Func StringFromGUID2($pGUID) Local $aReturn = DllCall('ole32.dll', 'int', 'StringFromGUID2', 'struct*', $pGUID, 'wstr', '', 'int', 65536) If @error Or Not $aReturn[0] Then Return SetError(@error + 20, @extended, '') Return SetExtended($aReturn[0], $aReturn[2]) EndFunc ;==>StringFromGUID2 ; User's COM error function. Will be called if COM error occurs Func _ErrFunc($oError) ; Do anything here. ConsoleWrite(@ScriptName & " (" & $oError.scriptline & ") : ==> COM Error intercepted !" & @CRLF & _ @TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & _ @TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & _ @TAB & "err.description is: " & @TAB & $oError.description & @CRLF & _ @TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & _ @TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _ @TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _ @TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _ @TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _ @TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF) EndFunc ;==>_ErrFunc Even after my mod, I still get: Quote Subscript used on non-accessible variable.: If $g_aSelectedRows[0] = 0 Then If $g_aSelectedRows^ ERROR related to this: If $g_aSelectedRows[0] = 0 Then Return MsgBox(0, "Info", "No Updates Selected. Script will Exit...") EndIf Edited September 27, 2021 by mLipok Danyfirex 1 Signature beginning:* Please remember: "AutoIt"..... * Wondering who uses AutoIt and what it can be used for ? * Forum Rules ** ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Code * for other useful stuff click the following button: Spoiler Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST API * ErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) * Show_Macro_Values.au3 * My contribution to others projects or UDF based on others projects: * _sql.au3 UDF * POP3.au3 UDF * RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF * SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane * Useful links: * Forum Rules * Forum etiquette * Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * Wiki: * Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX IE Related: * How to use IE.au3 UDF with AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskScheduler * IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related: * How to get reference to PDF object embeded in IE * IE on Windows 11 * I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions * EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *I also encourage you to check awesome @trancexx code: * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuff * OnHungApp handler * Avoid "AutoIt Error" message box in unknown errors * HTML editor * winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/ "Homo sum; humani nil a me alienum puto" - Publius Terentius Afer"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming" , be and \\//_. Anticipating Errors : "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty." Signature last update: 2023-04-24 Link to comment Share on other sites More sharing options...
WilliamasKumeliukas Posted September 27, 2021 Author Share Posted September 27, 2021 (edited) 18 minutes ago, Danyfirex said: Hello. It's me again. Just to leave a whole example. expandcollapse popup#RequireAdmin #include <WinAPICom.au3> #include <Debug.au3> #include <Array.au3> Global Const $S_OK = 0x00000000 Global Const $E_NOINTERFACE = 0x80004002 Global Const $sIID_IUnknown = "{00000000-0000-0000-C000-000000000046}" Global Const $sIID_ISearchCompletedCallback = "{88AEE058-D4B0-4725-A2F1-814A67AE964C}" Global Const $sIID_IDownloadCompletedCallback = "{77254866-9F5B-4C8E-B9E2-C77A8530D64B}" Global Const $sIID_IDownloadProgressChangedCallback = "{8C3F1CDD-6173-4591-AEBD-A56A53CA77C1}" Global Const $tagIUnknown = "QueryInterface hresult(ptr;ptr*);" & _ "AddRef dword();" & _ "Release dword();" Global Const $tagIDispatch = $tagIUnknown & _ "GetTypeInfoCount hresult(dword*);" & _ "GetTypeInfo hresult(dword;dword;ptr*);" & _ "GetIDsOfNames hresult(struct*;struct*;dword;dword;struct*);" & _ "Invoke hresult(uint;struct*;dword;word;struct*;struct*;ptr;uint*);" Global $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc") Global $g_aSelectedRows = 0 _Test() Exit Func _Test() _WinAPI_CoInitialize($COINIT_APARTMENTTHREADED) Local Const $sCriteria = "Type='Software' and IsInstalled=0" Local $oMUS = ObjCreate("Microsoft.Update.Session") Local $oSearcher = $oMUS.CreateUpdateSearcher() Local $oCompleted, $tCompleted, $dtagISearchCompletedCallback = "InvokeSCC hresult(idispatch;ptr);" $oCompleted = __ObjectFromTag("__MyInterface_", $dtagISearchCompletedCallback, $tCompleted) ;Create Cast Tag IUpdateSearcher Local $sTagSearcher = $tagIDispatch & _Dummy("A", "", 8) & "BeginSearch hresult(bstr;ptr;variant;idispatch*);" & "EndSearch hresult(idispatch;idispatch*);" Local $oSearcherCast = ObjCreateInterface($oSearcher, "{8F45ABF1-F9AE-4B95-A933-F0F66E5056EA}", $sTagSearcher, False) Local $AsyncState = "Danyfirex Loves AutoIt" Local $oJob = 0 ;~ $oJob = $oSearcher.BeginSearch($sCriteria, $oCompleted, $Variant) ;this will not work $oSearcherCast.BeginSearch($sCriteria, $oCompleted(), $AsyncState, $oJob) ;casted to make it work While Not $oJob.IsCompleted ;wait search Sleep(100) WEnd Local $oSearchResult = 0 $oSearcherCast.EndSearch($oJob, $oSearchResult) Local $aUpdates[$oSearchResult.Updates.Count][5] Local $oCustomUpdateCollection = $oSearchResult.Updates.Copy $oCustomUpdateCollection.Clear Local $iCount = 0 For $oUpdate In $oSearchResult.Updates $aUpdates[$iCount][0] = $oUpdate.Title $aUpdates[$iCount][1] = $oUpdate.Description $aUpdates[$iCount][2] = ByteSuffix($oUpdate.MaxDownloadSize) $aUpdates[$iCount][3] = $oUpdate.MaxDownloadSize $aUpdates[$iCount][4] = $oUpdate $iCount += 1 Next _ArraySort($aUpdates, 0, 0, 0, 3) _DebugArrayDisplay($aUpdates, "Select Some Updates for Download Click ""Run User Func""", "|0:3", 0, Default, "Title|Description|Size|Size Bytes", Default, _GetSelected) If $g_aSelectedRows[0] = 0 Then Return MsgBox(0, "Info", "No Updates Selected. Script will Exit...") EndIf ;Create Update Collection For $i = 1 To $g_aSelectedRows[0] ConsoleWrite("Add Update: " & $aUpdates[$g_aSelectedRows[$i]][0] & @CRLF) $oCustomUpdateCollection.Add($aUpdates[$g_aSelectedRows[$i]][4]) Next Local $oDownloader = $oMUS.CreateUpdateDownloader() $oDownloader.Updates = $oCustomUpdateCollection Local $sTagDownloader = $tagIDispatch & _Dummy("A", "", 8) & "BeginDownload hresult(ptr;ptr;variant;idispatch*);Download hresult();EndDownload hresult(idispatch;idispatch*);" Local $oDownloaderCast = ObjCreateInterface($oDownloader, "{68F1C6F9-7ECC-4666-A464-247FE12496C3}", $sTagDownloader, False) Local $oDownloadProgress, $tDownloadProgress, $dtagIDownloadProgressChangedCallback = "Invoke_DPCC hresult(idispatch;idispatch);" $oDownloadProgress = __ObjectFromTag("__MyInterface_", $dtagIDownloadProgressChangedCallback, $tDownloadProgress) Local $oDownloadCompleted, $tDownloadCompleted, $dtagIDownloadCompletedCallback = "Invoke_DCC hresult(idispatch;ptr);" $oDownloadCompleted = __ObjectFromTag("__MyInterface_", $dtagIDownloadCompletedCallback, $tDownloadCompleted) Local $AsyncState = "Danyfirex Loves AutoIt Download" Local $oDownloadJob = 0 ;~ $oDownloader.BeginDownload($oDownloadProgress(), $oDownloadCompleted(), $AsyncState, $oDownloadJob) ;this will not work $oDownloaderCast.BeginDownload($oDownloadProgress(), $oDownloadCompleted(), $AsyncState, $oDownloadJob) ;casted to make it work ProgressOn("Downloading Updates", "Download Started...") While Not $oDownloadJob.IsCompleted Sleep(100) WEnd Sleep(2000) ProgressOff() Local $oDownloadResult = 0 $oDownloaderCast.EndDownload($oDownloadJob, $oDownloadResult) If $oDownloadResult.ResultCode = 2 Then MsgBox(0, "Info", "Download Completed.") Else MsgBox(0, "Info", "Download Failed.") EndIf $oDownloader = 0 $oDownloaderCast = 0 $oSearcherCast = 0 $oSearcher = 0 $oMUS = 0 EndFunc ;==>_Test Func _GetSelected($aArray, $aSelected) $g_aSelectedRows = $aSelected If $g_aSelectedRows[0] = 0 Then MsgBox(0, "", "Select one/more items. Click ""Run User Func""") Else Send("{ESC}") EndIf EndFunc ;==>_GetSelected Func ByteSuffix($iBytes) Local $iIndex = 0, $aArray = [' bytes', ' KB', ' MB', ' GB', ' TB', ' PB', ' EB', ' ZB', ' YB'] While $iBytes > 1023 $iIndex += 1 $iBytes /= 1024 WEnd Return Round($iBytes) & $aArray[$iIndex] EndFunc ;==>ByteSuffix Func _Dummy($Name, $Parameters = "", $iTimes = 1) Local $sTag = "" For $i = 1 To $iTimes $sTag &= "DM_" & $Name & $i & " hresult(" & $Parameters & ");" Next Return $sTag EndFunc ;==>_Dummy Func __ObjectFromTag($sFunctionPrefix, $tagInterface, ByRef $tInterface, $bIsUnknown = Default, $sIID = "{00000000-0000-0000-C000-000000000046}") ; last param is IID_IUnknown by default If $bIsUnknown = Default Then $bIsUnknown = True Local $sInterface = $tagInterface ; copy interface description Local $tagIUnknown = "QueryInterface hresult(ptr;ptr*);" & _ "AddRef dword();" & _ "Release dword();" ; Adding IUnknown methods If $bIsUnknown Then $tagInterface = $tagIUnknown & $tagInterface ; Below line is really simple even though it looks super complex. It's just written weird to fit in one line, not to steal your attention Local $aMethods = StringSplit(StringTrimRight(StringReplace(StringRegExpReplace(StringRegExpReplace($tagInterface, "\w+\*", "ptr"), "\h*(\w+)\h*(\w+\*?)\h*(\((.*?)\))\h*(;|;*\z)", "$1\|$2;$4" & @LF), ";" & @LF, @LF), 1), @LF, 3) Local $iUbound = UBound($aMethods) Local $sMethod, $aSplit, $sNamePart, $aTagPart, $sTagPart, $sRet, $sParams, $hCallback ; Allocation $tInterface = DllStructCreate("int RefCount;int Size;ptr Object;ptr Methods[" & $iUbound & "];int_ptr Callbacks[" & $iUbound & "];ulong_ptr Slots[16]") ; 16 pointer sized elements more to create space for possible private props If @error Then Return SetError(1, 0, 0) For $i = 0 To $iUbound - 1 $aSplit = StringSplit($aMethods[$i], "|", 2) If UBound($aSplit) <> 2 Then ReDim $aSplit[2] $sNamePart = $aSplit[0] ; Replace COM types by matching dllcallback types $sTagPart = StringReplace(StringReplace(StringReplace(StringReplace($aSplit[1], "object", "idispatch"), "hresult", "long"), "bstr", "ptr"), "variant", "ptr") $sMethod = $sFunctionPrefix & $sNamePart $aTagPart = StringSplit($sTagPart, ";", 2) $sRet = $aTagPart[0] $sParams = StringReplace($sTagPart, $sRet, "", 1) $sParams = "ptr" & $sParams $hCallback = DllCallbackRegister($sMethod, $sRet, $sParams) DllStructSetData($tInterface, "Methods", DllCallbackGetPtr($hCallback), $i + 1) ; save callback pointer DllStructSetData($tInterface, "Callbacks", $hCallback, $i + 1) ; save callback handle Next DllStructSetData($tInterface, "RefCount", 1) ; initial ref count is 1 DllStructSetData($tInterface, "Size", $iUbound) ; number of interface methods DllStructSetData($tInterface, "Object", DllStructGetPtr($tInterface, "Methods")) ; Interface method pointers Return ObjCreateInterface(DllStructGetPtr($tInterface, "Object"), $sIID, $sInterface, $bIsUnknown) ; pointer that's wrapped into object EndFunc ;==>__ObjectFromTag Func __DeleteObjectFromTag(ByRef $tInterface) For $i = 1 To DllStructGetData($tInterface, "Size") DllCallbackFree(DllStructGetData($tInterface, "Callbacks", $i)) Next $tInterface = 0 EndFunc ;==>__DeleteObjectFromTag Func __MyInterface_QueryInterface($pSelf, $pRIID, $pObj) ; Ret: long Par: ptr;ptr* Local $sIID = StringFromGUID2($pRIID) If $sIID = $sIID_IUnknown Then DllStructSetData(DllStructCreate("ptr", $pObj), 1, $pSelf) Return $S_OK ElseIf $sIID = $sIID_ISearchCompletedCallback Then DllStructSetData(DllStructCreate("ptr", $pObj), 1, $pSelf) Return $S_OK ElseIf $sIID = $sIID_IDownloadCompletedCallback Then DllStructSetData(DllStructCreate("ptr", $pObj), 1, $pSelf) Return $S_OK ElseIf $sIID = $sIID_IDownloadProgressChangedCallback Then DllStructSetData(DllStructCreate("ptr", $pObj), 1, $pSelf) Return $S_OK Else Return $E_NOINTERFACE EndIf EndFunc ;==>__MyInterface_QueryInterface Func __MyInterface_AddRef($pSelf) Return 1 EndFunc ;==>__MyInterface_AddRef Func __MyInterface_Release($pSelf) Return 1 EndFunc ;==>__MyInterface_Release Volatile Func __MyInterface_Invoke_SCC($pSelf, $oSearchJob, $pISearchCompletedCallbackArgs) ;~ ConsoleWrite("InvokeSCC - oSearchJob.AsyncState: " & $oSearchJob.AsyncState & @CRLF) Return $S_OK EndFunc ;==>__MyInterface_Invoke_SCC Volatile Func __MyInterface_Invoke_DCC($pSelf, $oDownloadJob, $pIDownloadCompletedCallbackArgs) ;~ ConsoleWrite("InvokeDCC - $oDownloadJob.AsyncState: " & $oDownloadJob.AsyncState & @CRLF) ProgressSet(100, "Download Completed...", "Download Completed.") Return $S_OK EndFunc ;==>__MyInterface_Invoke_DCC Volatile Func __MyInterface_Invoke_DPCC($pSelf, $oDownloadJob, $oDownloadProgressChangedCallbackArgs) ;~ ConsoleWrite("InvokeDPCC" & @CRLF) Local $iCurrentPercent = $oDownloadProgressChangedCallbackArgs.Progress.CurrentUpdatePercentComplete ProgressSet($iCurrentPercent, "(" & $iCurrentPercent & "%) " & $oDownloadJob.Updates($oDownloadProgressChangedCallbackArgs.Progress.CurrentUpdateIndex).Title, _ "Downloading Updates (" & $oDownloadProgressChangedCallbackArgs.Progress.CurrentUpdateIndex + 1 & "/" & $oDownloadJob.Updates.Count & ")") Return $S_OK EndFunc ;==>__MyInterface_Invoke_DPCC Func StringFromGUID2($pGUID) Local $aReturn = DllCall('ole32.dll', 'int', 'StringFromGUID2', 'struct*', $pGUID, 'wstr', '', 'int', 65536) If @error Or Not $aReturn[0] Then Return SetError(@error + 20, @extended, '') Return SetExtended($aReturn[0], $aReturn[2]) EndFunc ;==>StringFromGUID2 ; User's COM error function. Will be called if COM error occurs Func _ErrFunc($oError) ; Do anything here. ConsoleWrite(@ScriptName & " (" & $oError.scriptline & ") : ==> COM Error intercepted !" & @CRLF & _ @TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & _ @TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & _ @TAB & "err.description is: " & @TAB & $oError.description & @CRLF & _ @TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & _ @TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _ @TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _ @TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _ @TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _ @TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF) EndFunc ;==>_ErrFunc Saludos Omg @Danyfirex, your incredible! I cannot thank you enough for this great help! 12 minutes ago, mLipok said: uff... no I know why my computer do not want to install recent update Because I do not have 100GB free space on my SSD @mLipok, this is a normal bug from Microsoft, I most of the time get this 100gb update for each culmulative updates (via microsoft update session), this is a miscalculation which is not actually downloading 103gb for real Edited September 27, 2021 by WilliamasKumeliukas typos Danyfirex 1 Sorry if it's quite challenging to understand me sometimes, there is 2 possible reasons to this: Spoiler #1. I am a native French speaker and learned English mainly from chatting with others players in online games. #2. I have a developmental disorder mainly affecting my social abilities, way of thinking, understanding stuffs and explaining myself in which it can seem ironic of seeing me here, but I been working on getting better every days for an dozens of years now ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Do not like my dirty code? It's fine, but in my opinion, the dirty codes are unique and I believe it's a good glimpse of how the mind of the person who wrote it thinks, and that, that's what I call a psychological deduction step by step in all its splendor. ~WilliamasKumeliukas Link to comment Share on other sites More sharing options...
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