Laden...

Mit Netzwerkfreigabe verbinden

Erstellt von R3turnz vor 8 Jahren Letzter Beitrag vor 8 Jahren 9.497 Views
R
R3turnz Themenstarter:in
125 Beiträge seit 2016
vor 8 Jahren
Mit Netzwerkfreigabe verbinden

Hallo,
ich möchte mich innerhalb meines Programmes mit einer Netzwerk-Freigabe verbinden, ich habe folgendes Snippet gefunden:


        /// <summary>
        /// Disconnects a network drive
        /// </summary>
        /// <param name="drive">Drive (z.B. L:)</param>
        private void MapNetworkDriveDisconnect(string drive)
        {
            Process p = new Process();
            p.StartInfo.FileName = "net";
            p.StartInfo.Arguments = string.Format("use {0} /DELETE", drive);
            p.StartInfo.UseShellExecute = false;
            p.Start();
        }
        /// <summary>
        /// Connects a network drive
        /// </summary>
        /// <param name="drive">The drive letter (e.g. L:)</param>
        /// <param name="server">The UNC path to the remote drive (e.g. \\MyServer\MyPrinter)</param>
        /// <param name="user">The User</param>
        /// <param name="password">The Password Used For Login</param>
        private void MapNetworkDriveConnect(string drive, string server, string user, string password)
        {
            Process p = new Process();
            p.StartInfo.FileName = "net";
            p.StartInfo.Arguments = string.Format("use {0} {1} /user:{2} {3}", drive, server, user, password);
            p.StartInfo.UseShellExecute = false;
            p.Start();
        }

(von http://dotnet-snippets.de/snippet/netzlaufwerke-verbinden-trennen-mit-user-u-passwort/1429)
Meine jetzige Planung sieht so aus:
Ich brauche einen Laufwerknamen, dazu brauche ich ein Alphabet, wie stelle man das am besten an? Den Rest zum nächsten freien Laufwerk-Namen habe ich schon.

Wie man oben erkennt startet er einen Prozess, wie kann ich hier das Ergebnis abfragen, also ob die Verbindung erfolgreich war?

LG

16.835 Beiträge seit 2008
vor 8 Jahren

Den Process Output auswerten, wenn Du es darüber machen willst.
Google-Suche nach c# get process output

Er kann - muss nicht - je nach eingestellter Systemsprache und/oder Betriebssversion anders sein.
Einfacher / besser ist hier Powershell mit dem Befehl New-PSDrive

Zur Not kannst Du via C# PowerShell ausführen und bekommst so ordentlich auswertbare Rückgabewerte.

Nimm nicht immer gleich das erste Snippet, das Du findest. Schau Dir auch die Möglichkeiten an und überdenke, ob das ein adäquater Weg ist.
Das Snippet hat so ein Bart, da gabs.. stammt aus einer Zeit als es noch kein Powershell gab.

Und stelll Dir auch immer selbst die Frage: bin ich wirklich der erste, der auf das Problem stößt oder könnte es nich dazu schon eine Lösung im Internet geben? 😉

R
R3turnz Themenstarter:in
125 Beiträge seit 2016
vor 8 Jahren

Hallo,
ich scheitere gerade noch an der Umsetzung. Ich möchte System.Management.Automation importieren, jedoch exestiert sie nicht bei mir, (Siehe Anhang) Wahrscheinlich hab ich irgendwas übersehen. 😁
Da ich komplet wenig zu einer Powershell in C# finden kann, außerdem dem msdn Eintrag, wollte ich noch wissen, wie ich an den "Output" komme, ich habe einen HasErrors Member gefunden, soll ich einfach so überprüfen?

LG

R
R3turnz Themenstarter:in
125 Beiträge seit 2016
vor 8 Jahren

Hey,
okay ich bin nun ein gutes Stück weiter:


        public bool Connect(string root, string user, string password)
        {
            var name = getNextDriveName();
            if (name == ' ') return false;
            try
            {
                
                using (var powershell = PowerShell.Create())
                {
                    powershell.AddCommand(string.Format("New - PSDrive –Name “{0}” –PSProvider FileSystem –Root “{1}”",name + ":\\",root), true);
                    Collection<PSObject> powershellobjects = powershell.Invoke();
                    //Temporär um die möglichen Ausgaben zu finden.//

                    foreach (var powershellobject in powershellobjects)
                    {
                        if (powershellobject != null)
                            Console.WriteLine(powershellobject.BaseObject.ToString());
                        Console.ReadKey();
                    }
                }
            }
           catch
            {
                return false;
            }
            return true;
        }
           
            
            
        private char getNextDriveName()
        {
            //Ich finde die Konvertierung hier nicht schön, brauche aber die Remove Methode, wenn ich das Element löschen möchte. 
            char[] alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
            ArrayList alphabet =  ArrayList.Adapter(alpha);
            DriveInfo[] drives = DriveInfo.GetDrives();
            foreach(var drive in drives)
            {
                alphabet.Remove(char.Parse(drive.Name.Substring(0, 1)));
            }

            return alphabet.Length > 0 ? (char)alphabet[0] : ' ';
                
        }

Das Problem ist es wirde eine Exception geschmissen, mein Command würde nicht exestieren, wie muss es richtig angeben?

LG

B
88 Beiträge seit 2016
vor 8 Jahren

Hallo R3turnz,

ich habe keine Ahnung von PowerShell, aber wie wird der Command denn zusammengebaut?
Hast du ihn dir mal ausgeben lassen, wie ist die Ausgabe? Vielleicht springt es dir oder jemand anderem dann ins Auge.

Gruß

R
R3turnz Themenstarter:in
125 Beiträge seit 2016
vor 8 Jahren

Hey,
das nomale Powershell schluckt den Befehl, in meinem Fall würde der so aussehen:


New-PSDrive –Name “K” –PSProvider FileSystem –Root “\\192.168.1.46\Rasp” –Persist

Hier meint Powershell der Typ der Netzwerkresource wäre falsch.> Fehlermeldung:

New-PSDrive : Der Typ der Netzwerkressource ist falsch
In Zeile:1 Zeichen:1

  • New-PSDrive –Name “K” –PSProvider FileSystem –Root “\192.168.1.46\Ra ...
  •   + CategoryInfo          : InvalidOperation: (K:PSDriveInfo) [New-PSDrive], Win32Exception  
      + FullyQualifiedErrorId : CouldNotMapNetworkDrive,Microsoft.PowerShell.Commands.NewPSDriveCommand
    

Mir ist gerade aufgefallen das ich nur Powershell 1.0 installiert habe, irgendwo meine ich gelesen habe, das erst mit Powershell 2.0 die KLasse verwendet werden kann.

Wenn ich Powershell nachinstallieren möchte gibt es nur Versionen für WIndows 7, diese funktionieren bei mir auch nicht.

LG

PS:Der Thread zieht sich immer mehr weg von der eigentlichen Freigabe und gehört jetzt schon fast mehr in Infrastruktur 😃 Wie geht man damit um?

16.835 Beiträge seit 2008
vor 8 Jahren

Mach Dir um die Threadkategorisierung keine Sorgen; aber aussagen wie "geht nicht" helfen niemanden und machen es auch fast unmöglich, Dir zu helfen.
Was geht denn nicht? Fehlermeldung?

Aktuelle Powershell-Version ist 5.0 und ist bei Windows 10 default.
Windows 7 hat die Powershell Version 2 als default.

Deine Fehlermeldung sagt auch deutlich, dass der Befehl falsch benutzt wurde und nicht, dass der Befehl nicht existiert.

PS: vermeide ArrayList und verwende typisierte Listen wie List<string>.

R
R3turnz Themenstarter:in
125 Beiträge seit 2016
vor 8 Jahren

Hallo,> Fehlermeldung:

Ein Ausnahmefehler des Typs "System.Management.Automation.CommandNotFoundException" ist in System.Management.Automation.dll aufgetreten.

Zusätzliche Informationen: Das Modul "New - PSDrive –Name “A” –PSProvider FileSystem –Root “" konnte nicht geladen werden. Wenn Sie weitere Informationen wünschen, führen Sie "Import-Module New - PSDrive –Name “A” –PSProvider FileSystem –Root “" aus.

Dieser Fehler tit aus dem Code heraus auf.

Folgender bei gleichem Befehl in Powershell:> Fehlermeldung:

New-PSDrive : Der angegebene Laufwerkstamm "\192.168.1.46\Rasp" ist entweder nicht vorhanden, oder es handelt sich
nicht um einen Ordner.
In Zeile:1 Zeichen:1

  • New-PSDrive –Name “A” –PSProvider FileSystem –Root “\192.168.1.46\Ra ...
  •   + CategoryInfo          : ReadError: (A:PSDriveInfo) [New-PSDrive], IOException  
      + FullyQualifiedErrorId : DriveRootError,Microsoft.PowerShell.Commands.NewPSDriveCommand
    

Ich kann die Freigabe über den Windows Explorer ganz normal abrufen.

Habe jetzt auch die Arraylist weg:


 List<char> alphabet = new List<char>();
            for (char c = 'A'; c < 'Z'; c++)
            {
                alphabet.Add(c);
            }
            DriveInfo[] drives = DriveInfo.GetDrives();
            foreach(var drive in drives)
            {
                alphabet.Remove(char.Parse(drive.Name.Substring(0,1)) );
            }

            return alphabet.Any() ? alphabet[0] : ' ';

Das mit der Version war mein Fehler, neben einer exe in Version 1.0 gibt es auch noch eine ohne Versionsangabe, wahrscheinlich dann 5.0.

LG

16.835 Beiträge seit 2008
vor 8 Jahren

Hier steht jetzt was von CommandNotFoundException, was dann doch suggeriert, dass er den Command nicht findet.
Zudem ist die Value bei Root leer, was ungültig ist. (=> Debugger)

Könnte daran liegen, dass der Command "New-PSDrive" und nicht "New - PSDrive" heisst.
Weiß nicht, woher Du die Leerzeichen hast. Oben hab ichs entsprechend schon ohne Leerzeichen beschrieben. Leerzeichen in Commandnamen gibts bei Powershell nicht.

Ansonsten scheint Deine Share eben halt nicht zu existieren. Das sagt die Fehlermeldung auch aus.
Würde also mal Deinen Rasp anschauen, ob die Config stimmt.

Denn prinzipiell geht der Command. Siehe angehängtes Foto.

Gut gemeinter Rat:
Du machst immer wieder kleine Fehler, die durch einen zweiten, dritten Blick auffallen sollten.
Das sind Fehler, die Folgefehler verursachen und sich leicht durch die Fehlermeldung entdecken lassen, zB eben, dass der Kommandname nicht gefunden wurde.
Da sollte Dir eigentlich auffallen, dass was mit dem Commandname nicht stimmt, hier eben die Leerzeichen.
Schenk den Fehlermeldungen also ein bisschen mehr Aufmerksamkeit, und Du kommst selbst viel schneller voran.

R
R3turnz Themenstarter:in
125 Beiträge seit 2016
vor 8 Jahren

Hallo,
ich hatte im vorhinein schon debuggt, ein bisschen habe ich schon dazu gelernt 🙂

Das mit den Leerzeichen hatte ich selber nach dem letzten Post auch schon ausprobiert macht aber keinen Unterschied.
Außerdem ist root auch nicht null. (Siehe Anhang)

Mein Pi ist auf jeden Fall richtig konfiguriert, ich kann Datein übertragen etc. Er braucht normalerweise noch ein Passwort , dafür müsste er ihn aber erstmal finden 🤔

Über Powershell funktioniert es jetzt auch, wo er das Passwort herhat weiß ich nicht, hatte mich davor schoneinmal angemeldet, vieleicht daher?

Aus dem Code weiterhin folgende Fehlermeldung:> Fehlermeldung:

System.Management.Automation.dll aufgetreten.

Zusätzliche Informationen: Das Modul "New-PSDrive –Name “B” –PSProvider FileSystem –Root " " konnte nicht geladen werden. Wenn Sie weitere Informationen wünschen, führen Sie "Import-Module New-PSDrive –Name “B” –PSProvider FileSystem –Root " " aus.

Folgender Code läuft:

   
using (var powershell = PowerShell.Create())
                {
                    powershell.AddCommand(string.Format("New-PSDrive –Name “{0}” –PSProvider FileSystem –Root \" {1} \" ",name,root));
                    Collection<PSObject> powershellobjects = powershell.Invoke();
                    //Temporär um die möglichen Ausgaben zu finden.//
                   
                    foreach (var powershellobject in powershellobjects)
                    {
                        if (powershellobject != null)
                            Console.WriteLine(powershellobject.BaseObject.ToString());
                        Console.ReadKey();
                    }
                }

Ob ich bei root die Anführungszeichen habe, oder nicht macht keinen Unterschied.

LG

B
88 Beiträge seit 2016
vor 8 Jahren

Mir fällt noch auf, dass Abt einen UNC Namen benutzt

\abtnas1\Backups und du eine lokale Netzwerk IP
192., ...

Kann es eventuell damit zusammenhängen?

  • FullyQualifiedErrorId Lässt mich in diese Richtung denken.

Werde mich jetzt aber aus dem Thread hier zurückziehen, da ich nur rate 😉

edit: Wie kommt es eigentlich, dass die Leerzeichen bei "New - PSDrive –Name “ in deinem Code auftauchen, aber nicht in der "angeblichen" Ausgabe, die du gepostet hast?
Du kannst dir sowas im Direktfenster im Debugger ausgeben lassen. Es war jetzt nicht Sinn der Übung, dass du uns mitteilst was du denkst was da stehen müsste, oder wie kam das zustande?

16.835 Beiträge seit 2008
vor 8 Jahren

powershell.AddCommand(string.Format("New-PSDrive –Name “{0}” –PSProvider FileSystem –Root \" {1} \" ",name,root));

dürfte sowieso ungültig sein, da Leerzeichen im Root nicht erlaubt sind.
Der Output hier wäre " Root ". Und auch die Hochkomma beim Namen sind ungültig oder könnten dazu führen, dass es als Name statt als Drive registriert wird.

Deine Fehlermeldung zeigt aber, dass Root leer ist.
Wobei ich ehrlich gesagt keine wirkliche Ahnung hab, was Dein Fehler auslöst, wenn wenn ich New-PSDrive –Name “B” –PSProvider FileSystem –Root " " ausführe nimmt er statt einem leeren Root das aktuell ausführende Verzeichnis.

Wenn ich nach powershell the module could not be loaded google könnte es durchaus an der Powershell und dem ausführenden Verzeichnis liegen.
Mit dem Befehl $PSVersionTable findest Du raus, welche Powershell Version Du hast. Bei mir ist es 5.0.10586.63.

Ich probiers mal mit meinem Rasp aus.
Antworte gleich...

Mein Rasp hats wohl erwischt.. Grüne LED blinkt..
7 flashes: kernel.img not found

16.835 Beiträge seit 2008
vor 8 Jahren

Also ich konnte es nun mit meiner NAS testen.
Sowohl die Registrierung über die IP wie auch über den Namen funktionieren.

Vermutlich ist beiu mir in Windows 10 das Modul von Haus aus geladen und Du musst es manuell (evtl. aufgrund der Version?) nachladen.
Aber wie man die entsprechenden Module lädt steht ja in der Doku bzw. findet man dazu zig Beispiele.
Einfach mal ein wenig Google verwenden.... dafür sind Suchmaschinen da.

R
R3turnz Themenstarter:in
125 Beiträge seit 2016
vor 8 Jahren

Hallo,
habe die Hochkomma entfernt.
Ich verstehe ein Modul als einen Art dll die geladen wird.

Ich habe auch Windows 10 mit Power-Shell 5.0, wie gesagt ist das Modul auch einscheinend geladen wenn ich Powershell normal verwende. Es könnte sein, dass das Auto-Loading (Powershell soll Module wenn gebraucht automatisch importieren) nicht funktioniert, wenn Powershell selber nicht gestartet wurde..Um zu Laden muss ich wissen , welches Modul müsste ich den Laden, und wo dieses liegt.

LG

16.835 Beiträge seit 2008
vor 8 Jahren

Importing a PowerShell Module
New-PSDrive

Und da steht, dass sich New-PSDrive in Module Microsoft.PowerShell.Management befindet.

R
R3turnz Themenstarter:in
125 Beiträge seit 2016
vor 8 Jahren

Achso, habe auch den Baum auf der rechten Seite gar nicht geachtet, werde es gleich mal probieren...

R
R3turnz Themenstarter:in
125 Beiträge seit 2016
vor 8 Jahren

Leider wieder Fehlanzeige:> Fehlermeldung:

Ein Ausnahmefehler des Typs "System.Management.Automation.CommandNotFoundException" ist in System.Management.Automation.dll aufgetreten.

Zusätzliche Informationen: Die Benennung "Import-Module Microsoft.PowerShell.Management" wurde nicht als Name eines Cmdlet, einer Funktion, einer Skriptdatei oder eines ausführbaren Programms erkannt. Überprüfen Sie die Schreibweise des Namens, oder ob der Pfad korrekt ist (sofern enthalten), und wiederholen Sie den Vorgang.

Er findet den Befehl nicht, obwohl er in Powershell direkt gefunden wird.
Hierbei habe ich jetzt das gleiche Problem wie der Typ im vochher verlinkten Thread, wie es aussieht haben die dort keine Lösung gefunden.
(https://social.msdn.microsoft.com/Forums/vstudio/en-US/7bcbfcba-7072-4757-8da7-bcb69de3d8fc/how-do-i-import-a-powershell-module-in-c?forum=csharpgeneral)
Werde nachher nochmal die dort gepostete RunScript Methode versuchen.

LG

16.835 Beiträge seit 2008
vor 8 Jahren

Und wie sieht Dein Code aus......................?
Siehe auch Powershell Import-Module command doesn't work with c# api

Auch hier wieder CommandNotFound mit sehr wahrscheinlich den gleichen Fehlersymptomen wie oben.

Probier immer ein paar Sachen aus.

R
R3turnz Themenstarter:in
125 Beiträge seit 2016
vor 8 Jahren

Hallo,
ich habe mir ein bisschen mehr Zeit gelassen:
Im verlinkten Thread bietet er 3 Möglichkeiten an.
1.Er fügt die Parameter über die AddParameter Methode ein, folgender Code:


powershell.Commands.AddCommand("Import-Module").AddParameter("Microsoft.Powershell.Managment");

                powershell.AddCommand(string.Format("NewPSDrive –Name “{0}” –PSProvider FileSystem –Root {1}", name, root));
                    Collection<PSObject> powershellobjects = powershell.Invoke();

Fehlermeldung:
Ein Ausnahmefehler des Typs "System.Management.Automation.CommandNotFoundException" ist in System.Management.Automation.dll aufgetreten.

Zusätzliche Informationen: Das Modul "NewPSDrive –Name “A” –PSProvider FileSystem –Root " konnte nicht geladen werden. Wenn Sie weitere Informationen wünschen, führen Sie "Import-Module NewPSDrive –Name “A” –PSProvider FileSystem –Root " aus.

An der Fehlermeldung sehe ich, das der erste Command scheinbar durchgelaufen ist das Modul aber immer noch nicht geladen ist.
Da der erste Kommand ja funktioniert hat, und dies offensichtlich ein Erfolg ist, wollte ich den zewiten genauso umgestalten.
Dabei kam folgender Code heraus:


 powershell.Commands.AddCommand("Import-Module").AddParameter("Microsoft.Powershell.Managment");

                powershell.AddCommand("New-PSDrive").AddArgument("Name \"" + name+"\"").AddArgument("PSProvider FileSystem").AddArgument("Root "+root);

Fehlermeldung:
Ein Ausnahmefehler des Typs "System.Management.Automation.ParameterBindingException" ist in System.Management.Automation.dll aufgetreten.

Schonmal eine andere Fehlermeldung, soweit ich den einen Satz in der Domumentation verstehe, das ich einen ungültigen Wert bei einem der Argumente Angegeben habe. Nach ein bisschen debuggen habe ich folgendes gefunden: Der Name also das eigentliche Argument scheint er nicht zu erkennen, und einfach alles in value zu schreiben. (Siehe Anhang) Die Exception scheinen daher zu kommen, da er die Escapesequenzen nicht erkennt und so plötzlich 4 \ vor dem root hat.
Ich habe es mit einem @ vor dem root versucht, jedoch wieder 4 .

Ich weiß nicht genau wie ich hier weiter machen soll, oder ob die \ überhaupt der Grund sind.
Die weiteren möglichkeiten habe ich gar nicht mehr probiert, da er den ersten Command jetzt zu schlucken scheint, hier erkennt er auch den Namen und den Wert des Parameters richtig.

LG

PS: Dies hier ist mehr ein "Live beim rumprobieren" dabeisein, so sieht man aber wenigstens wieso ich was gemacht habe.

D
152 Beiträge seit 2013
vor 8 Jahren

Ich habe es mit einem @ vor dem root versucht, jedoch wieder 4 . Backslash nicht escapen in einem String?

Die Methode AddParameter ist überladen und hat nicht nur einen Parameter.

R
R3turnz Themenstarter:in
125 Beiträge seit 2016
vor 8 Jahren

Es hat jetzt endlich geklappt 😃
Code:


     using (var powershell = PowerShell.Create())
                {
                    powershell.AddCommand("New-PSDrive");
                    powershell.AddParameter("Name", name);
                    powershell.AddParameter("PSProvider", "FileSystem");
                    powershell.AddParameter("Root", root);
                    if (!string.IsNullOrEmpty(user) && !string.IsNullOrEmpty(password))
                    {
                        var secure = new SecureString();
                        foreach (char c in password)
                        {
                            secure.AppendChar(c);
                        }
                        PSCredential credential = new PSCredential(user, secure);
                        powershell.AddParameter("Credential",credential);
                    }
                    Collection<PSObject> powershellobjects =  powershell.Invoke();
                    
                }

16.835 Beiträge seit 2008
vor 8 Jahren

Sieht gut aus. Den Code so hab ich aber auch noch nirgens in den Beispiele gesehen.
Sieht man immer was neues, bei Powershell 😉