Jump to content

Convert GetRef function from VBScript to AutoIt


WilliamasKumeliukas
 Share

Recommended Posts

@mLipok I don't get Subscript used on non-accessible variable.:. issue🤔

 

@WilliamasKumeliukas You're welcome. 😊

 

Saludos

 

 

Link to comment
Share on other sites

Just now, Danyfirex said:

@mLipok I don't get Subscript used on non-accessible variable.:. issue🤔

 

@WilliamasKumeliukas You're welcome. 😊

 

Saludos

 

 

@Danyfirex I get same error as mLipok but my first thought about it is I don't have any updates to do so I am guessing the variable is empty since it didn't ever receive data since there is no updates.  (I might be wrong, I didn't really verify before posting).

Best 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

here my little modification which solve the issue:

If IsArray($g_aSelectedRows) = 0 Or $g_aSelectedRows[0] = 0 Then
        Return MsgBox(0, "Info", "No Updates Selected. Script will Exit...")
    EndIf

 

Best 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

It may be You're not clicking the user define button in _DebugArrayDisplay.

Declare $g_aSelectedRows like Global $g_aSelectedRows[1]  on top instead Global $g_aSelectedRows = 0 to fix the issue.

 

Saludos

Link to comment
Share on other sites

11 minutes ago, Danyfirex said:

It may be You're not clicking the user define button in _DebugArrayDisplay.

Declare $g_aSelectedRows like Global $g_aSelectedRows[1]  on top instead Global $g_aSelectedRows = 0 to fix the issue.

 

Saludos

I didn't see the _DebugArrayDisplay pop-up before it prompt this error,  since it woult only pop up when there is at least 1 update available.

(I tested your solution and I can confirm it also work)

Best Regards,

WilliamasKumeliukas

Edited 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

I went to test here and didn't find the update file that was downloaded, where does the update download go?

Link to comment
Share on other sites

@Belini

In Windows 10 I see them here. 

C:\Windows\SoftwareDistribution\Download

 

Saludos

Link to comment
Share on other sites

6 minutes ago, Belini said:

I went to test here and didn't find the update file that was downloaded, where does the update download go?

@Belini, it download install updates the same way as official Windows Update from Windows settings (Win 10) or Wuapp (Win 7)

 

Best Regards,

WilliamasKumeliukas

Edited 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

@Danyfirex, I noticed in your code there is a missing search criteria at line 60:

Local Const $sCriteria = "Type='Software' and IsInstalled=0"

in VBScript I had to mention AutoSelectOnWebsite=1 otherwise GetRef return Null😕

so I'm quite curious of how your code could get through this step without this criteria.

(Sorry in advance if the way I said it is confusing, I didn't find any better way to be more clear)

 

Best 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

I really don't know (probably it returns update in must of the criteria cases to me due to I never update my windows I have all updates disable). I just put first criteria I see online. anyway you can learn more about criterias here.

 

Saludos

Link to comment
Share on other sites

@Danyfirex your code only work for me when I select Beta run otherwise I get this error:

"C:\Program Files (x86)\AutoIt3\Include\ArrayDisplayInternals.au3" (343) : ==> Variable subscript badly formatted.:
$vTmp = $aArray[$i][$j]
$vTmp = $aArray[^ ERROR

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

Link to comment
Share on other sites

1 hour ago, Danyfirex said:

What AutoIt version do you use?

 

Saludos

3.3.14.5

I didn't modify original includes and if I did, It was cloned in another folder outside of AutoIt installation folder using different file name as well to avoid confusion.

Edited 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

I'm using same. It's weird that  you get the issue. could you show the exactly code you're running.

 

Saludos

Link to comment
Share on other sites

Just now, Danyfirex said:

I'm using same. It's weird that  you get the issue. could you show the exactly code you're running.

 

Saludos

I've tested from scratch with your whole example code and same issue ( it didnt work either yesterday, I had forgot to mention this)

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

I'll add a code with some debug log to be sure about the issue/result.

Code:

Writing...

 

Saludos

Link to comment
Share on other sites

Updated:

;~ 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[1]

_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
    Local $iSearchResult = $oSearcherCast.EndSearch($oJob, $oSearchResult)
    ConsoleWrite("(" & @ScriptLineNumber & ")" & @TAB & "$oSearcherCast.EndSearch: " & Hex($iSearchResult) & @CRLF)

    If Not IsObj($oSearchResult) Or $oSearchResult.Updates.Count = 0 Then
        Return MsgBox(0, "Info", "No Updates Result. Script will Exit...")
    EndIf

    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)
    ConsoleWrite("(" & @ScriptLineNumber & ")" & @TAB & "UBound($aUpdates): " & UBound($aUpdates) & @CRLF)
    _DebugArrayDisplay($aUpdates, "Select Some Updates for Download Click ""Run User Func""", "|0:3", 0, Default, "Title|Description|Size|Size Bytes", Default, _GetSelected)
    ConsoleWrite("(" & @ScriptLineNumber & ")" & @TAB & "UBound($aUpdates): " & UBound($aUpdates) & @CRLF)
    ConsoleWrite("(" & @ScriptLineNumber & ")" & @TAB & "UBound($g_aSelectedRows): " & UBound($g_aSelectedRows) & @CRLF)

    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

    ConsoleWrite("(" & @ScriptLineNumber & ")" & @TAB & "$oCustomUpdateCollection.Count: " & $oCustomUpdateCollection.Count & @CRLF)

    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
    Local $iDownloadResult = $oDownloaderCast.EndDownload($oDownloadJob, $oDownloadResult)
    ConsoleWrite("(" & @ScriptLineNumber & ")" & @TAB & "$oDownloaderCast.EndDownload: " & Hex($iDownloadResult) & @CRLF)

    If $oDownloadResult.ResultCode = 2 Then
        ConsoleWrite("(" & @ScriptLineNumber & ")" & @TAB & "$oDownloadResult.ResultCode: " & Hex($oDownloadResult.ResultCode) & @CRLF)
        MsgBox(0, "Info", "Download Completed.")
    Else
        ConsoleWrite("(" & @ScriptLineNumber & ")" & @TAB & "$oDownloadResult.ResultCode: " & Hex($oDownloadResult.ResultCode) & @CRLF)
        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

Saludos

Link to comment
Share on other sites

35 minutes ago, Danyfirex said:

Updated:

;~ 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[1]

_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
    Local $iSearchResult = $oSearcherCast.EndSearch($oJob, $oSearchResult)
    ConsoleWrite("(" & @ScriptLineNumber & ")" & @TAB & "$oSearcherCast.EndSearch: " & Hex($iSearchResult) & @CRLF)

    If Not IsObj($oSearchResult) Or $oSearchResult.Updates.Count = 0 Then
        Return MsgBox(0, "Info", "No Updates Result. Script will Exit...")
    EndIf

    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)
    ConsoleWrite("(" & @ScriptLineNumber & ")" & @TAB & "UBound($aUpdates): " & UBound($aUpdates) & @CRLF)
    _DebugArrayDisplay($aUpdates, "Select Some Updates for Download Click ""Run User Func""", "|0:3", 0, Default, "Title|Description|Size|Size Bytes", Default, _GetSelected)
    ConsoleWrite("(" & @ScriptLineNumber & ")" & @TAB & "UBound($aUpdates): " & UBound($aUpdates) & @CRLF)
    ConsoleWrite("(" & @ScriptLineNumber & ")" & @TAB & "UBound($g_aSelectedRows): " & UBound($g_aSelectedRows) & @CRLF)

    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

    ConsoleWrite("(" & @ScriptLineNumber & ")" & @TAB & "$oCustomUpdateCollection.Count: " & $oCustomUpdateCollection.Count & @CRLF)

    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
    Local $iDownloadResult = $oDownloaderCast.EndDownload($oDownloadJob, $oDownloadResult)
    ConsoleWrite("(" & @ScriptLineNumber & ")" & @TAB & "$oDownloaderCast.EndDownload: " & Hex($iDownloadResult) & @CRLF)

    If $oDownloadResult.ResultCode = 2 Then
        ConsoleWrite("(" & @ScriptLineNumber & ")" & @TAB & "$oDownloadResult.ResultCode: " & Hex($oDownloadResult.ResultCode) & @CRLF)
        MsgBox(0, "Info", "Download Completed.")
    Else
        ConsoleWrite("(" & @ScriptLineNumber & ")" & @TAB & "$oDownloadResult.ResultCode: " & Hex($oDownloadResult.ResultCode) & @CRLF)
        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

Saludos

using this code, it doesn't generate any error and return:

(54)    $oSearcherCast.EndSearch: 00000000

giving the result I would get using beta version with your first code

Edited 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

So probably you need to use different criteria. I think beta and stable AutoIt version is not affecting the search.  

Saludos

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...