Jump to content

Background Intelligent Transfer Service (BITS)


Go to solution Solved by Nine,

Recommended Posts

30 minutes ago, DonChunior said:

As far as I understood, there is a COM interface for BITS.

If that is your understanding, where did that understanding come from?  Were there no references to the COM object from where you got that understanding? :huh2:  Maybe you can get a better understanding from the following links:

BITS Provider

BITS Compact Server

Using WMI Windows PowerShell Cmdlets to Manage the BITS Compact Server

 

Edited by TheXman
Link to comment
Share on other sites

  • Solution

Looks more that it is an interface where you would use ObjCreateInterface instead.

IBackgroundCopyManager seems to be the root of the interface.  The object is successfully created with :

$CLSID_BackgroundCopyManager = "{4991d34b-80a1-4291-83b6-3328366b9097}"
$IID_IBackgroundCopyManager = "{5ce34c0d-0dc9-4c1f-897c-daa1b78cee7c}"
$tagBackgroundCopyManager = "CreateJob hresult(str,int,struct*,ptr*); EnumJobs hresult(dword,ptr*);GetErrorDescription hresult(hresult,dword,str*); GetJob hresult(struct,ptr*)"
$oBits = ObjCreateInterface($CLSID_BackgroundCopyManager, $IID_IBackgroundCopyManager, $tagBackgroundCopyManager)

MsgBox ($MB_SYSTEMMODAL,"",IsObj($oBits))

 

Edited by Nine
Link to comment
Share on other sites

5 hours ago, TheXman said:

If that is your understanding, where did that understanding come from?  Were there no references to the COM object from where you got that understanding? :huh2:  Maybe you can get a better understanding from the following links:

BITS Provider

BITS Compact Server

Using WMI Windows PowerShell Cmdlets to Manage the BITS Compact Server

 

Hello @TheXman,

my assumption that there is a COM interface comes from the page "Calling into BITS from .NET and C# using Reference DLLs".
The first paragraph of this page talks about COM classes.

Edited by DonChunior
Added the link to the website.
Link to comment
Share on other sites

4 hours ago, Danp2 said:

@DonChunior Did you mean to put this into the AutoitX section?

Hello @Danp2,

yes, I thought that the board "AutoItX Help and Support" was the right place for my question
There it says "Support for the COM, DLL, PowerShell and .NET add-ons for AutoIt".
Did I misunderstand something and posted in the wrong board?

Link to comment
Share on other sites

4 minutes ago, DonChunior said:

Did I misunderstand something and posted in the wrong board?

I think so... from the AutoitX help file --

Quote

AutoItX is a DLL version of AutoIt v3 that provides a subset of the features of AutoIt via an ActiveX/COM and DLL interface. This means that you can add AutoIt-like features to your favourite scripting and programming languages, e.g. VB, VBScript, Delphi, C, C++, Kixtart, and most other languages that support the use of DLLs.

It appears that your are using Autoit, not AutoitX. It's not a big deal though. I'll report the thread to have one of the admin's move it. 😀

Link to comment
Share on other sites

5 hours ago, Nine said:

Looks more that it is an interface where you would use ObjCreateInterface instead.

IBackgroundCopyManager seems to be the root of the interface.  The object is successfully created with :

$CLSID_BackgroundCopyManager = "{4991d34b-80a1-4291-83b6-3328366b9097}"
$IID_IBackgroundCopyManager = "{5ce34c0d-0dc9-4c1f-897c-daa1b78cee7c}"
$tagBackgroundCopyManager = "CreateJob hresult(str,int,struct*,ptr*); EnumJobs hresult(dword,ptr*);GetErrorDescription hresult(hresult,dword,str*); GetJob hresult(struct,ptr*)"
$oBits = ObjCreateInterface($CLSID_BackgroundCopyManager, $IID_IBackgroundCopyManager, $tagBackgroundCopyManager)

MsgBox ($MB_SYSTEMMODAL,"",IsObj($oBits))

 

Hello @Nine,

thanks for the hint, I try to build on that!
This brings up a few more questions for me:
How did you come to the conclusion that ObjCreateInterface() should be used instead of ObjCreate()?
And how did you find out which CLSID and IID to use? I tried to find the corresponding information in the "OLE/COM Object Viewer" but couldn't find it.

Link to comment
Share on other sites

The documentation link you provided shows it is an interface, not a COM object.

I found the GUIDs on a few places, just google CLSID BackgroundCopyManager.  Not too hard to find.  I rarely used object viewer as I rarely find what I am searching. ;)

I tried the CreateJob method, without success tho.  Maybe I am missing something.  Let me know if you got it working.

Link to comment
Share on other sites

  • 4 weeks later...

I have made some progress, but I still stumble.

With the code below I manage to derive an object from the COM interface IBackgroundCopyManager and to create a job with the method CreateJob() (recognizable by typing the command "BITSADMIN /LIST" in the command line window), but e.g. I cannot cancel it anymore.
The last line of the Main() function causes the following error to be displayed in the Scite console: "AutoIt3.exe ended.rc:-1073741819".

Does anyone of you know what I did wrong?

; AU3Check settings
#AutoIt3Wrapper_Run_AU3Check=Y
#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7
#AutoIt3Wrapper_AU3Check_Stop_OnWarning=Y

Global Enum _
        $__BITSCONSTANT_BG_JOB_TYPE_DOWNLOAD, _
        $__BITSCONSTANT_BG_JOB_TYPE_UPLOAD, _
        $__BITSCONSTANT_BG_JOB_TYPE_UPLOAD_REPLY

; Background Intelligent Transfer Control Class 10.3
Global Const $sCLSID_BackgroundCopyManager = "{5FD42AD5-C04E-4D36-ADC7-E08FF15737AD}"
Global Const $sIID_IBackgroundCopyManager = "{5CE34C0D-0DC9-4C1F-897C-DAA1B78CEE7C}"
Global Const $sTagIBackgroundCopyManager = "CreateJob hresult(wstr;int;clsid*;ptr*);" & _
        "EnumJobs hresult(dword;ptr*);" & _
        "GetErrorDescription hresult(hresult;dword;wstr*);" & _
        "GetJob hresult(clsid;ptr*);"

Global Const $sIID_IBackgroundCopyJob = "{37668D37-507E-4160-9316-26306D150B12}"
Global Const $sTagIBackgroundCopyJob = "AddFile hresult(wstr;wstr);" & _
        "AddFileSet hresult(ulong;struct*);" & _
        "Cancel hresult();" & _
        "Complete hresult();" & _
        "EnumFiles hresult(ptr*);" & _
        "GetDescription hresult(wstr*);" & _
        "GetDisplayName hresult(wstr*);" & _
        "GetError hresult(ptr*);" & _
        "GetErrorCount hresult(ulong_ptr*);" & _
        "GetId hresult(clsid*);" & _
        "GetMinimumRetryDelay hresult(ulong_ptr*);" & _
        "GetNoProgressTimeout hresult(ulong_ptr*);" & _
        "GetNotifyFlags hresult(ulong_ptr*);" & _
        "GetNotifyInterface hresult(ptr*);" & _
        "GetOwner hresult(wstr*);" & _
        "GetPriority hresult(int*);" & _
        "GetProgress hresult(struct*);" & _
        "GetProxySettings hresult(int*;wstr*;wstr*);" & _
        "GetState hresult(int*);" & _
        "GetTimes hresult(struct*);" & _
        "GetType hresult(int*);" & _
        "Resume hresult();" & _
        "SetDescription hresult(wstr);" & _
        "SetDisplayName hresult(wstr);" & _
        "SetMinimumRetryDelay hresult(ulong);" & _
        "SetNoProgressTimeout hresult(ulong);" & _
        "SetNotifyFlags hresult(ulong);" & _
        "SetNotifyInterface hresult(ptr);" & _
        "SetPriority hresult(int);" & _
        "SetProxySettings hresult(int;str*;str*);" & _
        "Suspend hresult();" & _
        "TakeOwnership hresult();"

Main()

Func Main()
    Local $oBackgroundCopyManager = ObjCreateInterface($sCLSID_BackgroundCopyManager, $sIID_IBackgroundCopyManager, $sTagIBackgroundCopyManager)


    Local $sJobId = ""
    Local $pJob = 0
    $oBackgroundCopyManager.CreateJob("DonChuniorTestJob", $__BITSCONSTANT_BG_JOB_TYPE_DOWNLOAD, $sJobId, $pJob)
    ConsoleWrite($sJobId & @CRLF)
    ConsoleWrite(VarGetType($pJob) & @CRLF)

    Local $oBackgroundCopyJob = ObjCreateInterface($pJob, $sIID_IBackgroundCopyJob, $sTagIBackgroundCopyJob)
    ConsoleWrite(VarGetType($oBackgroundCopyJob) & @CRLF)
    $oBackgroundCopyJob.Cancel()
EndFunc   ;==>Main

 

Link to comment
Share on other sites

Hmmm, unfortunately, your CLSID does not work for me. It does not create an object.  What is your environment ?  Did you do something to make it work ?

The order of your methods seems highly suspicious.  They are in alpha order which is rarely the case.  If you look at my tag ($tagBackgroundCopyManager) this is the right order.  MSDN does not provide the true order.  So be careful.  This is probably why your cancel is not working as it call the wrong method.

Edited by Nine
Link to comment
Share on other sites

12 minutes ago, Nine said:

Hmmm, unfortunately, your CLSID does not work for me. It does not create an object.  What is your environment ?  Did you do something to make it work ?

The order of your methods seems highly suspicious.  They are in alpha order which is rarely the case.  If you look at my tag ($tagBackgroundCopyManager) this is the right order.  MSDN does not provide the true order.  So be careful.  This is probably why your cancel is not working as it call the wrong method.

I used the latest BITS version 10.3, which is available since Windows 10 May 2019 Update (10.0; Build 18362).
The version history can be found under the following link: https://docs.microsoft.com/en-us/windows/win32/bits/what-s-new
Could you try BITS version 10.1 (CLSID = {4BD3E4E1-7BD4-4A2B-9964-496400DE5193} and IID = {5CE34C0D-0DC9-4C1F-897C-DAA1B78CEE7C})?

Right, the order I chose is simply alphabetical.
How do you get the correct order (if you can't be asked)? 😉

Link to comment
Share on other sites

Link to comment
Share on other sites

Ok it is working now with a this CLSID :

Global Enum $BG_JOB_TYPE_DOWNLOAD, $BG_JOB_TYPE_UPLOAD, $BG_JOB_TYPE_UPLOAD_REPLY

Global Const $sCLSID_BackgroundCopyManager = "{659cdea7-489e-11d9-a9cd-000d56965251}" ; 2.5
;Global Const $sCLSID_BackgroundCopyManager = "{5FD42AD5-C04E-4D36-ADC7-E08FF15737AD}" ; 10.3
Global Const $sIID_IBackgroundCopyManager = "{5CE34C0D-0DC9-4C1F-897C-DAA1B78CEE7C}"
Global Const $tagBackgroundCopyManager = _
    "CreateJob hresult(wstr;int;clsid*;ptr*);" & _
    "GetJob hresult(clsid;ptr*);" & _
    "EnumJobs hresult(dword,ptr*);" & _
    "GetErrorDescription hresult(hresult,dword,str*)"

Global Const $sIID_IBackgroundCopyJob = "{37668D37-507E-4160-9316-26306D150B12}"
Global Const $tagIBackgroundCopyJob = _
    "AddFileSet hresult(ulong;struct*);" & _
    "AddFile hresult(wstr;wstr);" & _
    "EnumFiles hresult(ptr*);" & _
    "Suspend hresult();" & _
    "Resume hresult();" & _
    "Cancel hresult();" & _
    "Complete hresult();" & _
    "GetId hresult(clsid*);" & _
    "GetType hresult(int*);" & _
    "GetProgress hresult(struct*);" & _
    "GetTimes hresult(struct*);" & _
    "GetState hresult(int*);" & _
    "GetError hresult(ptr*);" & _
    "GetOwner hresult(wstr*);" & _
    "SetDisplayName hresult(wstr);" & _
    "GetDisplayName hresult(wstr*);" & _
    "SetDescription hresult(wstr);" & _
    "GetDescription hresult(wstr*);" & _
    "SetPriority hresult(int);" & _
    "GetPriority hresult(int*);" & _
    "SetNotifyFlags hresult(ulong);" & _
    "GetNotifyFlags hresult(ulong_ptr*);" & _
    "SetNotifyInterface hresult(ptr);" & _
    "GetNotifyInterface hresult(ptr*);" & _
    "SetMinimumRetryDelay hresult(ulong);" & _
    "GetMinimumRetryDelay hresult(ulong_ptr*);" & _
    "SetNoProgressTimeout hresult(ulong);" & _
    "GetNoProgressTimeout hresult(ulong_ptr*);" & _
    "GetErrorCount hresult(ulong_ptr*);" & _
    "SetProxySettings hresult(int;str*;str*);" & _
    "GetProxySettings hresult(int*;wstr*;wstr*);" & _
    "TakeOwnership hresult();"

Main()

Func Main()
  Local $oBackgroundCopyManager = ObjCreateInterface($sCLSID_BackgroundCopyManager, $sIID_IBackgroundCopyManager, $tagBackgroundCopyManager)
  ConsoleWrite (IsObj($oBackgroundCopyManager) & @CRLF)
  Local $sJobId = ""
  Local $pJob = 0
  ConsoleWrite ("create job " & $oBackgroundCopyManager.CreateJob("TestCreationJob", $BG_JOB_TYPE_DOWNLOAD, $sJobId, $pJob) & @CRLF)
  ConsoleWrite($sJobId & @CRLF)
  ConsoleWrite(VarGetType($pJob) & @CRLF)

  Local $oBackgroundCopyJob = ObjCreateInterface($pJob, $sIID_IBackgroundCopyJob, $tagIBackgroundCopyJob)
  ConsoleWrite(VarGetType($oBackgroundCopyJob) & @CRLF)

  MsgBox ($MB_SYSTEMMODAL,"","check")

  ConsoleWrite ("cancel " & $oBackgroundCopyJob.Cancel() & @CRLF)
EndFunc   ;==>Main

 

Link to comment
Share on other sites

@DonChunior  I was able to DL a file.  The problem you where facing was certainly the wrong order of the methods.

The full script :

Spoiler
#include <Constants.au3>

Global Enum $BG_JOB_TYPE_DOWNLOAD, $BG_JOB_TYPE_UPLOAD, $BG_JOB_TYPE_UPLOAD_REPLY
Global enum $BG_JOB_STATE_QUEUED, $BG_JOB_STATE_CONNECTING, $BG_JOB_STATE_TRANSFERRING, $BG_JOB_STATE_SUSPENDED, $BG_JOB_STATE_ERROR, _
  $BG_JOB_STATE_TRANSIENT_ERROR, $BG_JOB_STATE_TRANSFERRED, $BG_JOB_STATE_ACKNOWLEDGED, $BG_JOB_STATE_CANCELLED

Global Const $sCLSID_BackgroundCopyManager = "{659cdea7-489e-11d9-a9cd-000d56965251}" ; 2.5
;Global Const $sCLSID_BackgroundCopyManager = "{5FD42AD5-C04E-4D36-ADC7-E08FF15737AD}" ; 10.3
Global Const $sIID_IBackgroundCopyManager = "{5CE34C0D-0DC9-4C1F-897C-DAA1B78CEE7C}"
Global Const $tagBackgroundCopyManager = _
    "CreateJob hresult(wstr;int;clsid*;ptr*);" & _
    "GetJob hresult(clsid;ptr*);" & _
    "EnumJobs hresult(dword,ptr*);" & _
    "GetErrorDescription hresult(hresult,dword,str*)"

Global Const $sIID_IBackgroundCopyJob = "{37668D37-507E-4160-9316-26306D150B12}"
Global Const $tagIBackgroundCopyJob = _
    "AddFileSet hresult(ulong;struct*);" & _
    "AddFile hresult(wstr;wstr);" & _
    "EnumFiles hresult(ptr*);" & _
    "Suspend hresult();" & _
    "Resume hresult();" & _
    "Cancel hresult();" & _
    "Complete hresult();" & _
    "GetId hresult(clsid*);" & _
    "GetType hresult(int*);" & _
    "GetProgress hresult(struct*);" & _
    "GetTimes hresult(struct*);" & _
    "GetState hresult(int*);" & _
    "GetError hresult(ptr*);" & _
    "GetOwner hresult(wstr*);" & _
    "SetDisplayName hresult(wstr);" & _
    "GetDisplayName hresult(wstr*);" & _
    "SetDescription hresult(wstr);" & _
    "GetDescription hresult(wstr*);" & _
    "SetPriority hresult(int);" & _
    "GetPriority hresult(int*);" & _
    "SetNotifyFlags hresult(ulong);" & _
    "GetNotifyFlags hresult(ulong_ptr*);" & _
    "SetNotifyInterface hresult(ptr);" & _
    "GetNotifyInterface hresult(ptr*);" & _
    "SetMinimumRetryDelay hresult(ulong);" & _
    "GetMinimumRetryDelay hresult(ulong_ptr*);" & _
    "SetNoProgressTimeout hresult(ulong);" & _
    "GetNoProgressTimeout hresult(ulong_ptr*);" & _
    "GetErrorCount hresult(ulong_ptr*);" & _
    "SetProxySettings hresult(int;str*;str*);" & _
    "GetProxySettings hresult(int*;wstr*;wstr*);" & _
    "TakeOwnership hresult();"

Main()

Func Main()
  FileDelete ("Test.tmp")
  Local $oBackgroundCopyManager = ObjCreateInterface($sCLSID_BackgroundCopyManager, $sIID_IBackgroundCopyManager, $tagBackgroundCopyManager)
  ConsoleWrite (IsObj($oBackgroundCopyManager) & @CRLF)
  Local $sJobId = ""
  Local $pJob = 0
  ConsoleWrite ("create job " & $oBackgroundCopyManager.CreateJob("TestCreationJob", $BG_JOB_TYPE_DOWNLOAD, $sJobId, $pJob) & @CRLF)
  ConsoleWrite($sJobId & @CRLF)
  ConsoleWrite(VarGetType($pJob) & @CRLF)

  Local $oBackgroundCopyJob = ObjCreateInterface($pJob, $sIID_IBackgroundCopyJob, $tagIBackgroundCopyJob)
  ConsoleWrite(VarGetType($oBackgroundCopyJob) & @CRLF)

  $oBackgroundCopyJob.AddFile("https://dl.google.com/chrome/install/GoogleChromeStandaloneEnterprise64.msi", @ScriptDir & "\Test.tmp")
  $oBackgroundCopyJob.Resume()

  Local $iState
  For $i = 1 to 5000
    $oBackgroundCopyJob.GetState($iState)
    Switch $iState
      Case $BG_JOB_STATE_QUEUED
        ConsoleWrite ("Queued" & @CRLF)
      Case $BG_JOB_STATE_CONNECTING
        ConsoleWrite ("Connecting" & @CRLF)
      Case $BG_JOB_STATE_TRANSFERRING
        ConsoleWrite ("Trasnferring" & @CRLF)
      Case $BG_JOB_STATE_SUSPENDED
        ConsoleWrite ("Suspended" & @CRLF)
        ExitLoop
      Case $BG_JOB_STATE_ERROR
        ConsoleWrite ("State Error" & @CRLF)
        ExitLoop
      Case $BG_JOB_STATE_TRANSIENT_ERROR
        ConsoleWrite ("Transient error" & @CRLF)
        ExitLoop
      Case $BG_JOB_STATE_TRANSFERRED
        ConsoleWrite ("Transferred" & @CRLF)
        ExitLoop
      Case $BG_JOB_STATE_ACKNOWLEDGED
        ConsoleWrite ("Acknowledged" & @CRLF)
        ExitLoop
      Case $BG_JOB_STATE_CANCELLED
        ConsoleWrite ("Cancelled" & @CRLF)
        Exit
    EndSwitch
    Sleep (200)
  Next
  If $iState = $BG_JOB_STATE_TRANSFERRED Or $iState = $BG_JOB_STATE_ACKNOWLEDGED Then
    ConsoleWrite ($oBackgroundCopyJob.Complete() & @CRLF)
  Else
    ConsoleWrite ("cancel " & $oBackgroundCopyJob.Cancel() & @CRLF)
  EndIf
EndFunc   ;==>Main

 

:)

Edited by Nine
Link to comment
Share on other sites

17 hours ago, Nine said:

The order of your methods seems highly suspicious.  They are in alpha order which is rarely the case.  If you look at my tag ($tagBackgroundCopyManager) this is the right order.  MSDN does not provide the true order.  So be careful.  This is probably why your cancel is not working as it call the wrong method.

As mentioned before, I had first listed the methods in alphabetical order, as is the case in the online documentation of the interfaces:
https://docs.microsoft.com/en-us/windows/win32/api/bits/nn-bits-ibackgroundcopymanager#methods
https://docs.microsoft.com/en-us/windows/win32/api/bits/nn-bits-ibackgroundcopyjob#methods

But obviously the correct order has to be chosen as it is given in the header file bits.h.

Anyway, thanks a lot for your help, @Nine!

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...