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. |
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. |
AW: Netzwerkordnerzugriff
Hmm..
Zitat:
Wenn Ja, dann müsste das '$' hinter dem Laufwerksnamen stehen.. ;) "\\xx.xx.xx.xx\c$\" |
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. |
AW: Netzwerkordnerzugriff
Zitat:
|
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); |
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).
|
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) |
AW: Netzwerkordnerzugriff
Das funktioniert -.- also liegt es scheinbar doch irgendwie an mir.
|
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? |
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:
Öffen des UNC-PFades im Explorer:
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;
Delphi-Quellcode:
ShellExecute(self.Handle, nil, PChar(AUNCPath),nil,nil,SW_SHOW);
(Erstellt mit D6, eventuell Anpassungen an UniCode notwendig) |
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 |
AW: Netzwerkordnerzugriff
Verrätst du uns auch woran es lag? :roll:
|
AW: Netzwerkordnerzugriff
Ich hatte den Code mit dem error
Delphi-Quellcode:
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.
if err <> 0 then
ShowMessage(IntToStr(err) + ' - ' + SysErrorMessage(err)); 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. |
AW: Netzwerkordnerzugriff
IIRC sind Rückgabewerte über 32 kein Fehler. In der Doku sehe ich die Information allerdings nicht.
|
AW: Netzwerkordnerzugriff
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Allerdings habe ich direkt im MSDN nachgeschaut und nicht in der Delphi Doku. Zitat:
|
AW: Netzwerkordnerzugriff
Bei der Umstellung auf Lazarus habe ich hier nun ein Problem, ich rufe den logon in Lazarus wie folgt auf:
Delphi-Quellcode:
Erhalte aber immer einen Fehler://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;
Delphi-Quellcode:
Die Fehlermeldung ist (aus meiner Sicht) wenig aussagend: Projekt Workstation hat Exception-Klasse >>External: SIGSEGV<< ausgelöst.
//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; Evtl. habe ich die Ursache gefunden, jedoch noch keine Lösung.
Delphi-Quellcode:
Sorgt dafür das "path" leer ist, ab "ExpandUNCFileName" das sollte wohl eher nicht so sein.
path := ExcludeTrailingPathDelimiter(ExpandUNCFileName(Trim(path)));
|
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; |
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. |
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:
|
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:
Kann ich mir die Fehlermeldung, die bei "rc" rauskommt irgendwie ausgeben lassen ohne die "Systemfunktion" zu ändern?
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 := ''; ... ..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. |
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 |
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. |
AW: Netzwerkordnerzugriff
Ist zwar nicht direkt eine Lösung, aber zumindest ein ganz pragmatischer Workaround gegen einen leere Rückgabe:
Delphi-Quellcode:
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.
function _ExpandUNCFileName(const AFileName: UnicodeString): UnicodeString;
begin Result:= ExpandUNCFileName(AFileName); if Result = '' then Result:= AFileName; end; Grüße Dalai |
AW: Netzwerkordnerzugriff
Als "Dokumentation" bzw. Hilfe konnte ich nur das finden:
Zitat:
|
AW: Netzwerkordnerzugriff
Scheinbar ist das so gewollt:
Zitat:
|
AW: Netzwerkordnerzugriff
GetLastError?
|
AW: Netzwerkordnerzugriff
Hab ich auch schon ausprobiert, bekomme ich leider nichts zurück ('').
|
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 |
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