Einzelnen Beitrag anzeigen

shadowman

Registriert seit: 1. Nov 2005
48 Beiträge
 
#6

AW: "Nichtverbundenes Netzlaufwerk" aktivieren

  Alt 11. Dez 2015, 11:21
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?
  Mit Zitat antworten Zitat