Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Netzwerkordnerzugriff (https://www.delphipraxis.net/196896-netzwerkordnerzugriff.html)

Moombas 28. Jun 2018 13:24

Netzwerkordnerzugriff
 
Moin,

ich bins mal wieder mit einer wahrscheinlich einfachen Frage. "Brett vorm Kopf" -.-

Ich möchte per Button auf einen Netzwerkpfad zugreifen. Aufbau:

"\\IP\Laufwerk\Ordner" also:
"\\xx.xx.xx.xx\c$\"
bzw.
"\\xx.xx.xx.xx\d$\"

als Benutzer Max und Passwort Pass (natürlich sind dies hier nur synonyme)

Normalerweise kann man Ordner ja direkt über Shellexecute öffnen, aber beim Netzwerkordner funktioniert dies nicht, hab schon ne Menge gewühlt und Probiert (auch mit explorer + "/e,Pfad"), komme aber nicht weiter.

jobo 28. Jun 2018 13:52

AW: Netzwerkordnerzugriff
 
Zuerst würde ich bei sowas klären, ob es zu Fuß geht. Dann Code.
Zu Fuß:
- DOS Box
- net use ..

Fehlermeldung hier posten

Mgl. Probleme, Du bist schon als jemand anders dort verbunden (auf dem Zielrechner),
Differenzen zwischen Domäne und Arbeitsgruppe / local user /Gerät Angabe. Das muss halt passen (Du musst wissen, was Du willst und was Du tatsächlich tust)
Dann gibt's noch das ganze SMB Protokoll Versions-Theater aktuell, spielt da vielleicht auch rein.

HolgerX 28. Jun 2018 15:27

AW: Netzwerkordnerzugriff
 
Hmm..

Zitat:

Zitat von Moombas (Beitrag 1406036)
Moin,

"\\IP\Laufwerk\Ordner" also:
"\\xx.xx.xx.xx\$c\"
bzw.
"\\xx.xx.xx.xx\$d\"

Könnte es sein, dass Du auf die Versteckten Admin-Freigaben für die Laufwerke zugreifen willst?

Wenn Ja, dann müsste das '$' hinter dem Laufwerksnamen stehen.. ;)

"\\xx.xx.xx.xx\c$\"

Moombas 29. Jun 2018 08:22

AW: Netzwerkordnerzugriff
 
@jobo: keine sorge den Netzwerkzugriff über den normalen weg bekomme ich ohne weiteres hin mit

net use \\%IP%\C$ "Pass" /USER:Max /PERSISTENT:NO
explorer.exe /SEPARATE,\\%IP%\C$

@HolgerX: du hast recht, Tippfehler XD


Ich würde es halt gerne ohne externe Bat-Datei machen. Das müsste doch funktionieren.

jobo 29. Jun 2018 08:55

AW: Netzwerkordnerzugriff
 
Zitat:

Zitat von Moombas (Beitrag 1406089)
@jobo: keine sorge den Netzwerkzugriff über den normalen weg bekomme ich ohne weiteres hin mit

Gut! Das ist häufig nicht selbstverständlich.

HolgerX 29. Jun 2018 09:58

AW: Netzwerkordnerzugriff
 
Hmm..

Es geht Dir also darum, ohne NetUse eine Netzwerk-Verbindung per UNC-Pfad (ohne Laufwerksbuchstaben) zu erstellen.

Hatte da mal was um mich mit IPC zu verbinden..

Dafür gibt es die API 'WNetAddConnection2'!
Mit dieser kannst Du Netzwerk-Verbindungen ala NetUse herstellen.
Wenn Du dort das lokale Laufwerk als Parameter weglässt, dann wird auch ohne Laufwerk eine Verbindung/Anmeldung Hergestellt.

Diese wird sogar mit Netuse aufgelistet.

Danach einfach mit ShellExecute den UNC-Pfad öffnen.

ShellExecute(self.Handle, nil, PChar(UNCPfad),nil,nil,SW_SHOW);

Moombas 29. Jun 2018 10:11

AW: Netzwerkordnerzugriff
 
Den Weg hatte ich eigentlich schon probiert und bin gescheitert, da er dies nicht öffnen konnte (warum auch immer). Aktuell gehe ich noch den Umweg über die Bat-Datei (unschön, da username/Passwort im Klartext enthalten sind).

HolgerX 29. Jun 2018 10:29

AW: Netzwerkordnerzugriff
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hmm..

Angehängt ist ein Test tool..

Dieses Verwendet WNetAddConnection2 zum Anlegen und WNetCancelConnection2 zum löschen einer Netzverbindung.

und ShellExecute zum Öffnen.

(Erstellt mit D6)

Moombas 29. Jun 2018 11:12

AW: Netzwerkordnerzugriff
 
Das funktioniert -.- also liegt es scheinbar doch irgendwie an mir.

Moombas 29. Jun 2018 12:09

AW: Netzwerkordnerzugriff
 
also nun habe ich es fast, er fragt mich aber nach username/passwort, was ich ja eigentlich im WNetAddConnection2 übergebe. Und wenn ich beim shellexecute dies mit /u bzw /p einbaue, bin ich wieder soweit wie vorher.

@Holger wo hast du diese mit eingebaut oder hast du deinen code mal für mich?

HolgerX 29. Jun 2018 12:33

AW: Netzwerkordnerzugriff
 
Hmm..

Kann Dir nur Auszüge geben:

Delphi-Quellcode:
function IsLocalPath(const Path:string):boolean;
var
  i : cardinal;
begin
  i := GetDriveType(pchar(copy(path,1,2)));
  result := (i = DRIVE_FIXED) or
    (i = DRIVE_CDROM) or
    (i = DRIVE_RAMDISK) or
    (i = DRIVE_REMOVABLE);
end;


function Logout(Path:String):Cardinal;
begin
  result := NO_ERROR;
  if length(path) > 0 then begin
    if path[1] = '\' then begin
      path := ExcludeTrailingPathDelimiter(ExpandUNCFileName(Trim(path)));
      // Windows-Share LogOff
      result := WNetCancelConnection2(pchar(Path),CONNECT_UPDATE_PROFILE,true);

      // NetWare-Server LogOff nur mit dem Server-Namen!
      path := '\\' + ExtractServerName(path);
      WNetCancelConnection2(pchar(copy(Path,3,length(path)-2)),CONNECT_UPDATE_PROFILE,true);
    end else begin
      result := WNetCancelConnection2(pchar(Path),CONNECT_UPDATE_PROFILE,true);
    end;
  end;
end;


function Logon(Drive, Path, User, Password:String; TemporaryOnly : boolean):Cardinal;
var
  NetRes : TNetResource;
  tempres : Cardinal;
  dwFlags : Cardinal;
begin
  if islocalpath(path) then
    tempres := NO_ERROR //No need to logon
  else begin
    path := ExcludeTrailingPathDelimiter(ExpandUNCFileName(Trim(path)));

    // Windows-Share login
    NetRes.dwScope := RESOURCE_GLOBALNET;
    NetRes.dwDisplayType := RESOURCEDISPLAYTYPE_SHARE;//RESOURCEDISPLAYTYPE_GENERIC;
    NetRes.dwUsage := RESOURCEUSAGE_CONNECTABLE;
    NetRes.lpComment := '';

    // Nur diese Angaben sind notwendig..
    NetRes.dwType := RESOURCETYPE_DISK; // RESOURCETYPE_ANY;
    NetRes.lpLocalName := pchar(Drive);
    NetRes.lpRemoteName := pchar(path);
    NetRes.lpProvider := '';


    if TemporaryOnly then
      dwFlags := CONNECT_TEMPORARY // 0
    else
      dwFlags := CONNECT_UPDATE_PROFILE;

    // CONNECT_UPDATE_RECENT ?

    if User = '' then
      tempres := WNetAddConnection2(NetRes, nil, nil, dwFlags)
    else
      tempres := WNetAddConnection2(NetRes, pchar(Password), pchar(User), dwFlags);
  end;
  result := tempres;
end;

Verbindung herstellen / LW Mappen:

Delphi-Quellcode:
procedure TForm1.ButtonAddNetUseClick(Sender: TObject);
var
  err : DWORD;
begin
  err := Logon(EditLocalDrive.Text, EditShare.Text,EditUser.Text,EditPassword.Text,true);
  if err <> 0 then
    ShowMessage(IntToStr(err) + ' - ' + SysErrorMessage(err));
end;
Öffen des UNC-PFades im Explorer:

Delphi-Quellcode:
  ShellExecute(self.Handle, nil, PChar(AUNCPath),nil,nil,SW_SHOW);


(Erstellt mit D6, eventuell Anpassungen an UniCode notwendig)

Moombas 29. Jun 2018 13:52

AW: Netzwerkordnerzugriff
 
Hat immens geholfen (auch das mit der errorabfrage kannte ich bisher so nicht).

Allerdings taucht bei mir aktuell immer der Error 42 auf (trotz Verbindung & ohne text). Laut Windows gibt es diesen Fehler als Systemfehler auch nicht :?

Edit: Hat sich erledigt. Fehler gefunden.


Vielen Dank HolgerX :D

Luckie 29. Jun 2018 15:17

AW: Netzwerkordnerzugriff
 
Verrätst du uns auch woran es lag? :roll:

Moombas 2. Jul 2018 08:27

AW: Netzwerkordnerzugriff
 
Ich hatte den Code mit dem error

Delphi-Quellcode:
 if err <> 0 then
    ShowMessage(IntToStr(err) + ' - ' + SysErrorMessage(err));
auch auf die shellexecute angewendet, was dann zu der besagten Fehlermeldung führte. Diesen habe ich wieder entfernt und somit läuft es nun ohne Fehlermeldung.

So richtig konnte ich zur 42 zwar nichts finden, aber einige meinten 42 = success also alles gut. Da es aber keine eindeutige Aussage gab, habe ich ihn halt ganz entfernt anstatt die 42 auszuschließen.

jaenicke 2. Jul 2018 09:02

AW: Netzwerkordnerzugriff
 
IIRC sind Rückgabewerte über 32 kein Fehler. In der Doku sehe ich die Information allerdings nicht.

Aviator 3. Jul 2018 09:26

AW: Netzwerkordnerzugriff
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von jaenicke (Beitrag 1406274)
IIRC sind Rückgabewerte über 32 kein Fehler. In der Doku sehe ich die Information allerdings nicht.

Ich helfe dir dann mal :)

Allerdings habe ich direkt im MSDN nachgeschaut und nicht in der Delphi Doku.

Zitat:

Zitat von MSDN
Return Value
Type: HINSTANCE

If the function succeeds, it returns a value greater than 32. If the function fails, it returns an error value that indicates the cause of the failure. The return value is cast as an HINSTANCE for backward compatibility with 16-bit Windows applications. It is not a true HINSTANCE, however. It can be cast only to an int and compared to either 32 or the following error codes below.

Quelle: https://docs.microsoft.com/en-us/win...-shellexecutea

Hervorhebung durch mich.

Anhang 49445

Moombas 30. Sep 2019 11:01

AW: Netzwerkordnerzugriff
 
Bei der Umstellung auf Lazarus habe ich hier nun ein Problem, ich rufe den logon in Lazarus wie folgt auf:

Delphi-Quellcode:
 
  //IPC wird vorher definiert, entspricht der IP-Adresse des anderen PC's
  Path := widestring('\\' + IPC + '\c$');
  err := Logon('', Path, 'username', 'password', true);
  if (err <> 0) then
  begin
    ShowMessage(IntToStr(err) + ' - ' + SysErrorMessage(err));
  end;
Erhalte aber immer einen Fehler:

Delphi-Quellcode:
//Netzlaufwerk verbinden
function TTools.Logon(Drive: String; Path: WideString; User, Password:String; TemporaryOnly : boolean):Cardinal;
var
  NetRes : TNetResource;
  tempres : Cardinal;
  dwFlags : Cardinal;
begin
  if islocalpath(String(Path)) then
  begin
    tempres := NO_ERROR; //No need to logon
  end else
  begin
    path := ExcludeTrailingPathDelimiter(ExpandUNCFileName(Trim(path)));

    // Windows-Share login
    NetRes.dwScope := RESOURCE_GLOBALNET;
    NetRes.dwDisplayType := RESOURCEDISPLAYTYPE_SHARE;//RESOURCEDISPLAYTYPE_GENERIC;
    NetRes.dwUsage := RESOURCEUSAGE_CONNECTABLE;
    NetRes.lpComment := '';

    // Nur diese Angaben sind notwendig..
    NetRes.dwType := RESOURCETYPE_DISK; // RESOURCETYPE_ANY;
    NetRes.lpLocalName := PChar(Drive);
    NetRes.lpRemoteName := PChar(path);
    NetRes.lpProvider := '';

    if TemporaryOnly then
    begin
      dwFlags := CONNECT_TEMPORARY; // 0
    end else
    begin
      dwFlags := CONNECT_UPDATE_PROFILE;
    end;

    // CONNECT_UPDATE_RECENT ?
    if User = '' then
    begin
      tempres := WNetAddConnection2(NetRes, nil, nil, dwFlags);
    end else
    begin
      tempres := WNetAddConnection2(NetRes, PChar(Password), PChar(User), dwFlags);  //FEHLER, Passwort und Benutzernamen passen
    end;
  end;
  result := tempres;
end;
Die Fehlermeldung ist (aus meiner Sicht) wenig aussagend: Projekt Workstation hat Exception-Klasse >>External: SIGSEGV<< ausgelöst.

Evtl. habe ich die Ursache gefunden, jedoch noch keine Lösung.

Delphi-Quellcode:
path := ExcludeTrailingPathDelimiter(ExpandUNCFileName(Trim(path)));
Sorgt dafür das "path" leer ist, ab "ExpandUNCFileName" das sollte wohl eher nicht so sein.

HolgerX 30. Sep 2019 12:19

AW: Netzwerkordnerzugriff
 
Hmm..

Mal ganz blöd gefragt:
Welches TNetResource \ WNetAddConnection2 wird verwendet?

TNetResourceA + WNetAddConnection2A
TNetResourceW + WNetAddConnection2W

Hier solltest Du besser expliziet angeben, welches der beiden verwendet wird und dann am besten auch gleich

TNetResourceW + WNetAddConnection2W


Du castes mal einen WideString mit PChar
Delphi-Quellcode:
NetRes.lpRemoteName := PChar(path);

und mal den Lazarus UTF8 string
Delphi-Quellcode:
tempres := WNetAddConnection2(NetRes, PChar(Password), PChar(User), dwFlags);



Besser
Delphi-Quellcode:
function TTools.Logon(Drive: String; Path: WideString; User, Password:WideString; TemporaryOnly : boolean):Cardinal;
var
  NetRes : TNetResourceW;
..

NetRes.lpRemoteName := PWideChar(path);

..

begin
      tempres := WNetAddConnection2W(NetRes, nil, nil, dwFlags);
    end else
    begin
      tempres := WNetAddConnection2W(NetRes, PWideChar(Password), PWideChar(User), dwFlags);
    end;

Moombas 30. Sep 2019 13:02

AW: Netzwerkordnerzugriff
 
Ok, damit läuft er schon mal scheinbar durch aber verbindet sich nicht.

Wie oben erwähnt, denke ich das "path" dennoch nicht leer sein sollte nach
Delphi-Quellcode:
ExcludeTrailingPathDelimiter(ExpandUNCFileName(Trim(path)));
.
Sobald er ExpandUNCFileName macht, ist path leer, Trim(path) funktioniert also noch.

HolgerX 30. Sep 2019 13:19

AW: Netzwerkordnerzugriff
 
Hmm..

könnte es sein, das ExpandUNCFileName nur dann was zurück gibt, wenn es was zu expandieren hat?

Wenn path bereits UNC ist, dann kommt wohl ein Leerstring zurück...

Zitat:

Delphi-Quellcode:
 //IPC wird vorher definiert, entspricht der IP-Adresse des anderen PC's
  Path := widestring('\\' + IPC + '\c$');


Moombas 1. Okt 2019 07:14

AW: Netzwerkordnerzugriff
 
Das wäre dann aber nur bei Lazarus so, bei Delphi lief das einwandfrei durch.
Wenn ich mir die Funktion jedoch anschaue, ist es wohl eher so, das es bei jedem Fehler, der nicht "ERROR_NOT_CONNECTED" entspricht ein leeres Ergebnis zurück gibt.
Delphi-Quellcode:
function ExpandUNCFileName (const filename:unicodestring) : unicodestring;
...
    if rc = NO_ERROR then
      Result := PRemoteNameInfoW(buf)^.lpUniversalName
    else if rc = ERROR_NOT_CONNECTED then
      Result := filename
    else
      Result := '';          
...
Kann ich mir die Fehlermeldung, die bei "rc" rauskommt irgendwie ausgeben lassen ohne die "Systemfunktion" zu ändern?

..ohne diese Abfrage funktioniert es im Zweifelsfall auch, dennoch würde ich mich interessieren wie man das zum laufen bekommt, da ich hierbei ggf. wieder Unterschiede zwischen Delphi und Lazarus lernen könnte.

Incocnito 1. Okt 2019 10:36

AW: Netzwerkordnerzugriff
 
Hi,

vielleicht denke ich auch nur falsch, aber meiner Meinung nach kann
ExpandUNCFileName
nicht richtig arbeiten, solange die Verbindung zur IP selbst nicht
(mit WNetAddConnection2) bereits hergestellt ist.
Er kann den Rechner ja nicht fragen, weil er ja keine Rechte hat.

Ich hoffe, ihr wisst, worauf ich hinaus will!
"Henne-Ei-Problem"!

LG Incocnito

Moombas 1. Okt 2019 14:01

AW: Netzwerkordnerzugriff
 
Ich hab es erst mal auskommentiert, da es der letzte und einzige Part ist, den ich nun in Lazarus nicht zum laufen bekomme bzw. ohne den ich zurecht kommen würde.
Wenn jemand dafür dennoch eine Lösung weiß wäre ich dankbar.

Dalai 1. Okt 2019 14:28

AW: Netzwerkordnerzugriff
 
Ist zwar nicht direkt eine Lösung, aber zumindest ein ganz pragmatischer Workaround gegen einen leere Rückgabe:
Delphi-Quellcode:
function _ExpandUNCFileName(const AFileName: UnicodeString): UnicodeString;
begin
    Result:= ExpandUNCFileName(AFileName);
    if Result = '' then
        Result:= AFileName;
end;
Weiß nicht, was die Lazarus/FreePascal-Entwickler dazu bewogen hat, die Funktion einen Leerstring zurückgeben zu lassen. Ist das so dokumentiert? Dann ist es soweit in Ordnung. Wenn nicht => Bugreport, damit es gefixt werden kann.

Grüße
Dalai

Moombas 2. Okt 2019 09:04

AW: Netzwerkordnerzugriff
 
Als "Dokumentation" bzw. Hilfe konnte ich nur das finden:
Zitat:

ExpandUNCFileName
Expand a relative filename to an absolute UNC filename.

Declaration
Source position: finah.inc line 31

function ExpandUNCFileName(

const FileName: UnicodeString

):UnicodeString;

function ExpandUNCFileName(

const FileName: RawByteString

):RawByteString;

Description
ExpandUNCFileName runs ExpandFileName on FileName and then attempts to replace the drive letter by the name of a shared disk.

Errors
None.

Moombas 8. Okt 2019 09:33

AW: Netzwerkordnerzugriff
 
Scheinbar ist das so gewollt:
Zitat:

The function does report an error:
Returning an empty string is returning an error. You can check on that.
I will add this to the documentation, however.
Auch wenn ich einen Leerstring nicht als error ansehen würde, da ich dann immer noch nicht weiß, was für ein Fehler aufgetreten ist aber naja die Doku soll angepasst werden.

Luckie 8. Okt 2019 13:41

AW: Netzwerkordnerzugriff
 
GetLastError?

Moombas 11. Okt 2019 13:29

AW: Netzwerkordnerzugriff
 
Hab ich auch schon ausprobiert, bekomme ich leider nichts zurück ('').

Dalai 11. Okt 2019 14:08

AW: Netzwerkordnerzugriff
 
Nichts kann bei GetLastError nicht sein, denn diese Funktion liefert einen Zahlenwert (DWORD). Trotzdem kann es passieren, dass GetLastError nicht hilft, denn wenn innerhalb von ExpandUNCFileName nach dem Aufruf der fehlerauslösenden API-Funktion noch andere API-Funktionen gerufen werden, wird der eigentliche Fehler u.U. verschleiert ...

Grüße
Dalai

Moombas 15. Okt 2019 08:02

AW: Netzwerkordnerzugriff
 
Das kann sein, das ich das GetLastError ggf. zu spät aufgerufen habe beim testen und dann überschrieben war. Will ich jetzt nicht ausschließen.

Da es aber auch ohne diesen Part bzw. mit dem Workaround von Dalai geht, ist es erst mal egal. Finde es nur etwas "seltsam" das das unterschiedlich behandelt wird...


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:41 Uhr.

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