Entwickler-Ecke

Dateizugriff - Überwachung eines Netzlaufwerks


Nico B. - Do 08.12.11 16:33
Titel: Überwachung eines Netzlaufwerks
Hallo Leute,

ich brauche dringend Hilfe bei einem etwas komplexeren Problem.
Ich muss regelmäßig Dateien von einem anderen Rechner im Netzwerk laden.
Dazu richte ich bei Programmstart ein Netzlaufwerk ein.

Ich möchte nun dafür sorge tragen, dass diese Verbindung immer besteht, bzw. bei einem Verbindungsabbruch so bald wie möglich wieder aufgebaut wird.

Habt ihr Ideen?

P.S. Ich erstelle ein Netzlaufwerk, weil ich nicht weiß, wie ich bei einem Dateizugriff über die Rechner-IP den Benutzernamen und das Passwort zu dem freigegebenen Laufwerk mitgeben kann. Falls das aber irgendwie geht, bräuchte ich nur noch die Netzwerkverbindung überwachen.


Nico B. - Fr 09.12.11 10:32

Hallo Leute,

fangen wir doch mit dem ersten Schritt an...
Wie erkenne ich, ob ein Netzlaufwerk verbunden ist?

Ich habe dazu folgende Funktion gefunden:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
function GetNetworkDriveConnection(const Laufwerk,Verzeichnis: String): boolean;
var
  lpnLength: Cardinal;
  FuncResult: DWORD;
  lpLocalName: PChar;
  lpRemoteName: PChar;
  RemoteName: String;
begin
  lpLocalName:=AllocMem(MAX_PATH+1);
  lpRemoteName:=AllocMem(MAX_PATH+1);
  StrPCopy(lpLocalName,Laufwerk);
  lpnLength:=MAX_PATH;
  FuncResult:=WNetGetConnection(lpLocalName,lpRemoteName,lpnLength);
  RemoteName:=lpRemoteName;
  if (FuncResult=0AND (Verzeichnis=RemoteName)
    then
      Result:=true
    else
      Result:=false;
  FreeMem(lpLocalName);
  FreeMem(lpRemotename);
end;

Mit meinem Programm verbinde ich nun also ein Netzlaufwerk.
Dann starte ich einen Timer der regelmäßig über obenstehende Funktion die Verbindung zu meinem Netzlaufwerk prüft.
Anschließend ziehe ich das Netzwerkkabel von meinem PC ab.
ABER: Keine Reaktion. Die Funktion bemerkt nicht, dass das Netzlaufwerk nicht mehr verbunden ist.

Woran liegt das?

Edit: baka0815 hat natürlich recht. Es muss WNetGetConnection heißen.


baka0815 - Fr 09.12.11 12:00

Ich vermute mal, dass die Funktion WNetGetConnection [http://msdn.microsoft.com/en-us/library/windows/desktop/aa385453%28v=vs.85%29.aspx] aufgerufen wird.
Diese holt den Namen der Netzwerkressource, die mit dem Laufwerk verbunden ist, prüft jedoch nicht ob die Verbindung auch tatsächlich besteht.

Vielleicht findest du hier [http://msdn.microsoft.com/en-us/library/windows/desktop/aa385485%28v=vs.85%29.aspx#_win32_information_functions] eine Funktion die dir hilft.


Nico B. - Fr 09.12.11 14:51

Hallo Leute,

ich habe mir die von baka0815 empfohlene Seite angeschaut.
Mittlerweile habe ich auch in der Delphi-Hilfe alles zu den Windows Networking Functions gefunden.
Leider jedoch nur in englisch.
Mit diesem ganzen fachspezifischen englisch komme ich aber nicht so gut zurecht.

Kennt jemand eine Funktion mit der nicht nur überprüft wird, ob die angegebene Netzwerkressource existiert, sondern ob die Verbindung auch besteht?


Tankard - Fr 09.12.11 15:35

schau dir mal MultinetGetConnectionPerformance an. die gibt ne fehler zurueck, sollte die connection nicht bestehen.

Note that the MultinetGetConnectionPerformance function can be used only to request information for a local device that is redirected to a network resource, or for a network resource to which there is currently a connection.

ps:


Delphi-Quelltext
1:
2:
3:
4:
5:
if (FuncResult=0AND (Verzeichnis=RemoteName)
    then
      Result:=true
    else
      Result:=false;


ginge auch so:

Delphi-Quelltext
1:
  Result:=((FuncResult=0AND (Verzeichnis=RemoteName));                    


Narses - Sa 10.12.11 06:36

Moin!

Ich frage mich, ob nicht ein anderes Protokoll als SMB die einfachere Lösung darstellt. :nixweiss:

Wie wäre es mit FTP, oder wenn nur Daten geholt werden sollen, auch HTTP? :idea: Notfalls auch ein eigener Client/Dienst, der die Daten zur Verfügung stellt. Hier ist die Fehlerbehandlung deutlich einfacher. ;)

cu
Narses


Nico B. - Mo 12.12.11 10:50

Hallo Leute,

Tankards Vorschlag hat mich auf die Lösung meines Problems gebracht.
Tatsächlich kann man die Funktion MulinetGetConnectionPerformance missbrauchen, um zu überprüfen, ob ein Netzlaufwerk verbunden ist.
Hier meine Lösung:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
//Laufwerk = steht für den lokalen Laufwerksbuchstaben des Netzlaufwerks
//Verzeichnis = steht für den entfernten Pfad auf den zugegriffen werden soll
function GetNetworkDriveConnection(const Laufwerk,Verzeichnis: String): boolean;
var
  LRes: TNetResource;
  LInfo: TNetConnectInfoStruct;
begin
  ZeroMemory(@LRes,SizeOf(LRes));
  LRes.lpLocalName:=PChar(Laufwerk);
  LRes.lpRemoteName:=PChar(Verzeichnis);
  LInfo.cbStructure:=SizeOf(LInfo);
  Result:=MultinetGetConnectionPerformance(@LRes,@LInfo)=NO_ERROR;
end;

Die Lösung habe ich übrigens hier [http://www.delphipraxis.net/64880-wnetopenenum-falscher-parameter.html] gefunden.

Vielen Dank für eure Hilfe!!!
Problem gelöst!

Edit: Danke Tankard. Jetzt sollte es stimmen.


Tankard - Mo 12.12.11 12:47

Hi,

deine ZeroMemory Zeile ist wohl falsch. Hoffe nur hier und nicht in deinem Code den du einsetzt.

Gruss
Tankard