Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Probleme mit BITS (https://www.delphipraxis.net/190274-probleme-mit-bits.html)

GreatCornholio 19. Sep 2016 15:14

Probleme mit BITS
 
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.

Medium 20. Sep 2016 03:35

AW: Probleme mit BITS
 
Ich kenne das Framework leider nicht, und kann daher die Kernfrage nicht beantworten, aber dieses hier dennoch:
Zitat:

Zitat von GreatCornholio (Beitrag 1348055)
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?

Du weist dem Pointer die Adresse 0 zu. (BG_JOB_TYPE_DOWNLOAD ist das erste Element im Enum BG_JOB_TYPE, und hat somit automatisch den numerischen Wert 0.) Daher versucht dann CreateJob() an Adresse 0 seinen Wert für den Parameter zu finden, und wird auf den AV Hammer laufen. (Bzw. scheint dies netterweise vorher abgefangen zu werden.) Ich habe im Netz zu CreateJob() genau nur ein einziges anderes Beispiel gefunden auf die Schnelle, und dort wurde der Parameter wie in deinem ersten Beispiel direkt übergeben - nicht über einen Pointer. Daher weiss ich leider nicht, ob es überhaupt eine Überladung gibt, die einen Pointer annehmen kann. Falls ja, und es macht ja den Anschein, dann so:
Delphi-Quellcode:
var
  jobType: TBgJobType;
  pJobType: PBgJobType;
begin
  jobType := BG_JOB_TYPE_DOWNLOAD;
  pJobType := ^jobType;
  hRes:= FManager.CreateJob('Test', pJobType, pJobID, pJob);
  // oder alternativ ohne Zwischenvariable:
  hRes:= FManager.CreateJob('Test', @jobType, pJobID, pJob);
Aber ich wage zu bezweifeln, dass dies das Problem löst. Soweit sich meine kurze Googelei darstellte, scheint dieser Weg (diese Komponente bzw. das Framework) auch nicht sonderlich populär. Was stört dich an den ganz normalen Socket Komponenten, oder den Indys? Gerade mit den Indys sollte das ein Kinderspiel sein, und man findet massig Doku und anderes Material dazu im Netz.

jaenicke 20. Sep 2016 06:41

AW: Probleme mit BITS
 
Ich habe dies heute Morgen kurz ausprobiert. Bei mir ist der Aufruf erfolgreich. Kann es sein, dass du an deinem System etwas verändert hast? Gewisse Tuning-Tools deaktivieren diesen Dienst zum Beispiel gerne, obwohl es ja nicht so ist, dass er nicht benötigt wird.
Probiere es am besten einmal auf einem frischen System oder in einer neu aufgesetzten VM.

Zitat:

Zitat von Medium (Beitrag 1348112)
Du weist dem Pointer die Adresse 0 zu. (BG_JOB_TYPE_DOWNLOAD ist das erste Element im Enum BG_JOB_TYPE, und hat somit automatisch den numerischen Wert 0.)

Welcher Pointer? Der zweite Parameter ist vom Typ BG_JOB_TYPE, also genau der Enumeration, von deren Typ auch pJobType ist. Das p für Pointer ist in dem Variablennamen allerdings ungünstig gewählt.

Zitat:

Zitat von Medium (Beitrag 1348112)
Aber ich wage zu bezweifeln, dass dies das Problem löst. Soweit sich meine kurze Googelei darstellte, scheint dieser Weg (diese Komponente bzw. das Framework) auch nicht sonderlich populär. Was stört dich an den ganz normalen Socket Komponenten, oder den Indys? Gerade mit den Indys sollte das ein Kinderspiel sein, und man findet massig Doku und anderes Material dazu im Netz.

BITS bietet schon eine Menge mehr Möglichkeiten als man selbst einfach mal so umsetzen kann. Das System lädt die Datei zum Beispiel komplett im Hintergrund mit niedriger Priorität herunter und benachrichtigt dich, wenn sie da ist.

Jemand hier im Forum hat darüber auch glaube ich schon auf den Delphi-Tagen gesprochen, mir fällt nur der Name nicht ein...

himitsu 20. Sep 2016 11:39

AW: Probleme mit BITS
 
Zitat:

Zitat von jaenicke (Beitrag 1348114)
Jemand hier im Forum hat darüber auch glaube ich schon auf den Delphi-Tagen gesprochen, mir fällt nur der Name nicht ein...

Ich glaub das letzte oder vorletzte Jahr? (von diesma weiß ich nichts)

Zitat:

Zitat von jaenicke (Beitrag 1348114)
BITS bietet schon eine Menge mehr Möglichkeiten als man selbst einfach mal so umsetzen kann. Das System lädt die Datei zum Beispiel komplett im Hintergrund mit niedriger Priorität herunter und benachrichtigt dich, wenn sie da ist.

Im Grunde ist es ja vorallem genau dafür gedacht.
* Nur "Einer" muß ins Internet (nur BITS, wegen der Firewall),
* der kann alles in Ruhe runterladen, wenn der Rechner Zeit hat, bzw. wenn ein passendes Netzwerk zur Verfügung steht (z.B. nicht über's teure Handynetz)
* und nicht jedes poplige Programm muß einen eigenen Updateservice installieren, der ständig läuft, oder selber bei jedem Programmstart nachgucken. :wall:

Wir hätten uns die Raumpläne aufheben sollen, um nochma nachgucken zu können. :oops:

HolgerX 20. Sep 2016 12:06

AW: Probleme mit BITS
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo..

Habe auch mal vor einiger Zeit etwas mit BITS rumgespielt..

Allerdings habe ich die ganze Job-Geschichte in einen eigenen Thread ausgelagert, welcher auch den Status abfrägt und entsprechend Rückmeldung gibt.

Von dort habe ich mal etwas heraus gezogen:

Delphi-Quellcode:
procedure InitJob(AFileNameSource : WideString; AFileNameTarget : WideString);
var
  Bits : IBackgroundCopyManager;
  Job: IBackgroundCopyJob;
  JobID: GUID;
begin
  CoInitialize(nil);
  try
    try
      Bits := CoBackgroundCopyManager_.Create;

      // Erstellen neuen Job
      Assert(Succeeded(Bits.CreateJob('BITSJob', BG_JOB_TYPE_DOWNLOAD, jobID, job )));

      // Fileeinträge erzeugen
      Assert(Succeeded(job.AddFile(PWideChar(AFileNameSource), PWideChar(AFileNameTarget))));

      // Priorität setzen
      Assert(Succeeded(job.SetPriority( BG_JOB_PRIORITY_HIGH )));

//    ... Status-Abfragen

      job := nil;
    except
      on E: Exception do
        ShowMessage('Exception : ' + E.Classname + ': ' + E.Message);
    end;
  finally
    CoUninitialize;
  end;
end;

Dies verwendet die angehängte TLB, jedoch weiß ich nicht mehr, wo die her ist.
Auch ist die TLP für die BITS Vers. 1 und noch nicht für die Vers. 2, funktioniert auf Windows 7 aber problemlos.

Mit BITS können übrigens nicht nur Dateien aus dem Internet herunter geladen werden, sondern auch aus dem Lokalen Netz.

GreatCornholio 20. Sep 2016 12:25

AW: Probleme mit BITS
 
Danke für die Antworten!

Also teilweise kann ich Entwarnung geben.
Habe es gerade noch mal mit frisch gestartetem PC probiert, und mit fest gesetztem JobType-Parameter wird der Job nun fehlerlos erstellt, und es kann sogar eine Datei heruntergeladen werden.
Anscheinend hat sich "nur" der BITS-Service aufgehängt, aber so seltsam dass er zumindest noch teilweise funktioniert hat...

Was allerdings immer noch nicht geht, ist die Übergabe des JobTypes als Variable, dort kommt immer noch die gleiche Fehlermeldung wie vorher.
Ich kann Sachen machen wie:
Delphi-Quellcode:
hRes:= m_Manager.CreateJob('Test', BG_JOB_TYPE(0), rJobID, pJob);
, das funktioniert.
Aber das hier funktioniert nicht:
Delphi-Quellcode:
var
  i: Integer;
  ...
begin
  ...
  i:= 0;
  hRes:= m_Manager.CreateJob('Test', BG_JOB_TYPE(i), rJobID, pJob);
Warum ich BITS verwenden will wurde ja schon angesprochen.
Ich will große Dateien aus dem Internet laden, ohne mich darum kümmern zu müssen, und wenn sie irgendwann fertig sind bekomme ich eine Nachricht.

HolgerX 20. Sep 2016 13:59

AW: Probleme mit BITS
 
Hmm..

Bei meiner TLB ist der Typ für BG_JOB_TYPE als

TOleEnum = type LongWord;

definiert.

Bei deiner Version ist es direkt der Aufzählungstyp!

Vielleicht gibt es hier ja Unterschiede?

Aber wenn Du eh nur Downloads und keine Uploads machen willst, dann ist es doch egal und Du kannst auch direkt 0 als Konstante einsetzen.

himitsu 20. Sep 2016 14:47

AW: Probleme mit BITS
 
Zitat:

LongWord
Delphi-Quellcode:
{$MINIMUMENUMSIZE 4}
BG_JOB_TYPE = .....;
{$MINIMUMENUMSIZE 1}
In Delphi sind ENUMs nur so groß, wie nötig. (also oft nur 1 Byte)
In C++ sind sie fast immer "UNSIGNED INT" (4 Byte)

GreatCornholio 20. Sep 2016 15:24

AW: Probleme mit BITS
 
Ha!
Danke für den Tip, das wars! :thumb:

MfG

GreatCornholio 23. Sep 2016 16:25

AW: Probleme mit BITS
 
So, jetzt ist leider das nächste Problem aufgetaucht.
Hat schon mal jemand erfolgreich einen Programmaufruf bei Beendigung des Downloads implementiert?
Also über die Funktion IBackgroundCopyJob2.SetNotifyCmdLine()?

Ich kann mir erfolgreich einen Zeiger auf das IBackgroundCopyJob2-Interface holen, SetNotifyCmdLine aufrufen, und bekomme immer OK zurück.
Aber wenn ich einen Download starte, das Programm beende und warte, passiert einfach nichts, das Kommando wird nicht ausgeführt.
Mit
Delphi-Quellcode:
bitsadmin.exe /list
kann ich den Fortschritt und die Fertigstellung des Downloads verfolgen.
Ich kann sogar mit
Delphi-Quellcode:
bitsadmin /info {GUID} /verbose
mein Kommando sehen:
Code:
GUID: {GUID} DISPLAY: 'Test'
TYPE: DOWNLOAD STATE: TRANSFERRED OWNER: ich
PRIORITY: HIGH FILES: 1 / 1 BYTES: 70517025 / 70517025
CREATION TIME: 23.09.2016 15:55:21 MODIFICATION TIME: 23.09.2016 15:57:00
COMPLETION TIME: 23.09.2016 15:57:00 ACL FLAGS:
NOTIFY INTERFACE: UNREGISTERED NOTIFICATION FLAGS: 27
RETRY DELAY: 600 NO PROGRESS TIMEOUT: 1209600 ERROR COUNT: 0
PROXY USAGE: PRECONFIG PROXY LIST: NULL PROXY BYPASS LIST: NULL
DESCRIPTION:
JOB FILES:
        70517025 / 70517025 WORKING http://www.domain.de/MeinTestFile.zip -> D:\BITS Test\MeinTestFile.zip
NOTIFICATION COMMAND LINE: '"C:\Windows\System32\notepad.exe"'
owner MIC integrity level: MEDIUM
owner elevated ?           false

Peercaching flags
         Enable download from peers     :false
         Enable serving to peers        :false

CUSTOM HEADERS: NULL
Als CommandLine habe ich den Namen meines Programms (mit ParamStr(0)) und notepad.exe, jeweils mit und ohne Anführungszeichen verwendet.
Ich habe schon verschiedene Prioritäten verwendet, BG_JOB_PRIORITY_FOREGROUND und BG_JOB_PRIORITY_HIGH.
Die NotifyFlags vor und nach der CommandLine gesetzt.
Aber nichts funktioniert, obwohl es eigentlich funktionieren müsste...


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:02 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz