ShellExecute will nicht!



  • Hallo Leute,

    ich schaffe es einfach nicht ShellExecute zum laufen zu bekommen. Selbst Google und msdn konnten mir nicht weiterhelfen 😞
    Könnt ihr vielleicht mal bitte über den Code schauen, ich sehe den Fehler einfach nicht.

    #include <stdio.h>
    #include <windows.h>
    //#include <shellapi.h>
    //#include <conio.h> 
    //#include <stdlib.h> 
    
    void get_app_misstake(int miss);
    
    int main( int argc, char** argv ){
    
    	int i; //Laufvariable
    	int run_app_status; //Status von ShellExecute
    	char* app_path = "C:\\Miss.pdf\0"; //String auf auszuführende Datei
    	LPCWSTR exe_path = (LPCWSTR)"C:\\"; //LPCWSTR auf Ordner bzw. Datei
    
    	printf("=====Test-Programm=====\n");
    	printf("\n");
    
    	printf("Die Anzahl der uebergeben Kommandozeilenparameter: %d\n",argc);
    	printf("==========\n");
    
    	for(i=0;i<argc;i++){
    		printf("%03d: %s\n",i+1 , argv[i]);
    	}
    	printf("==========\n");
    	printf("%s\n", app_path);
    
    	//run_app_status = (int)ShellExecute( NULL, (LPCWSTR)"explore", (LPCWSTR)app_path, NULL, NULL, SW_NORMAL); //Fehler: ERROR_FILE_NOT_FOUND
    	//run_app_status = (int)ShellExecute( NULL, app_path, NULL, NULL, NULL, SW_NORMAL); //kompiliert nicht
    	//run_app_status = (int)ShellExecute( NULL, "open", "http://www.google.de", NULL, NULL, SW_SHOWDEFAULT); //kompiliert nicht
    	//run_app_status = (int)ShellExecute( NULL, NULL, (LPCWSTR)"http://www.google.de", NULL, NULL, SW_SHOWDEFAULT); //kompiliert nicht
    	//run_app_status = (int)ShellExecute( NULL, NULL, exe_path.c_str(), NULL, NULL, SW_NORMAL); //kompiliert nicht
    	run_app_status = (int)ShellExecute( NULL, NULL, exe_path, NULL, NULL, SW_NORMAL); // Fehler: ERROR_FILE_NOT_FOUND
    
    	if(run_app_status > 32)
    		printf("Programm wurde gestartet!\n");
    	else{
    		printf("Fehler!\n");
    		get_app_misstake( run_app_status);
    	}
    
    	getchar();
    
    	return 0;
    }
    
    void get_app_misstake(int miss){
    
    	switch(miss){
    
    		case ERROR_FILE_NOT_FOUND /* SE_ERR_FNF */ :
    			printf("Fehler: ERROR_FILE_NOT_FOUND\n");
    			break;
    
    		case ERROR_PATH_NOT_FOUND /* or SE_ERR_PNF */ :
    			printf("ERROR_PATH_NOT_FOUND\n");
    			break;
    
    		case ERROR_BAD_FORMAT :
    			printf("ERROR_BAD_FORMAT\n");
    			break;
    
    		case SE_ERR_ACCESSDENIED :
    			printf("SE_ERR_ACCESSDENIED\n");
    			break;
    
    		case SE_ERR_ASSOCINCOMPLETE :
    			printf("SE_ERR_ASSOCINCOMPLETE\n");
    			break;
    
    		case SE_ERR_DDEBUSY :
    			printf("SE_ERR_DDEBUSY \n");
    			break;
    
    		case SE_ERR_DDEFAIL :
    			printf("SE_ERR_DDEFAIL\n");
    			break;
    
    		case SE_ERR_DDETIMEOUT :
    			printf("SE_ERR_DDETIMEOUT\n");
    			break;
    
    		case SE_ERR_DLLNOTFOUND :
    			printf("SE_ERR_DLLNOTFOUND\n");
    			break;
    
    		case SE_ERR_NOASSOC :
    			printf("SE_ERR_NOASSOC\n");
    			break;
    
    		case SE_ERR_OOM :
    			printf("SE_ERR_OOM\n");
    			break;
    
    		case SE_ERR_SHARE :
    			printf("SE_ERR_SHARE\n");
    			break;
    
    		default :
    			printf("Fehler unbekannt!");
    	}
    
    }
    

    Ich habe es in einem Visual Studio 2010 CPP-Projekt.

    Vielen Dank
    Trible



  • Hi,

    du versuchst die Datei C:\ auszuführen. Kann nicht funktionieren.

    weil =

    LPCWSTR exe_path = (LPCWSTR)"C:\\";
    

    und exe_path versuchst du als Datei aufzurufen.
    ich würde mal

    char* app_path = "C:\\Miss.pdf\0";
    

    einsetzen anstelle von exe_path.

    ShellExecute(NULL, "open", app_path, NULL, NULL, SW_SHOWNORMAL)
    

    ist vom Aufbau korrekt aber:

    Du castest wie verrückt die Variabeln hin und her, überprüfe mal den Zeichensatz, der bei dir aktiv ist in den Projekteigenschaften. Unicode oder Multibyte.

    Gruß
    Ombre

    PS: Bei den versuchen die du getätigt hast, hast du einfach nur blind probiert aber nicht gelesen, was die MSDN sagt. Sonst hättest du nicht versucht (z.B.) als zweiten Parameter den Dateipfad zu übergeben ...
    und Google spuckt eigentlich auch genügend funktionierende Beispiele aus, die man nur anpassen bräuchte.



  • TribleTT schrieb:

    ich schaffe es einfach nicht ShellExecute zum laufen zu bekommen. Selbst Google und msdn konnten mir nicht weiterhelfen 😞
    Könnt ihr vielleicht mal bitte über den Code schauen, ich sehe den Fehler einfach nicht.

    Die Fehlermeldungen lassen in mir den Verdacht aufkommen, dass in den Linkereinstellungen die SHELL32.LIB fehlt.

    Wenn Du in MSDN bei "ShellExecute" nachguckst (http://msdn.microsoft.com/en-us/library/windows/desktop/bb762153.aspx), dann siehst Du, dass die Typen der Argumente als LPCTSTR angegeben sind. Du verwendest aber LPCWSTR - das ist etwas anderes.

    Das 'T' in LPCTSTR bedeutet, dass es zwei Funktionen gibt: die eine schluckt ANSI-Strings, die andere UNICODE-Strings. Je nach Projekteinstellungen wählt der Compiler eine der beiden Funktionen (ShellExecuteA oder ShellExecuteW) aus und belegt die Strings entsprechend.

    Du hast ein ANSI-Projekt (glaub mir einfach). Ein LPCTSTR wird somit zu einem LPCSTR gemacht, bzw. zu einem const char*. Du brauchst bei den Strings nichts Besonderes zu beachten und auch nicht hin- und herzucasten. Insbesondere wandelt ein Cast keine Strings um (von ANSI nach UNICODE oder umgekehrt).

    viele grüße
    ralph



  • Problem gelöst 🕶
    Danke für eure Hilfe, wäre nie von selbst auf den Fehler gekommen.

    Es lag daran, dass der Zeichensatz auf Unicode-Zeichensatz gestellt war. Wenn der Zeichensatz auf Multibyte gestellt ist, ist das Programm lauffähig.

    Was das mit dem Zeichensatz allerdings zu bedeuten hat, weiß ich nicht wirklich...
    Kennt vielleicht jemand Literatur die das einigermaßen gut erklärt?

    Hier noch das lauffähige Programm mit Kommentaren:

    #include <stdio.h> 
    #include <windows.h> 
    
    void get_app_misstake(int miss); 
    
    int main( int argc, char** argv ){ 
    
        int run_app_status; //Status von ShellExecute 
        char* app_path = "C:\\Miss.pdf"; //String auf auszuführende Datei 
    
    	/* Nicht nötig wenn Zeichensatz stimmt ;)
        LPCWSTR exe_path = (LPCWSTR)"C:\\Miss.pdf"; //LPCWSTR auf Ordner bzw. Datei 
    	LPCTSTR exe_path_2 = (LPCTSTR)"C:\\Miss.pdf"; //LPCWSTR auf Ordner bzw. Datei
    	*/
    
        printf("=====Test-Programm=====\n"); 
        printf("\n"); 
    
        printf("%s\n", app_path); 
    
    	/*
    
    	Diese Fehlermeldungen treten auf, wenn in den Projekteigenschaften als Zeichensatz Unicode eingestellt ist.
    
    	//run_app_status = (int)ShellExecute( NULL, "open", app_path, NULL, NULL, SW_NORMAL); // IntelliSense: Das Argument vom Typ ""const char*"" ist mit dem Paramenter vom Typ ""LPCWSTR"" inkompatibel.
    	//run_app_status = (int)ShellExecute( NULL, "open", "C:\\Miss.pdf", NULL, NULL, SW_NORMAL); // IntelliSense: Das Argument vom Typ ""const char*"" ist mit dem Paramenter vom Typ ""LPCWSTR"" inkompatibel.
    	//run_app_status = (int)ShellExecute( NULL, (LPCTSTR)"open", (LPCTSTR)"C:\\Miss.pdf", NULL, NULL, SW_NORMAL); // Fehler: ERROR_FILE_NOT_FOUND
        //run_app_status = (int)ShellExecute( NULL, NULL, exe_path, NULL, NULL, SW_NORMAL); // Fehler: ERROR_FILE_NOT_FOUND
    	//run_app_status = (int)ShellExecute( NULL, NULL, exe_path_2, NULL, NULL, SW_NORMAL); // Fehler: ERROR_FILE_NOT_FOUND
    	//run_app_status = (int)ShellExecute( NULL, "open", exe_path_2, NULL, NULL, SW_NORMAL); // Fehler: ERROR_FILE_NOT_FOUND
    
    	*/
    
    	/* Zeichensatz einstellen unter MS Visual Studio 2010:
    
    	Projekt-> <Projektname>-Eigenschaften-> Konfigurationseigenschaften-> Allgemein-> Zeichensatz
    
    	*/
    
    	run_app_status = (int)ShellExecute( NULL, "open", app_path, NULL, NULL, SW_NORMAL); //Um zu funktionieren muss der Zeichensatz auf Multicode eingestellt sein.
    
        if(run_app_status > 32) 
            printf("Programm wurde gestartet!\n"); 
        else{ 
            printf("Fehler!\n"); 
            get_app_misstake( run_app_status); 
        } 
    
        getchar(); 
    
        return 0; 
    } 
    
    void get_app_misstake(int miss){ 
    
        switch(miss){ 
    
            case ERROR_FILE_NOT_FOUND /* SE_ERR_FNF */ : 
                printf("Fehler: ERROR_FILE_NOT_FOUND\n"); 
                break; 
    
            case ERROR_PATH_NOT_FOUND /* or SE_ERR_PNF */ : 
                printf("ERROR_PATH_NOT_FOUND\n"); 
                break; 
    
            case ERROR_BAD_FORMAT : 
                printf("ERROR_BAD_FORMAT\n"); 
                break; 
    
            case SE_ERR_ACCESSDENIED : 
                printf("SE_ERR_ACCESSDENIED\n"); 
                break; 
    
            case SE_ERR_ASSOCINCOMPLETE : 
                printf("SE_ERR_ASSOCINCOMPLETE\n"); 
                break; 
    
            case SE_ERR_DDEBUSY : 
                printf("SE_ERR_DDEBUSY \n"); 
                break; 
    
            case SE_ERR_DDEFAIL : 
                printf("SE_ERR_DDEFAIL\n"); 
                break; 
    
            case SE_ERR_DDETIMEOUT : 
                printf("SE_ERR_DDETIMEOUT\n"); 
                break; 
    
            case SE_ERR_DLLNOTFOUND : 
                printf("SE_ERR_DLLNOTFOUND\n"); 
                break; 
    
            case SE_ERR_NOASSOC : 
                printf("SE_ERR_NOASSOC\n"); 
                break; 
    
            case SE_ERR_OOM : 
                printf("SE_ERR_OOM\n"); 
                break; 
    
            case SE_ERR_SHARE : 
                printf("SE_ERR_SHARE\n"); 
                break; 
    
            default : 
                printf("Fehler unbekannt!"); 
        } 
    
    }
    




  • TribleTT schrieb:

    char* app_path = "C:\\Miss.pdf\0"; //String auf auszuführende Datei
    

    Tu' mal die unötige '\0' da weg...

    // edit:

    Und dann mach'n ma mal halbwegs schönes C++ d'raus:

    /* Zeichensatz einstellen unter MS Visual Studio 2010: wurscht. */
    
    #include <string>
    #include <map>
    #include <iostream>
    
    #include <windows.h>
    
    #ifdef UNICODE
    	std::wostream &tcout = std::wcout;
    	typedef std::wstring tstring;
    #elif
    	std::ostream &tcout = std::cout;
    	typedef std::string tstring;
    #endif
    
    template< typename KEY, typename VALUE >
    class create_map
    {
    	private:
    		std::map< KEY, VALUE > map;
    
    	public:
    		create_map( KEY const &key, VALUE const &value) { map[ key ] = value; }
    		create_map< KEY, VALUE >& operator()( KEY const &key, VALUE const &value ) { map[ key ] = value; return *this; }
    		operator std::map< KEY, VALUE >() { return map; }
    };
    
    tstring get_shellex_error_msg( int const error_code )
    {
    	static std::map< int, tstring > const error_map = create_map< int, tstring >
    		( 0, TEXT( "The operating system is out of memory or resources." ) )
    		( ERROR_FILE_NOT_FOUND, TEXT( "The specified file was not found." ) )
    		( ERROR_PATH_NOT_FOUND, TEXT( "The specified path was not found." ) )
    		( ERROR_BAD_FORMAT, TEXT( "The .exe file is invalid (non-Win32 .exe or error in .exe image)." ) )
    		( SE_ERR_ACCESSDENIED, TEXT( "The operating system denied access to the specified file." ) )
    		( SE_ERR_ASSOCINCOMPLETE, TEXT( "The file name association is incomplete or invalid." ) )
    		( SE_ERR_DDEBUSY, TEXT( "The DDE transaction could not be completed because other DDE transactions were being processed." ) )
    		( SE_ERR_DDEFAIL, TEXT( "The DDE transaction failed." ) )
    		( SE_ERR_DDETIMEOUT, TEXT( "The DDE transaction could not be completed because the request timed out." ) )
    		( SE_ERR_DLLNOTFOUND, TEXT( "The specified DLL was not found." ) )
    		( SE_ERR_FNF, TEXT( "The specified file was not found." ) )
    		( SE_ERR_NOASSOC, TEXT( "There is no application associated with the given file name extension." ) )
    		( SE_ERR_OOM, TEXT( "There was not enough memory to complete the operation." ) )
    		( SE_ERR_PNF, TEXT( "The specified path was not found." ) )
    		( SE_ERR_SHARE, TEXT( "A sharing violation occurred." ) );
    
    	auto it = error_map.find( error_code );	
    	return ( it != error_map.end() ? it->second : TEXT( "An unknown error occured." ) );
    }
    
    int main()
    {
    	tcout << TEXT( "=====Test-Programm=====\n\n" );
    
    	LPCTSTR file = TEXT( "C:\\Miss.pdf" );
    	tcout << file << '\n';
    
    	int result = reinterpret_cast< int >(
    		ShellExecute( nullptr, TEXT( "open" ), file, nullptr, nullptr, SW_NORMAL ) );
    
    	if( result > 32 ) tcout << TEXT( "Programm wurde gestartet!\n" );
    	else tcout << get_shellex_error_msg( result ) << '\n';
    }
    

    // edith: 'n TEXT überseh'n


Anmelden zum Antworten