DonChunior Posted July 21, 2021 Share Posted July 21, 2021 I am working on a UDF for Microsoft's BITS (Background Intelligent Transfer Service). For this I use the AutoIt function ObjCreateInterface. Now the method IBackgroundCopyJob::AddFileSet causes me problems, because I have no idea how to implement it in AutoIt. For IBackgroundCopyJob::AddFile, the "little brother" of the previously mentioned method, it's easy - there my implementation looks like this: Func _BITS_BackgroundCopyJob_AddFile(Const ByRef $oBackgroundCopyJob, Const ByRef $sRemoteUrl, Const ByRef $sLocalName) $oBackgroundCopyJob.AddFile($sRemoteUrl, $sLocalName) EndFunc ;==>_BITS_BackgroundCopyJob_AddFile But how does it have to look for IBackgroundCopyJob::AddFileSet: Func _BITS_BackgroundCopyJob_AddFileSet(Const ByRef $oBackgroundCopyJob, Const ByRef $iFileCount, Const ByRef $aFileSet) $oBackgroundCopyJob.AddFileSet($iFileCount, ???) EndFunc ;==>_BITS_BackgroundCopyJob_AddFileSet For example, $aFileSet looks like this: Local $aFileSet[][] = [["RemoteName1", "LocalName1"], ["RemoteName2", "LocalName2"], ["RemoteName3", "LocalName3"]] Link to comment Share on other sites More sharing options...
Nine Posted July 21, 2021 Share Posted July 21, 2021 Try something like this : #include <WinAPIDiag.au3> Local $aFileSet[][] = [["RemoteName1", "LocalName1"], ["RemoteName2", "LocalName2"], ["RemoteName3", "LocalName3"]] Local $sStructDef For $i = 0 To UBound($aFileSet) - 1 $sStructDef &= "char r" & $i+1 & "[" & StringLen($aFileSet[$i][0])+1 & "];char l" & $i+1 & "[" & StringLen($aFileSet[$i][1])+1 & "];" Next ConsoleWrite($sStructDef & @CRLF) $tStruct = DllStructCreate($sStructDef) For $i = 0 To UBound($aFileSet) - 1 DllStructSetData($tStruct, "r" & $i+1, $aFileSet[$i][0]) DllStructSetData($tStruct, "l" & $i+1, $aFileSet[$i][1]) Next _WinAPI_DisplayStruct($tStruct, $sStructDef) $pStruct = DllStructGetPtr($tStruct) DonChunior 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
DonChunior Posted July 22, 2021 Author Share Posted July 22, 2021 @Nine, thanks for the tip - this looks promising! I will test the solution as soon as possible. Link to comment Share on other sites More sharing options...
DonChunior Posted July 22, 2021 Author Share Posted July 22, 2021 @Nine, I tried to implement the method with your suggestion. You can find the corresponding state of the UDF here: https://github.com/DonChunior/BITS-UDF/tree/AddFileSet Unfortunately the code does not work: In the SciTE console the error message "AutoIt3.exe ended.rc:-1073741819" is displayed. 😕 Do you have any idea what could be the cause of the problem? You could test the implementation of the AddFileSet method with the following sample code: #include <BITS.au3> Main() Func Main() Local $oBackgroundCopyManager = _BITS_Connect() Local $oJob = _BITS_BackgroundCopyManager_CreateJob($oBackgroundCopyManager, "Test_Job", $BG_JOB_TYPE_DOWNLOAD) Local $aFileSet = [["http://ipv4.download.thinkbroadband.com/1GB.zip", "C:\Temp\1GB.zip"], ["http://ipv4.download.thinkbroadband.com/512MB.zip", "C:\Temp\512MB.zip"]] _BITS_BackgroundCopyJob_AddFileSet($oJob, $aFileSet) EndFunc Link to comment Share on other sites More sharing options...
Nine Posted July 22, 2021 Share Posted July 22, 2021 So AutoIt3 is crashing...If it is not the actual strings then it must be pointers to string. So the struct should be "ptr;ptr;ptr;ptr;" (for 2 sets). Each pointer points to a string. ps. I tested with my code and it is crashing passing actual strings. But it is not crashing using ptr to string. However when I resume the job, it doesn't start downloading...Maybe I am missing something. “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
Danyfirex Posted July 22, 2021 Share Posted July 22, 2021 (edited) Hello. Use LPWSTR. PD: Your struct should be an array of BG_FILE_INFO pointers. Edit: I meant this in the @Nine's code: Local $tBGFileInfo=DllStructCreate("ptr[" & UBound($aFileSet) & "]") $tStruct = DllStructCreate($sStructDef) For $i = 0 To UBound($aFileSet) - 1 DllStructSetData($tStruct, "r" & $i+1, $aFileSet[$i][0]) DllStructSetData($tStruct, "l" & $i+1, $aFileSet[$i][1]) DllStructSetData($tBGFileInfo,1, DllStructGetPtr($tStruct,"r" & $i+1),$i+1) Next Local $pStruct = DllStructGetPtr($tBGFileInfo) Saludos Edited July 22, 2021 by Danyfirex Add Code 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...
TheXman Posted July 22, 2021 Share Posted July 22, 2021 (edited) @DonChunior I haven't looked through your whole bits.au3 udf file, but I do see one issue. Your definition if the BG_FILE_INFO struct is not correct. You aren't currently using it in your UDF but when/if you do, it will cause problems as it is currently defined. It is currently defined as: ; BG_FILE_INFO structure (https://docs.microsoft.com/en-us/windows/win32/api/bits/ns-bits-bg_file_info) Global Const $tagBG_FILE_INFO = "struct;wchar remoteName[2201];wchar localName[261];endstruct" it should be something like: Const $tagBG_FILE_INFO = _ "struct; " & _ "ptr remoteName;" & _ "ptr localName;" & _ "endstruct;" Below is a quick example that I created that will create an array of BG_FILE_INFO structs. It is based on an interpretation of the AddFileSet example code from the Microsoft site. It is commented pretty well but does not have any error checking. It is just a quick script to show another way that the struct array can be created. Because AutoIt does not make it easy to get pointer information of normally declared variables, the next best thing is to declare structs to hold the variables. That will give you access to their pointers. So as you will see, in order to get pointers to the remote and local names of the file set, I create an array of structs for the names. Other than that, the code should be pretty straight forward. I haven't tested it with your UDF. I'll leave that part of the fun to you. expandcollapse popup#AutoIt3Wrapper_AU3Check_Parameters=-w 3 -w 4 -w 5 -w 6 -d #include <Constants.au3> #include <WinAPIDiag.au3> #include <Array.au3> Const $gtagBG_FILE_INFO = _ "struct; " & _ "ptr remoteName;" & _ "ptr localName;" & _ "endstruct;" Global $gaFileSet = _ [ _ ["http://ipv4.download.thinkbroadband.com/1GB.zip", "C:\Temp\1GB.zip"], _ ["http://ipv4.download.thinkbroadband.com/512MB.zip", "C:\Temp\512MB.zip"] _ ] Global $gtBG_FILE_INFO_ARRAY = "" ;Get BG_FILE_INFO_ARRAY $gtBG_FILE_INFO_ARRAY = get_bg_file_info_array_struct_example($gaFileSet) ;Display BG_FILE_INFO_ARRAY _WinAPI_DisplayStruct( _ $gtBG_FILE_INFO_ARRAY, _ StringFormat("ptr[%i]", UBound($gaFileSet) * 2), _ "BG_FILE_INFO Array" _ ) Func get_bg_file_info_array_struct_example($aFileSet) Local $tBG_FILE_INFO = "", $tByteBuffer = "", $tBG_FILE_INFO_ARRAY = "" Local $iBG_FILE_INFO_SIZE = 0 Local $pArrayItemPointer = 0 Local $xWcharString = Binary("") Local $atRemoteNames[0], $atLocalNames[0] ;For each file set For $i = 0 To UBound($aFileSet) - 1 ;Add remote name to array of remote name structs $xWcharString = StringToBinary($aFileSet[$i][0], $SB_UTF16LE) $tByteBuffer = DllStructCreate(StringFormat("byte data[%i];", BinaryLen($xWcharString))) $tByteBuffer.data = $xWcharString _ArrayAdd($atRemoteNames, $tByteBuffer) ;Add local name to array of local name structs $xWcharString = StringToBinary($aFileSet[$i][1], $SB_UTF16LE) $tByteBuffer = DllStructCreate(StringFormat("byte data[%i];", BinaryLen($xWcharString))) $tByteBuffer.data = $xWcharString _ArrayAdd($atLocalNames, $tByteBuffer) Next ;Create a bg_file_info struct to get size of struct $tBG_FILE_INFO = DllStructCreate($gtagBG_FILE_INFO) $iBG_FILE_INFO_SIZE = DllStructGetSize($tBG_FILE_INFO) ;Create byte buffer to hold array of bg_file_info structs $tBG_FILE_INFO_ARRAY = DllStructCreate(StringFormat("byte buffer[%i]", $iBG_FILE_INFO_SIZE * UBound($aFileSet))) ;For each file set For $i = 0 To UBound($aFileSet) - 1 ;Add a populated bg_file_info struct to the array of bg_file_info structs $pArrayItemPointer = DllStructGetPtr($tBG_FILE_INFO_ARRAY) + ($iBG_FILE_INFO_SIZE * $i) $tBG_FILE_INFO = DllStructCreate($gtagBG_FILE_INFO, $pArrayItemPointer) $tBG_FILE_INFO.remoteName = DllStructGetPtr($atRemoteNames[$i]) $tBG_FILE_INFO.localName = DllStructGetPtr($atLocalNames[$i]) Next ;Sanity check - Display values from the bg_file_info array to make sure they were loaded properly For $i = 0 To UBound($aFileSet) - 1 ;Point to bg_file_info struct item within the bg_file_info array $pArrayItemPointer = DllStructGetPtr($tBG_FILE_INFO_ARRAY) + ($iBG_FILE_INFO_SIZE * $i) $tBG_FILE_INFO = DllStructCreate($gtagBG_FILE_INFO, $pArrayItemPointer) ;Get & display the remote name pointed to by the remote name pointer $tByteBuffer = DllStructCreate("byte data[1000];", $tBG_FILE_INFO.remoteName) ConsoleWrite(StringFormat("Remote name %2i = %s", $i + 1, BinaryToString($tByteBuffer.data, $SB_UTF16LE)) & @CRLF) ;Get & display the local name pointed to by the local name pointer $tByteBuffer = DllStructCreate("byte data[1000];", $tBG_FILE_INFO.localName) ConsoleWrite(StringFormat("Local name %2i = %s", $i + 1, BinaryToString($tByteBuffer.data, $SB_UTF16LE)) & @CRLF) Next Return $tBG_FILE_INFO_ARRAY EndFunc Console output: (this output was just a sanity check for me to know that the information in the arrays were correct) Remote name 1 = http://ipv4.download.thinkbroadband.com/1GB.zip Local name 1 = C:\Temp\1GB.zip Remote name 2 = http://ipv4.download.thinkbroadband.com/512MB.zip Local name 2 = C:\Temp\512MB.zip Edited July 22, 2021 by TheXman Smalll cosmetic change to the script Danyfirex and DonChunior 2 CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
Solution Nine Posted July 22, 2021 Solution Share Posted July 22, 2021 (edited) TheXman code did not work for me. Although this one is working perfectly fine : ... Local $oBackgroundCopyJob = ObjCreateInterface($pJob, $sIID_IBackgroundCopyJob, $tagIBackgroundCopyJob) ConsoleWrite(VarGetType($oBackgroundCopyJob) & @CRLF) ;$oBackgroundCopyJob.AddFile("http://www.autoitscript.com/autoit3/files/beta/update.dat", @ScriptDir & "\Test.tmp") Local $aFile = [["http://ipv4.download.thinkbroadband.com/5MB.zip", @ScriptDir & "\Test1.zip"], _ ["http://www.autoitscript.com/autoit3/files/beta/update.dat", @ScriptDir & "\Test2.txt"]] AddFileSet($oBackgroundCopyJob, $aFile) $oBackgroundCopyJob.Resume() ... Func AddFileSet(ByRef $obj, ByRef $aFileSet) Local $sStructDef = _StringRepeat("ptr;", UBound($aFileSet) * 2) Local $tStruct = DllStructCreate($sStructDef) Local $tFileInfo1[UBound($aFileSet)], $tFileInfo2[UBound($aFileSet)] For $i = 0 to UBound($aFileSet) - 1 $tFileInfo1[$i] = DllStructCreate("wchar[" & StringLen($aFileSet[$i][0]) + 1 & "];") $tFileInfo2[$i] = DllStructCreate("wchar[" & StringLen($aFileSet[$i][1]) + 1 & "];") DllStructSetData($tFileInfo1[$i], 1, $aFileSet[$i][0]) DllStructSetData($tFileInfo2[$i], 1, $aFileSet[$i][1]) DllStructSetData($tStruct, $i*2+1, DllStructGetPtr($tFileInfo1[$i])) DllStructSetData($tStruct, $i*2+2, DllStructGetPtr($tFileInfo2[$i])) Next _WinAPI_DisplayStruct($tStruct, $sStructDef) $obj.AddFileSet(UBound($aFileSet), $tStruct) EndFunc Edited July 22, 2021 by Nine Danyfirex and DonChunior 1 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
DonChunior Posted July 23, 2021 Author Share Posted July 23, 2021 Thank you all for the tips, I really appreciate your knowledge. 👍@Nine, a special thanks to you for giving me the solution on a silver platter! 😎 Link to comment Share on other sites More sharing options...
Nine Posted July 23, 2021 Share Posted July 23, 2021 Glad you liked it. To be honest, I was happy to find a streamlined solution to your issue. “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy 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