Entwickler-Ecke

Internet / Netzwerk - Download DLL?!


Darnus - Di 22.08.06 14:11
Titel: Download DLL?!
Hallo :D
Habe ein problem: Habe neu angefangen mit delphi zu arbeiten.. und möchte für den "Game Maker" eine download DLL bauen. So zuerstmal weiss ich nicht ob das hier richtig ist doch beim aufrufen passiert einfach nix, und ich möchte arg1 und arg2 benutzen können, das geht aber auch nicht! Kann mir jemand die funktion meiner DLL bitte beschreiben also was ich hier gemacht habe und was ich vergessen habe?! BIG Thx für die antworten.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
library Download;
uses Windows,
  SysUtils,
  Classes,
  shellapi,
  URLmon;

function dl(arg1,arg2:string): String Stdcall;
begin
 URLDownloadToFile(nil,'http://come2own.de/psdsoft/logo.wmv','C:\tes.wmv'0nil);
end;
exports dl;
begin
end.


EDIT: die funktion geht also der download! jetzt brauche ich nur die antworten auf arg1 (URL) und arg2 (Speicher unter), unten die funktion geht nicht!!! Kommt dann ein fehler.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
library Download;
uses Windows,
  SysUtils,
  Classes,
  shellapi,
  URLmon;

function dl(arg1,arg2:string): String Stdcall;
begin
 URLDownloadToFile(nil,arg1,arg2, 0nil);
end;
exports dl;
begin
end.


Moderiert von user profile iconraziel: Quote- durch Delphi-Tags ersetzt


Martok - Mi 23.08.06 02:28

Und welcher Fehler? Ohne wird man wohl kaum weiter kommen.

Mal davon abgesehen, außer Delphi kennt niemand den Typ String, daher muss PChar verwendet werden. Hat Mark glaub ich auch im Handbuch beschrieben...*guckt nach*... Aha, hier mal sein Beispiel:.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
library MyDLL;

uses SysUtils, Classes;

var res : array[0..1024of char;
function DoubleString(str:PChar):PChar; cdecl;
begin
  StrCopy(res,str);
  StrCat(res,str);
  Result := res;
end;

exports DoubleString;

begin
end.

Ist für dich aber einfacher, deine Funktion müsste so gehen. Ich denke auch nicht, dass du einen Rückgabewert brauchst?:

Delphi-Quelltext
1:
2:
3:
4:
procedure dl(from,local:PChar); Stdcall;
begin
  URLDownloadToFile(nil,from,local, 0nil);
end;


Darnus - Mi 23.08.06 03:15


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
library Download;

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,URLmon, StdCtrls;

Function dl(from,local:PChar):Pchar; Stdcall;
begin
  URLDownloadToFile(nil,from,local, 0nil);
end;
exports dl;
begin
end.


Ich habe das nun so gemacht, es kommt zwar ne wahrnung ([Warning] Download.dpr(11): Return value of function 'dl' might be undefined) aber es geht so wie ich es mir vorgestellt habe. Wenn ich deine variante nehme gibts wieder Error vom Mark :nixweiss:


JayEff - Mi 23.08.06 03:17

Um an DLLs Strings zu übergeben musst du ShareMem als ALLERERSTE unit in die usesklausel einbinden. alternativ kannst du dir Suche in: Delphi-Forum, Delphi-Library FASTSHAREMEM besorgen, dann sparst du dir glaub dateigröße.
Ausserdem ahst du in der Funktion Result nichts zugewiesen, darum ist der Rückgabewert auch undefiniert. macht aber nix, die dll wird trotzdem erstellt.


Martok - Mi 23.08.06 03:21

Hm, scheint so, als ob der immer eine Rückgabewert haben will, also eine function. Mach doch den Rückgabewert als integer, dann kannst du gleich den Rückgabwert der Downloadfunktion nehmen (Result:= URLDownloadToFile(...))

Und das mit ShareMem wird so nichts, weil beide Seiten die haben müssen. Und GameMaker definitiv nicht, auch wenn er auch Delphi ist.


JayEff - Mi 23.08.06 03:22

Das wusst ich nicht. Aber ist doch nur eine Warnung, kein Fehler, die Kompilierung scheint doch zu klappen?


Darnus - Mi 23.08.06 03:32

Jo, der fehler sagt nur das was mit dem Result also der rückfrage net stimmt ansonsten gehts! wenn ich statt funktion -> procedure nehme kommt von GM fehler. Wenn ich bei funktion nur das mache: dl(from,local:PChar); Stdcall; dann hat er mit der Kompilierung nen problem. Ein problem jagd das andere ...


Darnus - Mi 23.08.06 03:38

Habe noch etwas rumgepfeilt .... und...
Ich habs, ohne wahrnung und ohne fehler :D geht 100% so! Danke Jungs!

Ne kleine frage noch: Ich möchte evtl eine Transfer Rate aus der dll haben, aber dann muss ich auf Indy Umschreiben oder?!


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
library Download;

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,URLmon, StdCtrls;

procedure dl(from,local:PChar); Stdcall;
begin
  URLDownloadToFile(nil,from,local, 0nil);
end;
  exports dl;

end.


JayEff - Mi 23.08.06 17:35

Es gibt eine möglichkeit, mit URLDownloadToFile eine Progressbar einzubinden - wenn dir das hilft. Es ist nicht möglich, in einer DLL eine indykomponente einzubinden, zumindest hab ich das versucht und bin gescheitert. Siehe hierzu meinen Thread [http://www.delphi-forum.de/viewtopic.php?t=40761&highlight=].
Für die Progressbar hab ich folgenden Code:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
Type
    cDownloadStatusCallback = Class(TObject, IUnknown, IBindStatusCallback)
    Private
        Function QueryInterface(Const IID: TGUID; Out Obj): HResult; Stdcall;
        Function _AddRef: Integer; Stdcall;
        Function _Release: Integer; Stdcall;
        Function OnStartBinding(dwReserved: DWORD; pib: IBinding): HResult; Stdcall;
        Function GetPriority(Out nPriority): HResult; Stdcall;
        Function OnLowResource(reserved: DWORD): HResult; Stdcall;
        Function OnProgress(ulProgress, ulProgressMax, ulStatusCode: ULONG; szStatusText: LPCWSTR): HResult; Stdcall;
        Function OnStopBinding(HResult: HResult; szError: LPCWSTR): HResult; Stdcall;
        Function GetBindInfo(Out grfBINDF: DWORD; Var bindinfo: TBindInfo): HResult; Stdcall;
        Function OnDataAvailable(grfBSCF: DWORD; dwSize: DWORD; formatetc: PFormatEtc; stgmed: PStgMedium): HResult; Stdcall;
        Function OnObjectAvailable(Const IID: TGUID; punk: IUnknown): HResult; Stdcall;
    End;

Var
    Form1: TForm1;
    usercancel: Boolean = False;

Implementation

Function cDownloadStatusCallback._AddRef: Integer;
Begin
    Result := 0;
End;

Function cDownloadStatusCallback._Release: Integer;
Begin
    Result := 0;
End;

Function cDownloadStatusCallback.QueryInterface(Const IID: TGUID; Out Obj): HResult;
Begin
    If (GetInterface(IID, Obj)) Then
    Begin
        Result := 0
    End
    Else
    Begin
        Result := E_NOINTERFACE;
    End;
End;

Function cDownloadStatusCallback.OnStartBinding(dwReserved: DWORD; pib: IBinding): HResult;
Begin
    Result := S_OK;
End;

Function cDownloadStatusCallback.GetPriority(Out nPriority): HResult;
Begin
    Result := S_OK;
End;

Function cDownloadStatusCallback.OnLowResource(reserved: DWORD): HResult;
Begin
    Result := S_OK;
End;

Function cDownloadStatusCallback.OnStopBinding(HResult: HResult; szError: LPCWSTR): HResult; Stdcall;
Begin
    Result := S_OK;
End;

Function cDownloadStatusCallback.GetBindInfo(Out grfBINDF: DWORD; Var bindinfo: TBindInfo): HResult; Stdcall;
Begin
    Result := S_OK;
End;

Function cDownloadStatusCallback.OnDataAvailable(grfBSCF: DWORD; dwSize: DWORD; formatetc: PFormatEtc; stgmed: PStgMedium): HResult;
Begin
    Result := S_OK;
End;

Function cDownloadStatusCallback.OnObjectAvailable(Const IID: TGUID; punk: IUnknown): HResult; Stdcall;
Begin
    Result := S_OK;
End;

Function cDownloadStatusCallback.OnProgress(ulProgress, ulProgressMax, ulStatusCode: ULONG; szStatusText: LPCWSTR): HResult;
Begin
    Case ulStatusCode Of
        BINDSTATUS_FINDINGRESOURCE:
            Begin
                Form1.Label1.Caption := 'Datei wurde gefunden...';
                If (usercancel) Then
                Begin
                    Result := E_ABORT;
                    exit;
                End;
            End;
        BINDSTATUS_CONNECTING:
            Begin
                Form1.Label1.Caption := 'Es wird verbunden...';
                If (usercancel) Then
                Begin
                    Result := E_ABORT;
                    exit;
                End;
            End;
        BINDSTATUS_BEGINDOWNLOADDATA:
            Begin
                Form1.Gauge1.Progress := 0;
                Form1.Label1.Caption := 'Der Download wurde gestartet...';
                If (usercancel) Then
                Begin
                    Result := E_ABORT;
                    exit;
                End;
            End;
        BINDSTATUS_DOWNLOADINGDATA:
            Begin
                Form1.Gauge1.Progress := MulDiv(ulProgress, 100, ulProgressMax);
                Form1.Label1.Caption := 'Datei wird heruntergeladen...';
                If (usercancel) Then
                Begin
                    Result := E_ABORT;
                    exit;
                End;
            End;
        BINDSTATUS_ENDDOWNLOADDATA:
            Begin
                Form1.Label1.Caption := 'Download wurd beendet...';
                Form1.Gauge1.Progress := Form1.Gauge1.MaxValue;
            End;
    End;
    Application.ProcessMessages;

    Result := S_OK;
End;

Procedure download;
Var
    cDownStatus: cDownloadStatusCallback;
Begin
    cDownStatus := cDownloadStatusCallback.Create;
    Try
        URLDownloadToFIle(Nil'http://rmctool.rigismusiccity.de/RMCTool.exe',
            PChar(ExtractFilePath(Application.ExeName) + 'RMCTool.exe'), 0, cDownStatus);
    Finally
        cDownStatus.Free;
    End;
end;

Dazu brauchst du eine Gauge und einen Timer auf etwa 200ms. Ob dir das hilft weis ich nicht, ich denke aber, du kannst damit auf die Geschwindigkeit zurückrechnen. Irgentwie.
PS: Der code ist nicht von mir - Ich hab ihn aus irgent einem anderen Thread :oops: sorry, ich weis nicht mehr woher...