Shell mit aktueller Pfadangabe...


  • Mod

    Die Shell ist eine Applikationwie jede andere. Auch sie hat ein working directory. Die Funktionen dafür sind GetCurrentDirectory, SetCurrentDirectory.



  • @Martin Richter: Hab das so verstanden, dass er sich ne eigene Shell schreiben wollte und dann den Pfad zu seine Shell (eben seine Applikation) übergeben wollte...Naja wir werden es ja sehen :xmas2: .



  • Damit ich in einem bestimmten Verzeichnis arbeiten kann, muss ich erstmal dahinkommen, z.B. möchte ich in c:\test\datei.txt die Datei lesen. Die Shell wird hier in c:\ gestartet, also in der Promp steht c:\>> jetzt mit einem Befehl wie z.b cd in das verzeichnis wechseln.
    ICh möchte nur der Shell mit sagen in welchem Verzechnis sie gerade arbeiten soll, um z.b. dateien lesen,schreiben,.... so wie cmd

    Mein eigenes Verzeichnis bekomme ich mit folgender Funktion:

    string ApplicationDirectory()
    {
    	TCHAR szPathName[_MAX_PATH];
    	::GetModuleFileName(NULL, szPathName, _MAX_PATH);
    	LPTSTR pszFileName = _tcsrchr(szPathName, '\\') + 1;
    	*pszFileName = '\0'; 
    
    	return szPathName;
    }
    

  • Mod

    Dann verwende SetCurrentDirectory und Du kannst direkt mit fopen, die Datei öffnen.



  • Hab folgendes zusammengebastelt:

    #include <windows.h>
    #include <iostream>
    #include <string>
    #include <tchar.h>
    
    using namespace std;
    
    string ApplicationDirectory();
    
    //***Global***
    string Pfad = ApplicationDirectory();
    
    void prompt()
    {	
    	cout << Pfad << ">>";
    }
    
    string ApplicationDirectory()
    {
    	TCHAR szPathName[_MAX_PATH];
    	::GetModuleFileName(NULL, szPathName, _MAX_PATH);
    	LPTSTR pszFileName = _tcsrchr(szPathName, '\\') + 1;
    	*pszFileName = '\0'; 
    
    	return szPathName;
    }
    
    int main()
    {
    	string str;
    	do
    	{
    		prompt();
    		getline(cin, str);		
    
    		//Mit Befehl cd ... in ein anderes Verzechnis wechseln
    
    	}while(1);
    	return 0;
    }
    

    Anfangs wird in der Prompt der Start Pfad der Programms ausgegeben, dieser befindet sich in der Variable Pfad.
    Solbald ich den befehl cd VERZEICHNIS eingebe, wird VERZEICHNIS in Pfad gespeichert.

    Wie soll ich das mit SetCurrentDirectory machen so in etwa -> SetCurrentDirectory(VERZEICHNIS) ??
    Und wenn ich dann den Befehl dir eingebe wird nur das aktuelle Verzeichnis in dem das Programm gestartet wurde ausgegeben und nicht das geänderte.

    Bitte um Hilfe



  • Also ich will noch einmal fragen, wie kann ich die den meiner shell mitteilen das sie sich in einem anderen pfad befindet, ich weiß nicht wie man das mit SetCurrentDirectory() verwendet.
    Ich hoffe ihr versteht mich, also meine shell soll so funktionsweise wie cmd.exe, so dass ich in einem belibiegen Verzeichnis arbeiten kann.

    Bitte um Hilfe


  • Mod

    Ja! Deine Applikation befindet sich in diesem Verzeichnis, das GetCurrentDirectory angibt. Alle Dateioperationen die keinen Pfad haben oder einen relativen Pfad haben beziehen sich auf dieses directory. Mie Set setzen mit Get lesen.



  • Hab folgendes zusammengebastelt:

    #include <windows.h>
    #include <iostream>
    #include <string>
    #include <tchar.h>
    #include <sstream>
    #include <vector>
    
    using namespace std;
    
    string ApplicationDirectory();
    
    //***Global***
    string Pfad = ApplicationDirectory();
    
    string ApplicationDirectory()
    {
    	TCHAR szPathName[_MAX_PATH];
    	::GetModuleFileName(NULL, szPathName, _MAX_PATH);
    	LPTSTR pszFileName = _tcsrchr(szPathName, '\\') + 1;
    	*pszFileName = '\0'; 
    
    	return szPathName;
    }
    
    //Ausgabe Prompt
    void prompt()
    {	
    	cout << Pfad << ">>";
    }
    
    int main()
    {
    	string str;
    	do
    	{
    		//Setzt den aktuellen Pfad
    		SetCurrentDirectory(Pfad.c_str());
    		prompt();
    
    		getline(cin, str);	
    
    		istringstream cmdline (str);
    		string input;
    		vector<string> params;
    
    		string tmp;
    		while (cmdline >> tmp) 
    		{
    			params.push_back (tmp);
    		}
    
    		if(params.size() >= 2)
    		{
    			if(params[0] == "cd")
    			{
    				cout << "Wechsel zu -> " << params[1] << endl;
    				Pfad = params[1];
    			}
    		}
    		if(params.size() >= 1)
    		{
    			if(params[0] == "exit")
    				return 0;
    			if(params[0] == "dir")
    				system("dir");
    
    		}
    
    	}while(1);
    	return 0;
    }
    

    Es funktioniert jetzt, gibt es aber noch Verbesserungsvorschläge und wie kann ich prüfen ob der Pfad bei cd auch existiert

    Beispiel:

    *cd x:* // Fehler x existiert nicht!


  • Mod

    PathIsDirectory



  • Das mit der Überprüfung funktioniert jetzt 🙂
    Hab da ein nächstes Problem(e), wenn ich mich z.B. im Verzeichnis c:\ befinde wird auch in der Prompt c:\ angezeigt, doch wenn ich dann in ein weiteres Unterverzeichnis wechseln will wie z.B. Windows dann wird in der Prompt nur Windows angezeigt und nicht der volle Pfad: *c:\windows*
    Die Shell weiß das sie sich im verzeichnis c:\windows befindet, nur der Prompt muss ich dies noch irgendwie mitteilen. Ich dachte mir wenn ich das neue Unterverzeichnis dem string Pfad dazuaddiere, also pfad += params[1] dann würde der ganze Pfad stimmen doch das problem ist wenn ich in ein andere Partition wechseln will wie x: dann sehe der string so aus:

    Pfad = c:\windows\x:\... //es wird immer dann was dazu addiert.

    Wie würdet ihr das lösen??



  • Hier nochmal mein überarbeiteter Code:

    #include <windows.h>
    #include <iostream>
    #include <string>
    #include <tchar.h>
    #include <sstream>
    #include <vector>
    #include <Shlwapi.h>
    
    using namespace std;
    
    #pragma comment(lib, "Shlwapi.lib")
    
    string ApplicationDirectory();
    
    //***Global***
    string Pfad = ApplicationDirectory();
    
    string ApplicationDirectory()
    {
    	TCHAR szPathName[_MAX_PATH];
    	::GetModuleFileName(NULL, szPathName, _MAX_PATH);
    	LPTSTR pszFileName = _tcsrchr(szPathName, '\\') + 1;
    	*pszFileName = '\0'; 
    
    	return szPathName;
    }
    
    int checkDir(string str)
    {
    	if (PathIsDirectory(str.c_str()))
    		return 1;
    	else
    		return 0;
    }
    
    //Ausgabe Prompt
    void prompt()
    {	
    	cout << Pfad << ">>";
    }
    
    int main()
    {
    	string str;
    	do
    	{
    		//Setzt den aktuellen Pfad
    		SetCurrentDirectory(Pfad.c_str());
    		prompt();
    
    		getline(cin, str);	
    
    		istringstream cmdline (str);
    		string input;
    		vector<string> params;
    
    		string tmp;
    		while (cmdline >> tmp) 
    		{
    			params.push_back (tmp);
    		}
    
    		if(params.size() >= 2)
    		{
    			if(params[0] == "cd")
    			{				
    				//Pfad = params[1];
    				if(checkDir(params[1]) == 1)
    				{
    					Pfad = params[1];
    				}
    				else
    					cout << "Verzeichnis '" << params[1] << "' nicht gefunden" << endl << endl;
    
    			}
    		}
    		if(params.size() >= 1)
    		{
    			if(params[0] == "exit")
    				return 0;
    			if(params[0] == "dir")
    				system("dir");
    
    		}
    
    	}while(1);
    	return 0;
    }
    

    Ich hoffe Ihr könnt mir helfen, das Programm startet dort wo es kopiert wurde z.B. *F:\test* jetzt möchte ich in nach *c:* wechseln, gebe hierfür *cd c:* ein. In der Prompt steht jetzt c:\>> anschließend möchte ich in das Windows verzeihnis wechseln und gebe hierfür cd windows ein, jetzt steht in der Prompt windows>> doch wie kann man den ganzen Pfad ausgeben, hier c:\windows>>

    Bitte um Hilfe!



  • GetCurrentDirectory!?
    GetFullPathName !?



  • Vielen Dank 🙂
    Noch ein kurze Frage, wie kann man das folgende verbessern damit das feld keine feste größe hat, damit es zu keinem Bufferoverflow kommt.

    char app_name[300]; 
    GetCurrentDirectory(300, LPWSTR(app_name)); // aktuelles Verzeichnis holen...
    


  • Doku lesen

    To determine the required buffer size, set this parameter to NULL and the nBufferLength parameter to 0.

    und dann:

    DWORD dwReqSize = GetCurrentDirectory(0, NULL);
    TCHAR szCurDir = new TCHAR[dwReqSize+1];
    GetCurrentDirectory(dwReqSize+1, szCurDir);
    // ....
    delete [] szCurDir;
    

    PS: Warum castest Du ein "char" nach "LPWSTR"????? Das geht auf jeden Fall schief!



  • Hab mit deinem Beispiel 3 Fehler:

    error C2440: 'Initialisierung': 'TCHAR *' kann nicht in 'TCHAR' konvertiert werden
            Es gibt keinen Kontext, in dem diese Konvertierung möglich ist
    
    error C2664: 'GetCurrentDirectoryA': Konvertierung des Parameters 2 von 'TCHAR' in 'LPSTR' nicht möglich
    
    error C2541: 'delete': Objekte, die keine Zeiger sind, können nicht gelöscht werden
    


  • Sollte natürlich

    TCHAR *szCurDir = new TCHAR[dwReqSize+1];
    

    heissen...



  • Vielen Dank 🙂


Anmelden zum Antworten