Problem mit dem Auslesen des Programmfolders auf dem System...



  • Hallo Leute,

    ich hab mal wieder ein dämliches Problem, das sicher total einfach zu lösen ist und nur mir Probleme macht...
    Mein Script funktioniert, nur hab ich leider das Problem, dass es auf ner englischen Maschine nicht laufen würde, weil dort der Pfad zum IE nicht laufen würde ("C:\Programme" > "C:\Program Files", etc.).

    Also hab ich mich auf die Suche nach einer Lösung gemacht und bin auf folgendes gekommen:

    SHGetSpecialFolderPath(NULL, progPath, CSIDL_PROGRAM_FILES, FALSE)
    

    Die Funktion wollte ich gerne bei "case WM_PAINT:" mit reinschreiben (noch lieber hätte ichs oben bei den CHAR-Deklarationen einfach dazugeschrieben, so dass ich genauso wie auf die anderen CHARs damit arbeiten könnte, aber das geht ja glaube ich nicht, weil da die Funktion nicht abgearbeitet wird, oder?)

    Finds irgendwie blöd es an der WM_PAINT-Stelle zu machen... dann ruft er das ja mehrfach wiederholt auf, der Programm-Pfad ändert sich ja aber nicht... oder?

    So oder so:
    Leider klappt das Ganze nicht. Ich bekomme immer die Fehlermeldung:

    `SHGetSpecialFolderPath' was not declared in this scope
    

    und

    warning: unused variable 'SHGetSpecialFolderPath
    

    (Variable? Sollte doch ne Funktion sein...)

    Muss ich noch was Zusätzliches einbinden? Ich entwickle für WindowsXP oder neuere Systeme, hab eigentlich nur gelesen, dass man min. Windows2000 braucht für die Funktion. Sie sollte also eigentlich bereits eingebunden sein, oder nicht?

    Ich möchte etwas relativ Einfaches machen:
    1.) Lese "C:[Programmpfad]" aus. (also z.B: "C:\Programme" oder "C:\Program Files").
    2.) Verbinde den Output zu einem CHAR zusammen mit "Internet Explorer\\iexplore.exe", so dass ich diesen als Aufrufparameter für meinen Prozessaufruf (Zeile 221) verwenden kann.

    Der Aufruf und die Prozessabarbeitung etc funktioniert wie gedacht. Schreibe ich nämlich einfach "C:\\Programme\\Internet Explorer\\iexplore.exe" als cmd_ie läuft es wunderbar. Es geht also nur um das Auslesen des Pfads und die Verknüpfung zu einem verwendbaren CHAR.
    Für jemanden der schon ganz gut in C++ ist, ist das sicher ziemlich einfach, ich hab aber eindeutig Probleme damit.

    Hier jetzt der Code meines Programms.

    #include <windows.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include "resources.h"
    #include <dos.h>
    #include <conio.h>
    #include <process.h>
    #include <vector>
    #include "Psapi.h"
    #include <cstdio>
    #include <tlhelp32.h>
    #include <tchar.h>
    #include <iostream>
    #include <shlobj.h>
    
    using namespace std;
    
    HINSTANCE hInst;
    LRESULT CALLBACK WindProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
    
    int deskBreite = GetSystemMetrics(SM_CXSCREEN);
    int deskHoehe = GetSystemMetrics(SM_CYSCREEN);
    int winBreite = 410;
    int winHoehe = 100;
    HBRUSH hBrush = CreateSolidBrush(RGB(0,70,135));
    
    // Warnings //
    CHAR *warning_ie = "Please close the programm \"InternetExplorer\" before you start this application!";
    CHAR *warning_ie_window = "Please close InternetExplorer";
    
    // OpenCommands //
    CHAR *win_name = "The Programm is starting...";
    CHAR *cmd_stop = "c:\\xampplite\\xampp_stop.exe";
    CHAR *cmd_start = "c:\\xampplite\\xampp_start.exe";
    CHAR *cmd_ieadd = "open http:\\\\localhost:5912\\index.php";
    CHAR *cmd_ie_small = "\\Internet Explorer\\iexplore.exe";
    CHAR *cmd_ie;
    CHAR progPath;
    // Lese Programmfolder waehrend WM_PAINT aus //
    
    // Integer defining how long to wait (ie. for process at max in msec)
    int waitTime = 50000;
    int waitTime2 = 5000;
    int waitTime3 = 2000;
    int minTime = 200;
    int abbruch = 0;
    
    int xpos = (int) ((deskBreite/2) - (winBreite/2));
    int ypos = (int) ((deskHoehe/2) - (winHoehe/2));
    
    INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                       LPSTR lpCmdLine, int nCmdShow)
    {
    
        WNDCLASSEX  WndCls;
        static char szAppName[] = "MyServer";
        MSG         Msg;
    	HICON hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(101));
    
    	hInst       		 = hInstance;
        WndCls.cbSize        = sizeof(WndCls);
        WndCls.style         = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
        WndCls.lpfnWndProc   = WindProcedure;
        WndCls.cbClsExtra    = 0;
        WndCls.cbWndExtra    = 0;
        WndCls.hInstance     = hInst;
        WndCls.hIcon         = hIcon;
        WndCls.hCursor       = LoadCursor(hInstance, IDC_ARROW);
        WndCls.hbrBackground = hBrush;
        WndCls.lpszMenuName  = NULL;
        WndCls.lpszClassName = szAppName;
        WndCls.hIconSm       = hIcon;
        RegisterClassEx(&WndCls);
    
        CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
                              szAppName,
                              "MyServer...",
                              WS_POPUP|WS_VISIBLE,
                              xpos,
                              ypos,
                              winBreite,
                              winHoehe,
                              NULL,
                              NULL,
                              hInstance,
                              NULL);
    
        while( GetMessage(&Msg, NULL, 0, 0) )
        {
            TranslateMessage(&Msg);
            DispatchMessage( &Msg);
        }
    
        return static_cast<int>(Msg.wParam);
    }
    
    LRESULT CALLBACK WindProcedure(HWND hWnd, UINT Msg,
    			   WPARAM wParam, LPARAM lParam)
    {
        HDC hDC, MemDCBmpImg;
        PAINTSTRUCT Ps;
        HBITMAP bmpImg;
    
        switch(Msg){
    		case WM_DESTROY:
    			STARTUPINFO si10;
    			PROCESS_INFORMATION pi10;
    
    			memset(&si10, 0, sizeof(si10));
    		    memset(&pi10, 0, sizeof(pi10));
    		    si10.cb = sizeof(si10);
    
    			printf("Trying to create process xampp_stop!");
    			if(!CreateProcess(cmd_stop, "", 0, 0, FALSE, CREATE_NO_WINDOW, 0, 0, &si10, &pi10)){
    				printf("Process xampp_stop could not be created!");
    				return 0;
    			} else {
    				printf("Process xampp_stop was created!");
    			}
    			CloseHandle( pi10.hProcess );
    			CloseHandle( pi10.hThread );
    			PostQuitMessage(WM_QUIT);
    		break;
    		case WM_PAINT:
    			hDC = BeginPaint(hWnd, &Ps);
    			SHGetSpecialFolderPath(NULL, progPath, CSIDL_PROGRAM_FILES, FALSE);
    			cmd_ie = progPath + cmd_ie_small;
    
    			// Load the bitmap from the resource
    			bmpImg = LoadBitmap(hInst, MAKEINTRESOURCE(102));
    			// Create a memory device compatible with the above DC variable
    			MemDCBmpImg = CreateCompatibleDC(hDC);
    				 // Select the new bitmap
    				 SelectObject(MemDCBmpImg, bmpImg);
    
    			// Copy the bits from the memory DC into the current dc
    			BitBlt(hDC, 0, 0, 400, 94, MemDCBmpImg, 0, 0, SRCCOPY);
    
    			// Restore the old bitmap
    			DeleteDC(MemDCBmpImg);
    			DeleteObject(bmpImg);
    			EndPaint(hWnd, &Ps);
    
    			/* Is IE started? Then tell user to close it first and stop! */
    		    PROCESSENTRY32 entry;
    		    entry.dwSize = sizeof( PROCESSENTRY32 );
        		HANDLE snapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0);
    
    		    if (snapshot != INVALID_HANDLE_VALUE && Process32First( snapshot, &entry ) == TRUE ) {
    		    	if (stricmp( entry.szExeFile, "iexplore.exe" ) == 0 ) {
    		    		CloseHandle( snapshot );
    					exit(MessageBox(NULL, warning_ie, warning_ie_window, MB_ICONWARNING));
    		    	}
    		        while ( Process32Next( snapshot, &entry ) == TRUE ) {
    					if ( stricmp( entry.szExeFile, "iexplore.exe" ) == 0 ) {
    						CloseHandle( snapshot );
    						exit(MessageBox(NULL, warning_ie, warning_ie_window, MB_ICONWARNING));
    					}
    		        }
            	}
    
    			if(snapshot == INVALID_HANDLE_VALUE){
    				CloseHandle( snapshot );
    			}
    
    			// Handles for process and processinfos
    			STARTUPINFO si;
    			PROCESS_INFORMATION pi;
    
    			memset(&si, 0, sizeof(si));
    			memset(&pi, 0, sizeof(pi));
    			si.cb = sizeof(si);
    
    			STARTUPINFO si2;
    			PROCESS_INFORMATION pi2;
    			memset(&si2, 0, sizeof(si2));
    			memset(&pi2, 0, sizeof(pi2));
    			si2.cb = sizeof(si2);
    
    			STARTUPINFO si3;
    			PROCESS_INFORMATION pi3;
    
    			memset(&si3, 0, sizeof(si3));
    			memset(&pi3, 0, sizeof(pi3));
    			si3.cb = sizeof(si3);
    
    			STARTUPINFO si4;
    			PROCESS_INFORMATION pi4;
    
    			memset(&si4, 0, sizeof(si4));
    			memset(&pi4, 0, sizeof(pi4));
    			si4.cb = sizeof(si4);
    
    			printf("Trying to create process xampp_stop!");
    			if(CreateProcess(cmd_stop, "", 0, 0, FALSE, CREATE_NO_WINDOW, 0, 0, &si, &pi) == FALSE){
    				printf("Process xampp_stop could not be created!");
    				return 0;
    			} else {
    				printf("Process xampp_stop was created!");
    			}
    			WaitForSingleObject(pi.hProcess, waitTime);
    			CloseHandle( pi.hProcess );
    			CloseHandle( pi.hThread );
    
    			printf("Trying to create process xampp_start!");
    			if(CreateProcess(cmd_start, "", 0, 0, FALSE, CREATE_NO_WINDOW, 0, 0, &si2, &pi2) == FALSE){
    				printf("Process xampp_start could not be created!");
    				return 0;
    			} else {
    				printf("Process xampp_start was created!");
    			}
    
    			WaitForSingleObject(pi2.hProcess, waitTime);
    			CloseHandle( pi2.hProcess );
    			CloseHandle( pi2.hThread );
    
    			// Wait a little!
    			// Sleep(waitTime2);
    
    			printf("Trying to create process ie!");
    			if(CreateProcess(TEXT(cmd_ie), cmd_ieadd, 0, 0, FALSE, 0, 0, 0, &si3, &pi3) == FALSE){
    				printf("Process ie could not be created!");
    				return 0;
    			} else {
    				printf("IE-Process was created!");
    			}
    
    			// Find Presenter-Window
    			printf("Win-Name: ");
    			printf(win_name);
    			HWND this_hWnd = FindWindow(NULL, win_name);
    
    			// Minimiere die Anzeige
    			ShowWindow(this_hWnd, SW_SHOWMINIMIZED);
    			SetWindowText(this_hWnd, "MyServer");
    
    			WaitForSingleObject(pi3.hProcess, INFINITE);
    			CloseHandle( pi3.hProcess );
    			CloseHandle( pi3.hThread );
    			printf("IE has been stopped!");
    
    			printf("Trying to create process xampp_stop!");
    			if(!CreateProcess(cmd_stop, "", 0, 0, FALSE, CREATE_NO_WINDOW, 0, 0, &si4, &pi4)){
    				printf("Process xampp_stop could not be created!");
    				return 0;
    			} else {
    				printf("Process xampp_stop was created!");
    			}
    			WaitForSingleObject(pi4.hProcess, waitTime);
    			CloseHandle( pi4.hProcess );
    			CloseHandle( pi4.hThread );
    
    			// xampp should be offline, now close the application
    			exit(0);
    		break;
    		default: return DefWindowProc(hWnd, Msg, wParam, lParam);
    	}
        return 0;
    }
    

    Kann mir vielleicht jemanden einen Tipp geben?

    Viele Grüße und vielen Dank im Voraus
    *Fuchur*



  • Hallo Leute,

    hab meinen Fehler selbst gefunden.
    Dieser Codeschnippsel zeigt welche Funktion man benutzen muss und was man dafür einbinden sollte. Verwendet man die hier aufgeführte "SHGetSpecialFolderPath" funzt es nicht. Vielleicht ist diese erst ab Vista verfügbar.
    Deshalb lieber: "SHGetFolderPath".

    Vorsicht, ab Vista ist die aber nicht mehr vorhanden, deshalb muss man Sie manuell einbinden. Dafür folgendes einbinden:

    #include <shlobj.h>
    

    Und jetzt wie man drangehen sollte. Chars zusammenführen ist auch so ne Sache gewesen. strcat() hilft hier aber weiter.
    Mit diesen beiden Infos konnte ich meine Probleme lösen. Ich hoffe es hilft jemand anderem ebenfalls mal weiter.

    ...
    // GET C:\Programm-Folder AND attach Internet Explorer to it.
    CHAR *cmd_ie_small;
    cmd_ie_small = "\\Internet Explorer\\iexplore.exe";
    
    CHAR szPath[MAX_PATH];
    SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, 0, szPath);
    strcat(szPath, cmd_ie_small);
    
    if(CreateProcess(TEXT(szPath), cmd_ieadd, 0, 0, FALSE, 0, 0, 0, &si3, &pi3) == FALSE){
    ...
    

    Um es nochmal zu sagen: Ich bin selbst nicht gerade fortgeschritten mit C++... da gibt es also sicher eleganterer Lösungen. Funktioniert hats bei mir aber trotzdem.

    Auch wenn ichs jetzt selbst herausgefunden habe: Vielen Dank nichtsdestotrotz...
    Hoffnung hilft ja bekanntlich auch 😉

    Viele Grüße
    *Fuchur*



  • Die Funktion wollte ich gerne bei "case WM_PAINT:" mit reinschreiben (noch lieber hätte ichs oben bei den CHAR-Deklarationen einfach dazu geschrieben, so dass ich genauso wie auf die anderen CHARs damit arbeiten könnte, aber das geht ja glaube ich nicht, weil da die Funktion nicht abgearbeitet wird, oder?)

    Von WM_CREATE hast du aber schon gehört oder? Und den Unterschied zwischen einen Funktionsaufruf und einer Variablendeklaration kennst du auch? Wenn dem nicht so ist, solltest du dich erst mal mit den grundlegenden Grundlagen vertraut machen.

    Hilfe lesen hilft:
    SHGetFolderPath
    Deprecated. Gets the path of a folder identified by a CSIDL value.
    Note As of Windows Vista, this function is merely a wrapper for SHGetKnownFolderPath.
    Minimum supported client Windows 2000 Professional, Windows XP

    Es gibt die Funktion noch unter Vista.



  • Danke, WM_Create werd ich dann mal für das Auslesen benutzen...
    Bin deutlich tiefer in Java oder Webprogrammiersprachen alla PHP drin als in C / C++. Hab ich ja aber auch geschrieben. Ich find es relativ schwer anständige Tutorials zu finden zu C und auch wenn ich im Studium etwas C hatte, so doch nie tiefgreifend oder besonders gut erklärt.

    Ne Variablen-Deklaration kann ich aber glaube ich ganz gut von nem Funktionsaufruf unterscheiden... oder wie kommst du drauf? Wenns nicht vollständig anders ist als in Java oder PHP zumindest. Wie gesagt: So gut wie totaler Anfänger was C angeht. Wird wohl auch nie meine Lieblingssprache werden... aber manchmal kommt man eben schlecht drum rum...

    See you und danke für deine Antwort.
    *Fuchur*



  • Fuchur84 schrieb:

    Ne Variablen-Deklaration kann ich aber glaube ich ganz gut von nem Funktionsaufruf unterscheiden... oder wie kommst du drauf?

    Wie ich darauf komme? Na wenn ich so was lese:

    noch lieber hätte ichs oben bei den CHAR-Deklarationen einfach dazugeschrieben, so dass ich genauso wie auf die anderen CHARs damit arbeiten könnte,

    Dann wird mir klar, dass da wirklich die nötigsten Grundlagen fehlen.



  • Hab ja dazugeschrieben, dass ich weiss das das nicht geht... auch wenn ichs gerne täte... aber ja, mir fehlen durchaus auch einige Grundlagen, besonders wenn ich mich außerhalb vom Standardnamespace bewege.

    Wie gesagt: Mir ist sehr wohl bewusst, dass bei mir große Wissenslücken bestehen... deshalb steht ja auch überall: "Absoluter Newbee" usw.
    dabei... aber meiner Erfahrung nach lernt man eben an konkreten Sachen am besten und wie ich auch schon des öfteren gelesen habe: C++ und Co sind eben einfach schwer übers Netz zu lernen... das hindert mich aber nicht daran es trotzdem zu versuchen...

    Wie gesagt: Danke für deine Mühen.

    Viele Grüße
    *Fuchur*


Anmelden zum Antworten