Program autoaktualizacji

0

Witam!
Poszukuję skryptu/kodu/programu który pozwoli mi aktualizować oprogramowanie.
Mam program który wyświetla pewne dane pobierając je z kilku plików z katalogu programu.
Chciałbym go móc wraz z danymi aktualizować.
Powiedzmy, że w folderze programu tworzę plik files.versions (.TXT) o takiej zawartości:

program.exe=4.1
datafiles=6,8

program wchodzi na stronę strona.pl/ver.php?program.exe=4.1&datafiles=6,8
strona jeśli znalazła by nową wersję aplikacji albo danych zwracała by coś takiego:

program.exe=NEW
program.exe.path=strona.pl/program.exe
datafiles=NEW
datafiles.path=strona.pl/data.zip

problem w tym, że program musiał by podmienić program.exe jeśli znajdzie nową wersję, a jeśli znajdzie nową wersję danych to usuwa katalog wraz z danymi o nazwie "DANE"
w katalogu aplikacji i zastępuje go danymi wypakowanymi z data.zip

W C++ dopiero się uczę, znam jedynie płynnie PHP, a potrzebuję "na wczoraj" taki moduł do mini programu który stworzyłem przy wykorzystaniu platformy .NET Framework w Visual C++ 2010 który stworzyłem charytatywnie dla pewnej szkoły.
Proszę bardzo o jakieś wskazówki, bardzo mile widziane fragmenty kodu, artykuły itp. będę kombinował jak to zrobić, dla tego nie żądam gotowca.
Szukałem u "wujka" google, na forum i innych stronach ale nie znalazłem odpowiedzi na mój problem.

0

myślę że powinieneś zrobić osobny upgrader który by robił to co napisałeś bo program sam siebie nie podmieni. Jeśli dobrze zrozumiałem oczywiście, że program właściwy ma wyszukiwać aktualizacje itd

0

Tak jak przedmówca powiedział, trzeba drugi exec (często nazywa się on upgrmgr.exe "upgrade manager" jak się popatrzy w komercyjne programy), bo musisz to zrobić w osobnym procesie, odpalonego exec'a nie podmienisz.

Jak zrobić PRO upgrader:

Co powinien zrobić upgrader (zakładam, że korzystasz jedynie z winapi):

  1. Sprawdzić czy proces docelowy jest uruchomiony, jeśli nie zakończyć go
    //jeśli jest uruchomiony:
    Najpierw dobrze jest stwierdzić istnienie danego procesu (EnumProcesses: http://msdn.microsoft.com/en-us/library/ms682629(v=vs.85).aspx i iterujesz wyliczone procesy + OpenProcess po kolei na każdym procesie + do odczytania nazwy (jest mnogo sposobów) main module: GetProcessImageFileName: http://msdn.microsoft.com/en-us/library/ms683217(v=VS.85).aspx(to do XP) lub QueryFullProcessImageName(to od Visty) lub stare dobre GetModuleFileNameEx: http://msdn.microsoft.com/en-us/library/ms683198(v=VS.85).aspx(od win2k) ale nie działa pomiędzy procesami x86~x64). Po odczytaniu CloseHandle zamykasz otwarty OpenProcess.
    Jeśli znajdziesz szukaną nazwę procesu trzeba by go zakończyć (wracając do iteracji zwracam też na fakt możliwości istnienia kilku procesów z tego samego execa).

1.1 Sposobów znowu jest mnogo w zależności od rodzaju procesu. Najlepiej jak program ten ma okno główne którego zamknięcie krzyżykiem kończy proces, wtedy ogranicza się do zamknięcia okna. Żeby znaleźć to okno: (FindWindow: http://msdn.microsoft.com/en-us/library/ms633499(v=vs.85).aspx) + PostMessage(hWnd, WM_CLOSE, 0, 0); i trzeba by dać chwilę procesowi na posprzątanie się, żeby odczekać można(sposób łopatologiczny): (Sleep: http://msdn.microsoft.com/en-us/library/ms686298(v=vs.85).aspx) i sprawdzanie w pętli czy już po procesie lub (bardziej PRO, a wcale nie bardziej skomplikowany :>) można pobawić się w WaitForSingleObject przekazując handle otwartego wcześniej procesu OpenProcess.
1.2 Jeśli proces nie ma okna, ale ma wątek posiadający systemową pętlę komunikatów, trzeba by spróbować wysłać mu WM_QUIT, jest trochę pisaniny żeby dobrać się wątku głównego, tutaj jest kompletny przykład: http://www.codeproject.com/Questions/78801/How-to-get-the-main-thread-ID-of-a-process-known-b.aspx
1.3 Jeśli powyższe 2 poprzednie kroki nie dają skutku, bo po odczekaniu danego czasu dziad nie chce się ubić lub jeśli po prostu proces nie wykonuje pętli zdarzeniowej (przeprowadza ciągłe obliczenia i/lub np. jest stopowany czymś synchronizacyjnym i większość czasu wisi) trzeba go wywalić na hama: TerminateProcess: (http://msdn.microsoft.com/en-us/library/ms686714(v=vs.85).aspx).

  1. Jak wiadomo, że proces jest ubity możesz już po swojemu kombinować z podmianami plików, dobrze jakbyś wcześniej pobrał w docelowym programie zawartość nowej aktualizacji (albo i ten może pobierać to w sumie bez różnicy), w każdym razie dobrze też zrobić kopię zapasową obecnego stanu programu :> po czym można zmieniać co potrzeba: podstawowe funkcje: CopyFile, DeleteFile, MoveFile, itd. ew. CreateFile (http://msdn.microsoft.com/en-us/library/aa364232(v=VS.85).aspx).

  2. Jak wszystko będzie już gotowe można dać CreateProcess odpalając nową wersję programu docelowego, tutaj jeśli program docelowy jest nasz, dobrze jest przetestować czy program poprawnie działa, np. robiąc w nim eventa (CreateEvent) w ten sposób informując upgreader że śmiga, w tym momencie można posprzątać kopię zapasową, no i chyba tyle...

Aha jeśli chcemy pobierać zasoby HTTP lub FTP celem pobrania aktualizacji można użyć starego dobrego WinINet: (http://msdn.microsoft.com/en-us/library/aa385483(v=VS.85).aspx), podpinanie oddzielnych bibliotek czy ręcznie pisanie tego w winsocku nie jest konieczne.

1 użytkowników online, w tym zalogowanych: 0, gości: 1