Announcement

Collapse
No announcement yet.

Directorynamen von Netzlaufwerk (UNC) ermitteln

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Directorynamen von Netzlaufwerk (UNC) ermitteln

    Hallo<BR>

    kennt jemand eine Möglichkeit, wie man den kompletten Pfad auf einem Netzlaufwerk ermittelt (Beipiel: \\FS_xxx\PUBLIC\abc.txt) ?

    Hajo

  • #2
    Hallo Hans-Georg,

    eine Möglichkeit habe ich gefunden. Diese Möglichkeit setzt aber vorraus, das in der Registry des Netzrechners gelesen werden darf. Über SelectDirectory ermittel ich einen Ordner und prüfe, ob es ein UNC-Pfad ist. Wenn ja, dann extrahiere ich den Rechnernamen und die Freigabe. Mit Rechnernamen und Freigabe lese ich die Registry des Netzrechners aus und erhalte den tatsächlichen Ordnernamen. Nachfolgend ein Beispiel.

    Viel Erfolg, Jürgen

    <PRE>

    bool __fastcall TfrmPfad::UNCPfad(AnsiString asFileName, AnsiString &asServer, AnsiString &asFreigabe)
    {
    int iPos = 0;
    bool bFlag = false;

    //Wenn das erste Zeichen ein Backslash ist, dann gehe ich davon aus, das es
    //sich um eine UNC-Pfadangabe handelt.
    if(asFileName.SubString(1,1) == "\\")
    {
    bFlag = true;

    //<Servername>
    //Backslash durch Doppelpunkt tauschen
    asFileName.Delete(1, 2);
    iPos = asFileName.Pos("\\");
    asServer = asFileName.SubString(1, iPos-1);
    asFileName.Delete(1, iPos);

    //<Freigabename> ermitteln und merken
    iPos = asFileName.Pos("\\");
    asFreigabe = asFileName.SubString(1, iPos-1);
    }
    return(bFlag);
    }
    //---------------------------------------------------------------------------

    void __fastcall TfrmPfad::HoleRegistryFreigabe()
    {
    TStringList *lstKey = new TStringList;
    TRegistry *pReg = new TRegistry;
    AnsiString asTemp = "";

    char cData[256]; //nimmt die Daten (REG_MULTI_SZ) auf
    memset(cData, ' ', sizeof(cData)); //Initalisierung mit Blanks

    //Der komplette Pfad lautet:
    //"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Servi ces\lanmanserver\Shares"
    try
    {
    pReg->RootKey = HKEY_LOCAL_MACHINE;
    if(pReg->RegistryConnect("\\\\" + asServer)) //Fremde Registry lesen
    {
    if(pReg->OpenKeyReadOnly("SYSTEM"))
    {
    if(pReg->OpenKeyReadOnly("CurrentControlSet"))
    {
    if(pReg->OpenKeyReadOnly("Services"))
    {
    if(pReg->OpenKeyReadOnly("lanmanserver"))
    {
    if(pReg->OpenKeyReadOnly("Shares"))
    {
    if(pReg->ValueExists(asFreigabe))
    {
    //Die Daten liegen als REG_MULTI_SZ, also als mehrere
    //aneinander hängende nullterminierte Strings vor"
    pReg->ReadBinaryData(asFreigabe, cData, sizeof(cData));
    asTemp = ""; //Reset
    for(int i = 0; i < sizeof(cData); i++)
    {
    //Kopiere alle folgenden Zeichen bis zum 0-Terminator.
    //Wenn ein Terminator erreicht ist, dann ist ein Eintrag
    //"Bezeichner=Wert" komplett
    if(cData[i] != '\0')
    {
    asTemp += cData[i]; //Zeichen kopieren
    }
    else
    {
    lstKey->Add(asTemp); //Eintrag "Bezeichner=Wert" speichern
    asTemp = ""; //Reset
    }
    }
    //Ein Eintrag "Bezeichner=Wert" enthält die Freigabe:
    //"Path=F:\"; also nach "Path" suchen und Wert zurück-
    //geben
    asFreigabeLW = lstKey->Values["Path"];
    }
    else
    {
    asFreigabeLW = ""; //Nicht gefunden
    }
    }
    else
    {
    asFreigabeLW = ""; //Nicht gefunden
    }
    }
    else
    {
    asFreigabeLW = ""; //Nicht gefunden
    }
    }
    else
    {
    asFreigabeLW = ""; //Nicht gefunden
    }
    }
    else
    {
    asFreigabeLW = ""; //Nicht gefunden
    }
    }
    else
    {
    asFreigabeLW = ""; //Nicht gefunden
    }
    }
    } //try
    catch(ERegistryException &E)
    {
    delete pReg;
    lstKey->Clear();
    delete lstKey;
    String s = "Zugriff auf die Registry ist fehlgeschlagen";
    Application->MessageBox(E.Message.c_str(), s.c_str(), MB_OK);
    } //catch
    delete pReg;
    lstKey->Clear();
    delete lstKey;
    }
    //---------------------------------------------------------------------------

    void __fastcall TfrmPfad::Button1Click(TObject *Sender)
    {
    AnsiString asDir = "";
    AnsiString asPfadDatei = "";
    i

    Comment


    • #3
      <PRE>

      void __fastcall TfrmPfad::Button1Click(TObject *Sender)
      {
      AnsiString asDir = "";
      AnsiString asPfadDatei = "";
      int iPos = 0;

      txtInit();
      if(SelectDirectory("Ziel-Ordner wählen.", WideString(asDir), asDir))
      {
      //Pfad ausgeben
      txtPfad->Text = asDir;
      //Prüfen, ob Datenbank im UNC-Pad liegt und "<Servername>" und "<Freigabename>"
      //extrahieren
      if(UNCPfad(asDir, asServer, asFreigabe))
      {
      //UNC-Pfad zwischenspeichern und "\\<Servername>\<Freigabename>" entfernen
      asPfadDatei = asDir;
      asPfadDatei.Delete(1, asServer.Length()+2); //Entferne "<Servername>"+2 wegen "\\"
      asPfadDatei.Delete(1, asFreigabe.Length()+2); //Entferne "<Freigabename>"+2 wegen "\\"
      //Prüfen, ob administative Freigabe vorliegt (z.B. "c$" oder "h$")
      iPos = asFreigabe.Pos("$");
      if(iPos == 0)
      {
      //Keine administative Freigabe, Freigabename auflösen
      HoleRegistryFreigabe();
      if(asFreigabeLW == "")
      {
      AnsiString asMsg = "Auf die Registry von Rechner\r\n";
      asMsg += "\t<" + asServer + ">\r\n";
      asMsg += "konnte nicht zugegriffen werden!";
      MessageDlg(asMsg, mtWarning, TMsgDlgButtons()<<mbOK, 0);
      }
      }
      else
      {
      //administative Freigabe, "$" in Freigabename durch ":\" ersetzen
      asFreigabeLW = asFreigabe;
      asFreigabeLW.Delete(iPos, 1);
      asFreigabeLW.Insert(":\\", iPos);
      }
      //TCP/IP-Pfad zusammenbauen, wenn asFreigabeLW einen Text enthält.
      if(asFreigabeLW != "")
      {
      txtTCPPfad->Text = asServer + ":" + asFreigabeLW + asPfadDatei;
      }
      }
      else
      {
      //Datenbank liegt im lokalen Pfad
      txtTCPPfad->Text = asDir;
      }
      }
      }
      //---------------------------------------------------------------------------

      <\PRE&gt

      Comment


      • #4
        Hallo Jürgen<BR>
        vielen Dank für die ausführliche Antwort.<BR>
        Wahrscheinlich habe ich nicht genau erklärt, was ich vorhabe. Ich möchte über das Netz auf einen anderen Computer zugreifen, ohne daß ich über "Netzwerk verbinden" dem Netzcomputer einen Laufwerksbuchstaben zuordnen muß. Es gibt eine Komponente "TOpenDirectory", die dies beherrscht. Allerdings möchte ich diese Komponente in der vorliegenden Form nicht einsetzen. Gibt es keine andere Möglichkeit dies zuerreichen ?<BR>
        Gruss Hajo

        Comment


        • #5
          Hallo Hans-Georg,

          die Komponente TOpenDirectory kenne ich nicht. Mein Beispiel wurde mit dem C++Bulder 5 entwickelt. Dort habe ich SelectDirectoy aus der Unit FileCtrl benutzt. Das geht so leidlich...

          <PRE>
          if(SelectDirectory("Ziel-Ordner wählen.", WideString(asDir), asDir))
          {
          //Tu was...
          }
          <\PRE>

          Mit obiger Anweisung hangle ich mich durch die (Netzwerk-)Ordner. Wenn ich den OK-Button drücke, werte ich den AnsiString asDir aus und schaue, ob es ein UNC-Pfad ist, den ich dann entsprechend weiterverarbeite.

          Ciao, Jürge

          Comment


          • #6
            Hallo,<BR>
            das mappen eines Laufwerks ohne Laufwerksbuchstabe sollte so ungefähr gehen:

            <pre>

            //---------------------------------------------------------------------------
            // Netzlaufwerk verbinden
            // LocalName = Driveletter mit Doppelpunkt
            // RemoteName = UNC-Pfad
            //
            bool TForm1::MapNetworkDrive(char *UserName, char *Password, char *LocalName, char *RemoteName)
            {
            // MPR.LIB
            NETRESOURCE nr;
            DWORD res;
            bool rc;
            // UserName = "UserName",
            // Password = "Password",
            // LocalName = "Q:",
            // RemoteName = "\\\\products2\\relsys";
            //
            nr.dwType = RESOURCETYPE_ANY;
            nr.lpLocalName = LocalName;
            nr.lpRemoteName = RemoteName;
            nr.lpProvider = NULL;
            //
            res = WNetAddConnection2(&nr, Password, UserName, FALSE);
            if(res == NO_ERROR)
            {
            rc = true;
            }
            else
            {
            rc = false;
            }
            return(rc);
            }
            //---------------------------------------------------------------------------
            // Netlaufwerk abhängen
            // LocalName = Laufwerksbuchstabe oder UNC Pfad des Shares
            //
            bool TForm1::ReleaseNetworkDrive(char *LocalName)
            {
            bool rc;
            DWORD dwResult;

            dwResult = WNetCancelConnection2(LocalName,
            CONNECT_UPDATE_PROFILE,
            FALSE); // nicht abhängen wenn Dateien offen sind

            if(dwResult == NO_ERROR)
            {
            rc = true;
            }
            else
            {
            rc = false
            }
            return(rc);
            }

            </pre>
            Gruss<BR>
            Armi

            Comment

            Working...
            X