Laufwerksbuchstaben vom USB-Stick



  • Hallo Community,

    ich bin gerade dabei mein in Batch getüfteltes Tool in C++ zu schreiben. Der Hintergrund ist der, das ein USB-Stick vorhanden ist, der sämtliche Treiber, Updates, Benchmarks und Systemverbesserungen enthält und das Tool diese Programme/Änderungen über ein Menü aufrufbar macht.
    Jetzt stellt sich mir nur die Frage, wie ich an den Laufwerksbuchstaben des Sticks (der ja bei jedem PC variabel sein kann) kommen kann. Es gibt bestimmt irgend eine Möglichkeit z.B. auszulesen, von wo, das Programm gerade geöffnet worden ist, und dass ich diesen Pfad dann als Variable speichern kann.

    Des weiteren habe ich es schon geschafft sämtliche Programme über System("Beispiel.exe"); zu starten. Jedoch bleibt das Tool solange stehen, bis das gestartete Programm wieder beendet wurde. In irgend einer Form ist vermutlich eine nicht warten Funktion enthalten.

    Nach ausführlichem Suchen im Netz bin ich nicht wirklich fündig geworden. Hier sind bestimmt einige Gurus am Start, die mir hoffentlich helfen können:).

    EDIT: Das oben gesrichtene habe ich bereits durch System("Start beispiel.exe"); schon selbst hinbekommen - hier auch meine Rückinfo - und Danke trotzdem :)!

    Grüße
    LK



  • Hallo,
    ich weiß ja nicht ob dir das hilft, aber es gibt bei MSDN folgendes:

    http://msdn.microsoft.com/de-de/library/windows/desktop/aa364972%28v=vs.85%29.aspx

    GetLogicalDrives nennt sich das ganze.

    Return value

    If the function succeeds, the return value is a bitmask representing the currently available disk drives. Bit position 0 (the least-significant bit) is drive A, bit position 1 is drive B, bit position 2 is drive C, and so on.

    Der Rückgabewert sollte dir also den Laufwerkbuchstaben liefern, wenn ich das richtig verstanden habe.

    Dann gibts noch GetDriveType (http://msdn.microsoft.com/en-us/library/aa364939(VS.85).aspx)
    könnte dir eventuell auch dabei helfen um zum Beispiel zu erkennen ob es
    sich überhaupt um einen Stick handelt.

    Ich hoffe ich konnte helfen.

    Gruß

    Cyax



  • Puh hab keinen Plan wie ich an den Rückgabewert komme der beschrieben wird.

    Bin noch nicht so erfahren, wie ich hier ne Syntax daraus schreiben kann.

    Grüße
    LK



  • void getUSBdrives( ArrayOfStrings *result )
    {
    	result->clear();
    #if defined( _Windows )
    	DWORD	driveMap = GetLogicalDrives();
    	char	path[] = "A:\\";
    	while( driveMap )
    	{
    		if( driveMap & 1 )
    		{
    			UINT type = GetDriveType( path );
    			if( type == DRIVE_REMOVABLE )                       // <---- korrektur
    			{
    				result->addElement( path );
    			}
    		}
    		driveMap >>= 1;
    		++(*path);
    	}
    #elif defined( __MACH__ )
        struct statfs   *fsInfo;
        int				fsCount = getmntinfo( &fsInfo, MNT_NOWAIT );
        for( int i=0; i<fsCount; i++ )
        {
            if( !strcmp( fsInfo[i].f_fstypename, "msdos" ) )
            {
    			result->addElement( fsInfo[i].f_mntonname );
            }
        }
    
    #endif
    }
    

    ArrayOIfStrings entspricht std::vectorstd::string mußt halt selber anpassen.

    mfg Martin



  • Ach du Schande 😕 . OK - darf mich offensichtlich noch einmal ganz anders dahinterklemmen. Versteh bei deiner Ausführung fast nur Bahnhof. Jetzt weiß ich vermutlich warum die Leute das Lehrbuch vom Jürgen Wolf (Grundkurs C++) so in den Grund und Boden reden...

    Erstmal vielen vielen Dank für deine Ausführung 👍. Hab aktuell keinen Plan wie ich das ganze implementieren kann.
    Gibts noch eine andere Empfehlung für ein vernünfiges Lehrbuch?

    Grüße
    LK



  • LKrieger schrieb:

    Ach du Schande 😕 . OK - darf mich offensichtlich noch einmal ganz anders dahinterklemmen. Versteh bei deiner Ausführung fast nur Bahnhof. Jetzt weiß ich vermutlich warum die Leute das Lehrbuch vom Jürgen Wolf (Grundkurs C++) so in den Grund und Boden reden...

    Erstmal vielen vielen Dank für deine Ausführung 👍. Hab aktuell keinen Plan wie ich das ganze implementieren kann.
    Gibts noch eine andere Empfehlung für ein vernünfiges Lehrbuch?

    Grüße
    LK

    Ich weiß jetzt natürlich nicht, warum Du nur Bahnhof verstehst. Möglicherweise solltest Du in Deinem Lehrbuch die Kapitel über bitweise Operatoren und die Shiftoperatoren lesen.

    Die Zeilen 21 bis 30 sind nur für Mac OS X. Die benötigst Du nicht.

    Die Zeile 5 liefert mir eine Bitmaske für die vorhanden Laufwerke. Das niederwertigste Bit steht für Laufwerk A:, das nächstshöhere für B: usw.

    Zeile 6 definiert ein char array mit dem Wurzelverzeichnis eines Laufwerks. Da ich mit A: anfange, ist es auch gleich mit dessen Pfad initialisert.

    Die Schleife ab Zeile 7 bearbeitet nun alle Laufwerke.

    Zeile 9 prüft, ob das niederwertigste Bit im Bitfeld gesetzt ist. (Im ersten Durchlauf steht das für A:)
    Wenn ja, wird die Eigenschaft des Laufwerks ermittelt (Zeile 11)
    Wenn dieses ein Wechselmedium ist (Zeile 12) wird der Pfad der Ergebnissliste hinzugefügt (Zeile 14) (Wenn Du std::vectorstd::string nimmst, heißt die Funktion zum Hinzufügen push_back.)

    Zeile 17 schiebt nun alle Bits des Bitfeldes um ein Bit nach rechts. Das höchstwertige Bit wird mit 0 aufgefüllt, die Information zum Laufwerk A: entfällt. Da das niederwertigste Bit des Bitfeldes nun für das Laufwerk B: steht, muß dann natürlich auch der Pfad angepasst werden, was in Zeile 18 passiert, indem einfach der Laufwerksbuchstabe um 1 erhöht wird A -> B -> C etc.

    Wenn alle Laufwerke bearbeitet wurden, steht in driveMap 0 und die Schleife terminiert.

    mfg Martin



  • Das liefert dir Accessoires "nur" eine Liste alles USB Laufwerke. Ich hatte es so verstanden, dass der TE den Pfad des Laufwerks wissen will von dem das Programm aus gestartet wurde.
    Gibt's dafür überhaupt ne Funktion?



  • Scheiß Handy Tastatur. Das liefert dir aber nur sollte das da oben heißen

    Als Lehrbuch würde ich den Primer empfehlen, arbeite selber damit. Da steht echt alles drinnen.



  • unsure schrieb:

    Das liefert dir Accessoires "nur" eine Liste alles USB Laufwerke. Ich hatte es so verstanden, dass der TE den Pfad des Laufwerks wissen will von dem das Programm aus gestartet wurde.
    Gibt's dafür überhaupt ne Funktion?

    Gibt es:

    http://msdn.microsoft.com/en-us/library/windows/desktop/ms683197(v=vs.85).aspx

    mfg Martin



  • Cool. Danke!



  • @LKrieger
    Vergiss den Laufwerksbuchstaben des Sticks!
    Hol dir einfach den Filenamen (inklusive Pfad) des aktuellen Programms: GetModuleFileName
    Dann schneidest du den Filenamen-Teil weg, und schwupps, hast du das gesuchte Verzeichnis.
    Funktioniert dann auch wenn dein Programm in einem Unterverzeichnis liegt, doch nicht auf einem USB Stick sondern auf der HDD liegt, es mehrere USB Sticks gibt etc.



  • Ich weiß jetzt natürlich nicht, warum Du nur Bahnhof verstehst. Möglicherweise solltest Du in Deinem Lehrbuch die Kapitel über bitweise Operatoren und die Shiftoperatoren lesen.

    Die Zeilen 21 bis 30 sind nur für Mac OS X. Die benötigst Du nicht.

    Die Zeile 5 liefert mir eine Bitmaske für die vorhanden Laufwerke. Das niederwertigste Bit steht für Laufwerk A:, das nächstshöhere für B: usw.

    Zeile 6 definiert ein char array mit dem Wurzelverzeichnis eines Laufwerks. Da ich mit A: anfange, ist es auch gleich mit dessen Pfad initialisert.

    Die Schleife ab Zeile 7 bearbeitet nun alle Laufwerke.

    Zeile 9 prüft, ob das niederwertigste Bit im Bitfeld gesetzt ist. (Im ersten Durchlauf steht das für A:)
    Wenn ja, wird die Eigenschaft des Laufwerks ermittelt (Zeile 11)
    Wenn dieses ein Wechselmedium ist (Zeile 12) wird der Pfad der Ergebnissliste hinzugefügt (Zeile 14) (Wenn Du std::vectorstd::string nimmst, heißt die Funktion zum Hinzufügen push_back.)

    Zeile 17 schiebt nun alle Bits des Bitfeldes um ein Bit nach rechts. Das höchstwertige Bit wird mit 0 aufgefüllt, die Information zum Laufwerk A: entfällt. Da das niederwertigste Bit des Bitfeldes nun für das Laufwerk B: steht, muß dann natürlich auch der Pfad angepasst werden, was in Zeile 18 passiert, indem einfach der Laufwerksbuchstabe um 1 erhöht wird A -> B -> C etc.

    Wenn alle Laufwerke bearbeitet wurden, steht in driveMap 0 und die Schleife terminiert.

    mfg Martin

    Hmm ja da gehts wohl schon an. Shiftoperatoren und bitweise Operatoren findet man in meinem Buch vergebens. Bin das gerade mal am googeln.

    @hustbaer:
    Wie kann ich dann sowas implementieren? Ich kannte z.b. Dword ebenfalls nicht. Im Netz hab ich jetzt gelesen das es ein typdef unsigned long ist welcher im Header windows.h definiert ist (steht auch kein Wort in meinem Buch). Wenn ich das allerdings richtig verstehe benötige ich nur:

    DWORD WINAPI GetModuleFileName(
      _Out_     LPTSTR lpFilename,
    );
    

    Das ganze müsste jetzt irgendwie in einer Variablen string gepackt werden, und wie du sagst, der Name und Restpfad bis auf den Laufwerksbuchstaben gekürzt werden... - wie.



  • LKrieger schrieb:

    Hmm ja da gehts wohl schon an. Shiftoperatoren und bitweise Operatoren findet man in meinem Buch vergebens. Bin das gerade mal am googeln.

    Wenn das so ist, ist Dein Buch ein Fall für die Altpapierverwertung.

    LKrieger schrieb:

    @hustbaer:
    Wie kann ich dann sowas implementieren? Ich kannte z.b. Dword ebenfalls nicht. Im Netz hab ich jetzt gelesen das es ein typdef unsigned long ist welcher im Header windows.h definiert ist (steht auch kein Wort in meinem Buch). Wenn ich das allerdings richtig verstehe benötige ich nur:

    DWORD WINAPI GetModuleFileName(
      _Out_     LPTSTR lpFilename,
    );
    

    Das ganze müsste jetzt irgendwie in einer Variablen string gepackt werden, und wie du sagst, der Name und Restpfad bis auf den Laufwerksbuchstaben gekürzt werden... - wie.

    Das ist Windowsspezifisch. Dafür braucht Du ein Buch über die Windowsprogrammierung.

    Mal ein ungetesteter Vorschlag:

    std::string getMyPath()
    {
        char fileName[10240];
    
        GetModuleFileName( NULL, fileName, 10240 );
        char *slash = strrchr( fileName, '\\' );
        if( slash )
            *slash = 0;
    
        return std::string( fileName );
    }
    

    Die Funktion prüft jetzt nicht den Rückgabewert von GetModuleFileName. Die Wahrschienlichkeit, daß der Pfad länger als 10 KB ist, dürfte aber gegen 0 tendieren.

    mfg Martin



  • mgaeckler schrieb:

    Das ist Windowsspezifisch. Dafür braucht Du ein Buch über die Windowsprogrammierung.

    Oder einfach die MSDN Webseite.

    Und ich würde PathRemoveFileSpec statt strrchr verwenden. Dann kommt das ganze auch mit "/" klar (die unter Windows auch als Pfad-Trennzeichen erlaubt sind).
    EDIT: Lol. OK. Doch nicht. Laut Kommentaren auf der MSDN Seite kann die Funktion gerade *nicht* mit Forward-Slashes umgehen. Peinlich.



  • Hmm hier kreidet mein Compiler folgendes an:

    Fehler 1 error C2664: 'DWORD GetModuleFileNameW(HMODULE,LPWSTR,DWORD)' : Konvertierung von Argument 2 von 'char [10240]' in 'LPWSTR' nicht möglich

    Fehler 2 IntelliSense: Das Argument vom Typ ""char *"" ist mit dem Parameter vom Typ ""LPWSTR"" inkompatibel.

    @hustbaer: peinlich - alles ok, bei mir ists viel schlimmer...

    Grüße
    LK



  • LKrieger schrieb:

    Hmm hier kreidet mein Compiler folgendes an:

    Fehler 1 error C2664: 'DWORD GetModuleFileNameW(HMODULE,LPWSTR,DWORD)' : Konvertierung von Argument 2 von 'char [10240]' in 'LPWSTR' nicht möglich

    Fehler 2 IntelliSense: Das Argument vom Typ ""char *"" ist mit dem Parameter vom Typ ""LPWSTR"" inkompatibel.

    Grüße
    LK

    Dann hast Du wohl UNICODE aktiviert. Dann so:

    std::string getMyPath()
    {
        char fileName[10240];
    
        GetModuleFileNameA( NULL, fileName, 10240 );
        char *slash = strrchr( fileName, '\\' );
        if( slash )
            *slash = 0;
    
        return std::string( fileName );
    }
    

    mfg Martin



  • Nein, dann bitte so:

    std::wstring getMyPath()
    {
        wchar_t fileName[10240];
        GetModuleFileName(NULL, fileName, 10240);
        PathRemoveFileSpec(fileName);
        return fileName;
    }
    


  • OK der Code von dir Martin gibt mir immer seltsame Zahlen wie 0E124000 aus und diese immer wieder untschiedlich.

    Bei deinem Code Hustbaer bekomme ich vom Compiler wieder zwei Fehler:

    Fehler 2 error LNK1120: 1 nicht aufgel÷ste Externe

    Fehler 1 error LNK2019: Verweis auf nicht aufgel÷stes externes Symbol "__imp__PathRemoveFileSpecW@4" in Funktion ""class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > __cdecl getMyPath(void)" (?getMyPath@@YA?AV?basic_string@_WU?basic\_string@\_WU?char_traits@_W@std@@V?$allocator@_W@2@@std@@XZ)".

    Grüße
    LK



  • Dir fehlt dann wohl die Shlwapi.lib in deinem Projekt. Das kann man auch leicht in der Hilfe zu der Funktion nachlesen.
    http://msdn.microsoft.com/de-de/library/windows/desktop/bb773748%28v=vs.85%29.aspx



  • Und LNK**** Fehler kommen vom Linker, nicht vom Compiler 😉
    Und man kann die auch googeln:
    https://www.google.com/search?q=LNK1120
    https://www.google.com/search?q=LNK2019


Log in to reply