Thema: Delphi Probleme mit BITS

Einzelnen Beitrag anzeigen

GreatCornholio

Registriert seit: 19. Sep 2016
6 Beiträge
 
Delphi XE7 Professional
 
#1

Probleme mit BITS

  Alt 19. Sep 2016, 14:14
Hallo zusammen,

ich versuche gerade Downloads mit BITS durchzuführen, aber irgendwie bekomme ich es einfach nicht hin.
Ich habe schon mehrere APIs erfolgreich verwendet, aber hier stehe ich wie der sprichwörtliche Ochse vorm Berg...

Kurze Beschreibung:
Ich habe die Deklarationen aus jwaBits.pas in meinen Code kopiert für einen ersten Test.
Eine Instanz des IBackgroundCopyManagers kann ich erfolgreich erstellen.
Aber wenn ich versuche, einen neuen Job zu erstellen, hängt das Programm komplett (mehrere Stunden warten hat daran auch nichts geändert).
Falls es zur Ursachenforschung beiträgt, ich verwende Windows 10.

Hier der Code zum Erzeugen des BackgroundCopyManagers (FManager ist eine Variable vom Typ IBackgroundCopyManager):
Delphi-Quellcode:
procedure TForm3.FormCreate(Sender: TObject);
var
  hRes: HRESULT;
begin
  FManager:= nil;
  hRes:= CoCreateInstance(CLSID_BackgroundCopyManager,
                        nil,
                        CLSCTX_LOCAL_SERVER,
                        IID_IBackgroundCopyManager,
                        FManager);
  if not Succeeded(hRes) then
    raise Exception.Create('Could not create BackgroundCopyManager.');
end;
Und hier der Code zum Erstellen eines neuen Jobs:
Delphi-Quellcode:
procedure TForm3.Button1Click(Sender: TObject);
var
  hRes: HRESULT;
  pJobID: TGUID;
  pJob: IBackgroundCopyJob;
  pJobType: BG_JOB_TYPE;
  pErrDescr: PWideChar;
begin
  pJobID:= TGUID.Empty;
  pJob:= nil;
  pJobType:= BG_JOB_TYPE_DOWNLOAD;
  hRes:= FManager.CreateJob('Test', BG_JOB_TYPE_DOWNLOAD, pJobID, pJob);
  // Die untere Zeile wird nie erreicht , das Programm hängt in der oberen Zeile fest
  if Succeeded(hRes) then
  begin
    hRes:= pJob.SetPriority(BG_JOB_PRIORITY_FOREGROUND);
    // TODO: Do the real stuff when job creation works...
    pJob.Cancel;
  end
  else
  begin
    hRes:= FManager.GetErrorDescription(hRes, 1031, pErrDescr);
  end;
Hier bleibt das Programm in der Zeile mit CreateJob hängen.
Wenn ich irgendwann im Debugger auf Pause klicke, lande ich so gut wie immer im CPU-Fenster bei ntdll.RtlUserThreadStart:

Das wirklich Rätselhafte kommt aber noch: Wenn ich den JobType nicht direkt im Funtionsaufruf setze, sondern als Parameter
Delphi-Quellcode:
  pJobType:= BG_JOB_TYPE_DOWNLOAD;
  hRes:= FManager.CreateJob('Test', pJobType, pJobID, pJob);
bekomme ich sofort einen Fehlercode -2147023115 zurück mit der Meldung 'Der Aufzählungswert liegt außerhalb des erlaubten Bereichs.'.

Und jetzt die Masterfrage: Was mache ich falsch?
Was stimmt nicht mit meinen Definitionen (sind ja nur Kopien aus JEDI)?

Ich bin für jede Hilfe dankbar!
Das bringt mich total zur Verzweiflung...

MfG

Hier der Vollständigkeit halber noch die komplette Datei:
Delphi-Quellcode:
unit unitForm3;

interface

uses
  Winapi.Windows,
  Winapi.Messages,
  System.SysUtils,
  System.Variants,
  System.Classes,
  Vcl.Graphics,
  Vcl.Controls,
  Vcl.StdCtrls,
  Vcl.Forms,
  Vcl.Dialogs{,
  unitBitsDownloadManager,
  unitBitsCopyJob}
;

const
  BG_NOTIFY_JOB_TRANSFERRED = $0001;
  {$EXTERNALSYM BG_NOTIFY_JOB_TRANSFERRED}
  BG_NOTIFY_JOB_ERROR = $0002;
  {$EXTERNALSYM BG_NOTIFY_JOB_ERROR}
  BG_NOTIFY_DISABLE = $0004;
  {$EXTERNALSYM BG_NOTIFY_DISABLE}
  BG_NOTIFY_JOB_MODIFICATION = $0008;
  {$EXTERNALSYM BG_NOTIFY_JOB_MODIFICATION}
  BG_NOTIFY_FILE_TRANSFERRED = $0010;
  {$EXTERNALSYM BG_NOTIFY_FILE_TRANSFERRED}

  BG_JOB_ENUM_ALL_USERS = $0001;
  {$EXTERNALSYM BG_JOB_ENUM_ALL_USERS}

  BG_SIZE_UNKNOWN = Int64(-1);
  {$EXTERNALSYM BG_SIZE_UNKNOWN}

type
  GUID = TGUID;

  BG_ERROR_CONTEXT = (
    BG_ERROR_CONTEXT_NONE,
    BG_ERROR_CONTEXT_UNKNOWN,
    BG_ERROR_CONTEXT_GENERAL_QUEUE_MANAGER,
    BG_ERROR_CONTEXT_QUEUE_MANAGER_NOTIFICATION,
    BG_ERROR_CONTEXT_LOCAL_FILE,
    BG_ERROR_CONTEXT_REMOTE_FILE,
    BG_ERROR_CONTEXT_GENERAL_TRANSPORT,
    BG_ERROR_CONTEXT_REMOTE_APPLICATION);
  {$EXTERNALSYM BG_ERROR_CONTEXT}
  TBgErrorContext = BG_ERROR_CONTEXT;

  BG_JOB_PRIORITY = (
    BG_JOB_PRIORITY_FOREGROUND,
    BG_JOB_PRIORITY_HIGH,
    BG_JOB_PRIORITY_NORMAL,
    BG_JOB_PRIORITY_LOW);
  {$EXTERNALSYM BG_JOB_PRIORITY}
  TBgJobPriority = BG_JOB_PRIORITY;
  PBgJobPriority = ^BG_JOB_PRIORITY;

  BG_JOB_TYPE = (
    BG_JOB_TYPE_DOWNLOAD,
    BG_JOB_TYPE_UPLOAD,
    BG_JOB_TYPE_UPLOAD_REPLY);
  {$EXTERNALSYM BG_JOB_TYPE}
  TBgJobType = BG_JOB_TYPE;

  BG_JOB_STATE = (
    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);
  {$EXTERNALSYM BG_JOB_STATE}
  TBgJobState = BG_JOB_STATE;
  PBgJobState = ^BG_JOB_STATE;

  BG_JOB_PROXY_USAGE = (
    BG_JOB_PROXY_USAGE_PRECONFIG,
    BG_JOB_PROXY_USAGE_NO_PROXY,
    BG_JOB_PROXY_USAGE_OVERRIDE,
   BG_JOB_PROXY_USAGE_AUTODETECT);
  {$EXTERNALSYM BG_JOB_PROXY_USAGE}
  TBgJobProxyUsage = BG_JOB_PROXY_USAGE;
  PBgJobProxyUsage = ^BG_JOB_PROXY_USAGE;

  _BG_FILE_PROGRESS = record
    BytesTotal: UINT64;
    BytesTransferred: UINT64;
    Completed: BOOL;
  end;
  {$EXTERNALSYM _BG_FILE_PROGRESS}
  BG_FILE_PROGRESS = _BG_FILE_PROGRESS;
  {$EXTERNALSYM BG_FILE_PROGRESS}
  TBgFileProgress = BG_FILE_PROGRESS;
  PBgFileProgress = ^BG_FILE_PROGRESS;

  _BG_JOB_PROGRESS = record
    BytesTotal: UINT64;
    BytesTransferred: UINT64;
    FilesTotal: ULONG;
    FilesTransferred: ULONG;
  end;
  {$EXTERNALSYM _BG_JOB_PROGRESS}
  BG_JOB_PROGRESS = _BG_JOB_PROGRESS;
  {$EXTERNALSYM BG_JOB_PROGRESS}
  TBgJobProgress = BG_JOB_PROGRESS;
  PBgJobProgress = ^BG_JOB_PROGRESS;

  _BG_FILE_INFO = record
    RemoteName: LPWSTR;
    LocalName: LPWSTR;
  end;
  {$EXTERNALSYM _BG_FILE_INFO}
  BG_FILE_INFO = _BG_FILE_INFO;
  {$EXTERNALSYM BG_FILE_INFO}
  TBgFileInfo = BG_FILE_INFO;
  PBgFileInfo = ^BG_FILE_INFO;

  _BG_JOB_TIMES = record
    CreationTime: FILETIME;
    ModificationTime: FILETIME;
    TransferCompletionTime: FILETIME;
  end;
  {$EXTERNALSYM _BG_JOB_TIMES}
  BG_JOB_TIMES = _BG_JOB_TIMES;
  {$EXTERNALSYM BG_JOB_TIMES}
  TBgJobTimes = BG_JOB_TIMES;
  PBgJobTimes = ^BG_JOB_TIMES;

const
  IID_IBackgroundCopyFile: TGUID = '{01B7BD23-FB88-4A77-8490-5891D3E4653A}';
  {$EXTERNALSYM IID_IBackgroundCopyFile}
type
  IBackgroundCopyFile = interface(IUnknown)
  ['{01b7bd23-fb88-4a77-8490-5891d3e4653a}']
    function GetRemoteName(out pVal: LPWSTR): HRESULT; stdcall;
    function GetLocalName(out pVal: LPWSTR): HRESULT; stdcall;
    function GetProgress(out pVal: BG_FILE_PROGRESS): HRESULT; stdcall;
  end;
  {$EXTERNALSYM IBackgroundCopyFile}

const
  IID_IEnumBackgroundCopyFiles: TGUID = '{CA51E165-C365-424C-8D41-24AAA4FF3C40}';
  {$EXTERNALSYM IID_IEnumBackgroundCopyFiles}
type
  IEnumBackgroundCopyFiles = interface(IUnknown)
  ['{ca51e165-c365-424c-8d41-24aaa4ff3c40}']
    function Next(celt: ULONG; out rgelt: IBackgroundCopyFile; pceltFetched: PULONG): HRESULT; stdcall;
    function Skip(celt: ULONG): HRESULT; stdcall;
    function Reset: HRESULT; stdcall;
    function Clone(out ppenum: IEnumBackgroundCopyFiles): HRESULT; stdcall;
    function GetCount(out puCount: ULONG): HRESULT; stdcall;
  end;
  {$EXTERNALSYM IEnumBackgroundCopyFiles}

const
  IID_IBackgroundCopyError: TGUID = '{19C613A0-FCB8-4F28-81AE-897C3D078F81}';
  {$EXTERNALSYM IID_IBackgroundCopyError}
type
  IBackgroundCopyError = interface(IUnknown)
  ['{19c613a0-fcb8-4f28-81ae-897c3d078f81}']
    function GetError(out pContext: BG_ERROR_CONTEXT; out pCode: HRESULT): HRESULT; stdcall;
    function GetFile(out ppVal: IBackgroundCopyFile): HRESULT; stdcall;
    function GetErrorDescription(LanguageId: DWORD; out pErrorDescription: LPWSTR): HRESULT; stdcall;
    function GetErrorContextDescription(LanguageId: DWORD; out pContextDescription: LPWSTR): HRESULT; stdcall;
    function GetProtocol(out pProtocol: LPWSTR): HRESULT; stdcall;
  end;
  {$EXTERNALSYM IBackgroundCopyError}

const
  IID_IBackgroundCopyJob: TGUID = '{37668D37-507E-4160-9316-26306D150B12}';
  {$EXTERNALSYM IID_IBackgroundCopyJob}
type
  IBackgroundCopyJob = interface(IUnknown)
  ['{37668d37-507e-4160-9316-26306d150b12}']
    function AddFileSet(cFileCount: ULONG; pFileSet: PBgFileInfo): HRESULT; stdcall;
    function AddFile(RemoteUrl, LocalName: LPCWSTR): HRESULT; stdcall; //
    function EnumFiles(out pEnum: IEnumBackgroundCopyFiles): HRESULT; stdcall;
    function Suspend: HRESULT; stdcall; //
    function Resume: HRESULT; stdcall; //
    function Cancel: HRESULT; stdcall; //
    function Complete: HRESULT; stdcall; //
    function GetId(out pVal: TGUID): HRESULT; stdcall; //
    function GetType(out pVal: BG_JOB_TYPE): HRESULT; stdcall; //
    function GetProgress(out pVal: BG_JOB_PROGRESS): HRESULT; stdcall;
    function GetTimes(out pVal: BG_JOB_TIMES): HRESULT; stdcall;
    function GetState(out pVal: BG_JOB_STATE): HRESULT; stdcall; //
    function GetError(out ppError: IBackgroundCopyError): HRESULT; stdcall;
    function GetOwner(out pVal: LPWSTR): HRESULT; stdcall;
    function SetDisplayName(Val: LPCWSTR): HRESULT; stdcall; //
    function GetDisplayName(out pVal: LPWSTR): HRESULT; stdcall; //
    function SetDescription(Val: LPCWSTR): HRESULT; stdcall; //
    function GetDescription(out pVal: LPWSTR): HRESULT; stdcall; //
    function SetPriority(Val: BG_JOB_PRIORITY): HRESULT; stdcall; //
    function GetPriority(out pVal: BG_JOB_PRIORITY): HRESULT; stdcall; //
    function SetNotifyFlags(Val: ULONG): HRESULT; stdcall; //
    function GetNotifyFlags(out pVal: ULONG): HRESULT; stdcall; //
    function SetNotifyInterface(Val: IUnknown): HRESULT; stdcall; //
    function GetNotifyInterface(out pVal: IUnknown): HRESULT; stdcall; //
    function SetMinimumRetryDelay(Seconds: ULONG): HRESULT; stdcall;
    function GetMinimumRetryDelay(out Seconds: ULONG): HRESULT; stdcall;
    function SetNoProgressTimeout(Seconds: ULONG): HRESULT; stdcall;
    function GetNoProgressTimeout(out Seconds: ULONG): HRESULT; stdcall;
    function GetErrorCount(out Errors: ULONG): HRESULT; stdcall;
    function SetProxySettings(ProxyUsage: BG_JOB_PROXY_USAGE; ProxyList, ProxyBypassList: PWCHAR): HRESULT; stdcall;
    function GetProxySettings(pProxyUsage: BG_JOB_PROXY_USAGE; pProxyList, pProxyBypassList: LPWSTR): HRESULT; stdcall;
    function TakeOwnership(): HRESULT; stdcall;
  end;
  {$EXTERNALSYM IBackgroundCopyJob}

const
  IID_IEnumBackgroundCopyJobs: TGUID = '{1AF4F612-3B71-466F-8F58-7B6F73AC57AD}';
  {$EXTERNALSYM IID_IEnumBackgroundCopyJobs}
type
  IEnumBackgroundCopyJobs = interface(IUnknown)
  ['{1af4f612-3b71-466f-8f58-7b6f73ac57ad}']
    function Next(celt: ULONG; out rgelt: IBackgroundCopyJob; pceltFetched: PULONG): HRESULT; stdcall;
    function Skip(celt: ULONG): HRESULT; stdcall;
    function Reset: HRESULT; stdcall;
    function Clone(out ppenum: IEnumBackgroundCopyJobs): HRESULT; stdcall;
    function GetCount(out puCount: ULONG): HRESULT; stdcall;
  end;
  {$EXTERNALSYM IEnumBackgroundCopyJobs}

const
  IID_IBackgroundCopyManager: TGUID = '{5CE34C0D-0DC9-4C1F-897C-DAA1B78CEE7C}';
  {$EXTERNALSYM IID_IBackgroundCopyManager}
  LIBID_BackgroundCopyManager: GUID = '{4991d34b-80a1-4291-83b6-3328366b9097}';
  {$EXTERNALSYM LIBID_BackgroundCopyManager}
  CLSID_BackgroundCopyManager: GUID = '{4991d34b-80a1-4291-83b6-3328366b9097}';
  {$EXTERNALSYM CLSID_BackgroundCopyManager}

type
  IBackgroundCopyManager = interface(IUnknown)
  ['{5ce34c0d-0dc9-4c1f-897c-daa1b78cee7c}']
    function CreateJob(DisplayName: LPCWSTR; Type_: BG_JOB_TYPE; out pJobId: GUID; out ppJob: IBackgroundCopyJob): HRESULT; stdcall;
    function GetJob(const jobID: GUID; out ppJob: IBackgroundCopyJob): HRESULT; stdcall;
    function EnumJobs(dwFlags: DWORD; out ppEnum: IEnumBackgroundCopyJobs): HRESULT; stdcall;
    function GetErrorDescription(hResult: HRESULT; LanguageId: DWORD; out pErrorDescription: LPWSTR): HRESULT; stdcall;
 end;
 {$EXTERNALSYM IBackgroundCopyManager}

const
  IID_IBackgroundCopyCallback: TGUID = '{97EA99C7-0186-4AD4-8DF9-C5B4E0ED6B22}';
  {$EXTERNALSYM IID_IBackgroundCopyCallback}
type
  IBackgroundCopyCallback = interface(IUnknown)
  ['{97ea99c7-0186-4ad4-8df9-c5b4e0ed6b22}']
    function JobTransferred(pJob: IBackgroundCopyJob): HRESULT; stdcall;
    function JobError(pJob: IBackgroundCopyJob; pError: IBackgroundCopyError): HRESULT; stdcall;
    function JobModification(pJob: IBackgroundCopyJob; dwReserved: DWORD): HRESULT; stdcall;
  end;
  {$EXTERNALSYM IBackgroundCopyCallback}

type
  TForm3 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    FManager: IBackgroundCopyManager;
  public
  end;

var
  Form3: TForm3;

implementation

uses
  Winapi.ActiveX,
  System.Win.ComObj;

{$R *.dfm}

procedure TForm3.FormCreate(Sender: TObject);
var
  hRes: HRESULT;
begin
  FManager:= nil;
  hRes:= CoCreateInstance(CLSID_BackgroundCopyManager,
                        nil,
                        CLSCTX_LOCAL_SERVER,
                        IID_IBackgroundCopyManager,
                        FManager);
  if not Succeeded(hRes) then
    raise Exception.Create('Could not create BackgroundCopyManager.');
end;

procedure TForm3.FormDestroy(Sender: TObject);
begin
  FManager:= nil;
end;

procedure TForm3.Button1Click(Sender: TObject);
var
  hRes: HRESULT;
  pJobID: TGUID;
  pJob: IBackgroundCopyJob;
  pJobType: BG_JOB_TYPE;
  pErrDescr: PWideChar;
begin
  pJobID:= TGUID.Empty;
  pJob:= nil;
  pJobType:= BG_JOB_TYPE_DOWNLOAD;
  hRes:= FManager.CreateJob('Test', BG_JOB_TYPE_DOWNLOAD, pJobID, pJob);
  if Succeeded(hRes) then
  begin
    hRes:= pJob.SetPriority(BG_JOB_PRIORITY_FOREGROUND);
    // TODO: Do the real stuff when job creation works...
    pJob.Cancel;
  end
  else
  begin
    hRes:= FManager.GetErrorDescription(hRes, 1031, pErrDescr);
  end;
end;

initialization
  CoInitFlags:= COINIT_APARTMENTTHREADED;

end.
  Mit Zitat antworten Zitat