Auto Update Prozess



  • Hallo,

    was ist der beste (und einfachste - sofern sich das nicht ausschließt) Weg um eine Auto Update Prozess für ein Programm zu implementieren? Das ganze mit WinAPI Bordmitteln und für Windows XP bis Windows 7.
    Mein Hauptproblem ist hier Windows Vista/7 und die UAC, da der normale User nicht in C:\Programme schreiben darf und damit die exe nicht ausgetauscht werden darf.

    Folgendes habe ich mir ausgedacht:

    1. Bei der Installation (welche als Admin läuft) lasse ich eine Service mit installieren.
      Meine Vermutung ist folgende:
      Wenn der Service als Admin installiert wurde, hat er auch Adminrechte (hier muss ich bei der Installation vielleicht noch etwas beachten)
    2. Mein Programm prüft, ob auf der Homepage eine neue Version vorhanden ist und lädt diese herunter und speichert sie unter Eigene Dateien...
    3. Dann wird der Service gestartet und dieser tauscht die Dateien aus

    So, jetzt wart ich darauf, das mir jemand sagt, dass das Bullshit ist und es eine andere Möglichkeit gibt 😃



  • Hallo,

    also ganz ehrlich?! Wenn ich, nachdem ich mein OS neu aufgesetzt und sämtliche Software neu installiert habe, in meine Dienste sehe wird mir übel. Was sich da alles einnistet und Updates machen will ist pervers und geht mir persönlich total auf den Sack. Apple macht es beispielsweise so und noch jede Menge andere Programme...

    Ich finde folgende Lösung am elegantesten:

    Bastel dir zwei Anwendungen. Eine ist deine Hauptanwendung die, bei Bedarf(Benutzer kann einen Haken irgendwo setzen oder so), die zweite Anwendung aufruft und die führt dann das Update durch. Schließt also die Hauptanwendung, prüft, lädt bla bla bla...

    Das ist vielleicht schon mal der erste Ansatz.

    Jedoch kann ich dir leider nicht weiterhelfen was die Rechte usw. angeht.



  • Achso..und was mir noch so einfällt...
    Also erstmal ist es mir neu, dasa man nicht so einfach in den besagten Ordner schreiben darf. Kann zwar gut sein aber ich weiß es halt nicht. Aber ich frage mich dann nur, wie schon die Installation ablaufen soll?!
    Und ein anderes Problem, was mich mal unglaublich nervte, war, der Unterschied zwischen 32 und 64 bittigen Anwendungen. Ich hatte mal vorgehabt eine Anwendung, die 32 bittig war, in den system32 Ordner unter einem 64bittigen OS zu erstellen. Das ging voll nach hinten los..Immerhin gibt es doch auf für iinstallierte Programme auch einen x86 Ordner und einen Ordner für 64bittige Anwendungen



  • Bei eingeschaltener UAC ist es unter Vista und Windows 7 so, dass ein Popup bei der Installation erscheint bei welchen man bestätigen muss, dass jetzt auf Admin Rechte umgeschalten wird.
    Das die Application als Admin laufen muss, kann man vom Visual Studio in die Manifest Datei schreiben lassen. Dann macht das Windows automatisch.
    Bei eingeschaltener UAC darf der User (wenn das Programm nicht als Admin läuft) nicht in Programme schreiben. Deshalb sollen ja Programm alle Einstellungen und alle Daten in "Dokumente und Einstellungen" speichern.
    Ach ja, UAC ist per Default eingeschalten...

    Zu deinem Lösungsvorschlag... ich muss sagen, das mir die ganzen Services auch auf die Nerven gehen. Schon alleine das sollte ein Grund sein, dass nicht so zu machen 🙄

    Allerdings muss wenn ein Update ausgeführt wird, immer der UAC Dialog bestätigt werden. Ich muss mir das noch mal überlegen 😃



  • Machs einfach so, dass der User dein Programm als Admin starten muss. Is doch nix dabei.
    Wenn das Programm nicht als Admin gestartet wird, kommt halt ne Meldung und es wird abgebrochen



  • Und wo ich da ja gerade sehe, dass du einen Dienst erstellen willst...

    Könnest du vielleicht so freundlich sein und mal das Grundgerüst eines Dienstes(C++/WINAPI) reinstellen:-)?
    Irgendwie komme ich da nämlich nicht weiter:-P



  • Der_Knob schrieb:

    Allerdings muss wenn ein Update ausgeführt wird, immer der UAC Dialog bestätigt werden. Ich muss mir das noch mal überlegen 😃

    das ist gängige Praxis, an der sich niemand stören dürfte. Zumindest bei weitem nicht so wie an einem Dienst, der mit Admin-Rechten im Hintergrund läuft



  • ok, überzeugt... dann ein Update Programm, welcher mit Adminrechten laufen muss...

    @secondsun: Hier mal das Grundgerüst für einen Service.
    Ich hab das schnell mal zusammen kopiert. Hab's aber nicht getestet.
    Falls es Probleme gibt, meld dich noch mal.

    #include <windows.h>
    
    TCHAR*			serviceName = TEXT("pEmergencyUser");
    SERVICE_STATUS		serviceStatus;
    SERVICE_STATUS_HANDLE	serviceStatusHandle = 0;
    HANDLE			stopServiceEvent = 0;
    
    void WINAPI ServiceControlHandler( DWORD controlCode )
    {
    	switch ( controlCode )
    	{
    		case SERVICE_CONTROL_INTERROGATE:
    			break;
    
    		case SERVICE_CONTROL_SHUTDOWN:
    		case SERVICE_CONTROL_STOP:
    			serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
    			SetServiceStatus( serviceStatusHandle, &serviceStatus );
    
    			SetEvent( stopServiceEvent );
    			return;
    
    		case SERVICE_CONTROL_PAUSE:
    			break;
    
    		case SERVICE_CONTROL_CONTINUE:
    			break;
    
    		default:
    			if ( controlCode >= 128 && controlCode <= 255 )
    				// user defined control code
    				break;
    			else
    				// unrecognised control code
    				break;
    	}
    
    	SetServiceStatus( serviceStatusHandle, &serviceStatus);
    }
    
    void WINAPI ServiceMain( DWORD /*argc*/, TCHAR* /*argv*/[] )
    {
    	// initialise service status
    	serviceStatus.dwServiceType = SERVICE_WIN32;
    	serviceStatus.dwCurrentState = SERVICE_STOPPED;
    	serviceStatus.dwControlsAccepted = 0;
    	serviceStatus.dwWin32ExitCode = NO_ERROR;
    	serviceStatus.dwServiceSpecificExitCode = NO_ERROR;
    	serviceStatus.dwCheckPoint = 0;
    	serviceStatus.dwWaitHint = 0;
    
    	serviceStatusHandle = RegisterServiceCtrlHandler( serviceName, ServiceControlHandler );
    
    	if ( serviceStatusHandle )
    	{
    		// service is starting
    		serviceStatus.dwCurrentState = SERVICE_START_PENDING;
    		SetServiceStatus( serviceStatusHandle, &serviceStatus );
    
    		// do initialisation here
    		stopServiceEvent = CreateEvent( 0, FALSE, FALSE, 0 );
    
    		// running
    		serviceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
    		serviceStatus.dwCurrentState = SERVICE_RUNNING;
    		SetServiceStatus( serviceStatusHandle, &serviceStatus );
    
    		// ToDo .... do work here or do a loop until the process is stopped
    		// do
    		// {
    		// }
    		// while ( WaitForSingleObject( stopServiceEvent, 5000 ) == WAIT_TIMEOUT );
    
    		// service was stopped
    		serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
    		SetServiceStatus( serviceStatusHandle, &serviceStatus );
    
    		// do cleanup here
    		CloseHandle( stopServiceEvent );
    		stopServiceEvent = 0;
    
    		// service is now stopped
    		serviceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
    		serviceStatus.dwCurrentState = SERVICE_STOPPED;
    		SetServiceStatus( serviceStatusHandle, &serviceStatus );
    	}
    }
    
    void RunService()
    {
    	SERVICE_TABLE_ENTRY serviceTable[] =
    	{
    		{ serviceName, ServiceMain },
    		{ 0, 0 }
    	};
    
    	StartServiceCtrlDispatcher( serviceTable );
    }
    
    void InstallService()
    {
    	SC_HANDLE serviceControlManager = OpenSCManager( 0, 0, SC_MANAGER_CREATE_SERVICE );
    
    	if ( serviceControlManager )
    	{
    		TCHAR path[ _MAX_PATH + 1 ];
    		if ( GetModuleFileName( 0, path, sizeof(path)/sizeof(path[0]) ) > 0 )
    		{
    			SC_HANDLE service = CreateService( serviceControlManager,
    							serviceName, serviceName,
    							SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
    							SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, path,
    							0, 0, 0, 0, 0 );
    			if ( service )
    				CloseServiceHandle( service );
    		}
    
    		CloseServiceHandle( serviceControlManager );
    	}
    }
    
    void UninstallService()
    {
    	SC_HANDLE serviceControlManager = OpenSCManager( 0, 0, SC_MANAGER_CONNECT );
    
    	if ( serviceControlManager )
    	{
    		SC_HANDLE service = OpenService( serviceControlManager,
    			serviceName, SERVICE_QUERY_STATUS | DELETE );
    		if ( service )
    		{
    			SERVICE_STATUS serviceStatus;
    			if ( QueryServiceStatus( service, &serviceStatus ) )
    			{
    				if ( serviceStatus.dwCurrentState == SERVICE_STOPPED )
    					DeleteService( service );
    			}
    
    			CloseServiceHandle( service );
    		}
    
    		CloseServiceHandle( serviceControlManager );
    	}
    }
    
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
    {
    	if ( lstrcmpi( szCmdLine, TEXT("install") ) == 0 )
    	{
    		InstallService();
    	}
    	else if ( lstrcmpi( szCmdLine, TEXT("uninstall") ) == 0 )
    	{
    		UninstallService();
    	}
    	else
    	{
    		RunService();
    	}
    
    	return 0;
    }
    


  • Ne, das reicht mir so schon:-)
    Vielen Dank;-)



  • Moment mal... du magst doch keine Services... war das ein April Scherz 😃



  • Ich mag keine Update Dienste:-P
    Und ich mag sie noch weniger wenn sie von Apple kommen:-D

    Brauche jetzt nur einen Dienst für einen Kunden. Deswegen kam das gerade wie gerufen.

    Nettes Programm habt ihr da übrigens entwickelt;-)


Anmelden zum Antworten