Hallo,
lange her seit dem letzten Beitrag, aber das Problem ist wohl noch aktuell.
Wie oben schon erwähnt wurde, gibt es ab Vista die Funktion "
WNetRestoreConnectionW" nicht mehr, so dass der Code von shmia im Post #3 unter Windows 8.1 nicht funktioniert.
In
diesem Artikel zu der entfernten Funktion wird im Abschnitt "Community Additions" unter "The Third Parameter is WRONG" die Funktion "
WNetRestoreSingleConnectionW" erwähnt, die es auch in Vista, Windows 8.1 etc. gibt. Klang vielversprechend, also habe ich das Beispiel aus Post #3 wie folgt abgeändert:
Code:
type
TWNetRestoreSingleConnectionW = function (hwndParent:HWND; lpDevice:PWideChar; fUseUI:boolean):DWORD; stdcall;
function ReconnectDrive(const path:string):DWORD;
var
libhandle : HMODULE;
func : TWNetRestoreSingleConnectionW;
driveW : WideString;
begin
Result := 0;
driveW := ExtractFileDrive(path);
if driveW='' then
Exit;
libhandle := LoadLibrary('mpr.dll');
if libhandle=0 then
Exit;
try
func := TWNetRestoreSingleConnectionW(GetProcAddress(libhandle, 'WNetRestoreSingleConnectionW'));
if Assigned(func) then
Result := func(0, @driveW[1], true);
finally
FreeLibrary(libhandle);
end;
end;
Leider zu früh gefreut. Übergibt man für "fUseUI" false, gibt es keine Rückmeldung und das Laufwerk bleibt "inaktiv". Übergibt man true, bleibt das Laufwerk zwar auch "inaktiv", aber es wird zumindest das angezeigt:
Zitat:
Fehler bei der erneuten Verbindungsherstellung von K: mit
\\SV-MAIN\K (Entwicklung)
Microsoft Windows Network: Der lokale Gerätename wird bereits verwendet.
Die Verbindung wurde nicht wiederhergestellt.
Ansonsten habe ich nach längeren Recherchen noch diese zwei Möglichkeiten gefunden:
#1
http://www.devsuperpage.com/search/A...p?ArtID=149021
Code:
function ConnectDrive(_drvLetter: string; _netPath: string; _showError:
Boolean;
_reconnect: Boolean): DWORD;
var
nRes: TNetResource;
errCode: DWORD;
dwFlags: DWORD;
begin
{ Fill NetRessource with #0 to provide uninitialized values }
{ NetRessource mit #0 füllen => Keine unitialisierte Werte }
FillChar(NRes, SizeOf(NRes), #0);
nRes.dwType := RESOURCETYPE_DISK;
{ Set Driveletter and Networkpath }
{ Laufwerkbuchstabe und Netzwerkpfad setzen }
nRes.lpLocalName := PChar(_drvLetter);
nRes.lpRemoteName := PChar(_netPath); { Example: \\Test\C }
{ Check if it should be saved for use after restart and set flags }
{ Überprüfung, ob gespeichert werden soll }
if _reconnect then
dwFlags := CONNECT_UPDATE_PROFILE and CONNECT_INTERACTIVE
else
dwFlags := CONNECT_INTERACTIVE;
errCode := WNetAddConnection3(Form1.Handle, nRes, nil, nil, dwFlags);
{ Show Errormessage, if flag is set }
{ Fehlernachricht aneigen }
if (errCode <> NO_ERROR) and (_showError) then
begin
Application.MessageBox(PChar('An error occured while connecting:' +
#13#10 +
SysErrorMessage(GetLastError)),
'Error while connecting!',
MB_OK);
end;
Result := errCode; { NO_ERROR }
end;
#2
http://www.experts-exchange.com/ques...ped-Drive.html
Code:
function RefreshMappedDrive(cDrvLetter: Char): Boolean;
const
WbemUser ='';
WbemPassword ='';
WbemComputer ='
localhost';
wbemFlagForwardOnly = $00000020;
var
FSWbemLocator : OLEVariant;
FWMIService : OLEVariant;
FWbemObjectSet: OLEVariant;
FWbemObject : OLEVariant;
oEnum : IEnumvariant;
iValue : LongWord;
WshNetwork : OLEVariant;
begin;
Result := False;
FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
FWMIService := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
FWbemObjectSet:= FWMIService.ExecQuery('SELECT LocalName,ConnectionState,RemotePath FROM Win32_NetworkConnection','WQL',wbemFlagForwardOnly);
oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
while oEnum.Next(1, FWbemObject, iValue) = 0 do
begin
if String(FWbemObject.LocalName) = (cDrvLetter+':') then //if this drive
begin
if String(FWbemObject.ConnectionState) <> 'Connected' then //if disconnected
begin
//try to reconnect ....
try
WshNetwork := CreateOleObject('WScript.Network');
WshNetwork.MapNetworkDrive(cDrvLetter+':', String(FWbemObject.RemotePath));
except
end;
Result := True;
end
else
begin
Result := True;
end;
Break;
end;
FWbemObject:=Unassigned;
end;
end;
procedure TForm1.Button6Click(Sender: TObject);
begin
if FileExists('z:\test.txt') then
Memo2.Lines.Add('exists')
else
begin
Memo2.Lines.Add('connecting');
CoInitialize(nil);
try
RefreshMappedDrive('Z');
finally
CoUninitialize;
end;
end;
end;
Beide funktionieren aber ebenfalls nicht so richtig.
Beim ersten Beispiel gibt es das:
Zitat:
An error occured while connecting:
Der angegebene Gerätename ist unzulässig
Beim zweiten Beispiel gibt es das:
Zitat:
Der lokale Gerätename wird bereits verwendet
Sonst gab es noch Beiträge zum tatsächlichen Einrichten / Entfernen von Netzlaufwerken per Code, was aber aufgrund der höchstwahrscheinlichen notwendigen Eingabe des Benutzernamens / des Passwords etc. nicht infrage kommt.
Habt Ihr vielleicht neuere Erkentnisse / Lösungsvorschläge?