This article will teach you how to use wyUpdate in "standalone mode" to silently update your app from within a Windows Service. This is just a part of the larger step-by-step walkthrough. So if you haven't read the walkthrough you should start there.
To use wyUpdate to silently check if there are updates, the use the "/quickcheck /justcheck /noerr
" arguments when starting wyUpdate:
wyUpdate.exe /quickcheck /justcheck /noerr
wyUpdate will return 0 if no updates are found, 1 if an error occurred, and 2 if there are updates available.
If there's an update available, you can use the "/fromservice" argument to start the updating process:
wyUpdate.exe /fromservice
You should not exit your service after you start wyUpdate with the "/fromservice" argument. Instead you should stop your service before the update and start it again after the update.
Also, your service must be installed as a "LocalSystem" service for the updating to work correctly. Please note that a "LocalSystem" service is different than a "LocalService" service:
Below is a C++ sample to that launches wyUpdate to silently check for updates. Then, if updates are found, the service relaunches wyUpdate to install the new update.
#include "Shlwapi.h" #pragma comment (lib, "Shlwapi.lib") void GetModuleDirectory(LPTSTR szPath) { GetModuleFileName(NULL, szPath, MAX_PATH); LPTSTR pSlash = _tcsrchr(szPath, '\\'); if (pSlash == 0) szPath[2] = 0; else *pSlash = 0; } bool UpdateAvailable() { // Get the real path to wyUpdate.exe // (assumes it's in the same directory as this app) TCHAR szPath[MAX_PATH]; szPath[0] = '\"'; GetModuleDirectory(&szPath[1]); PathAppend(szPath, _T("wyUpdate.exe\" /quickcheck /justcheck /noerr")); STARTUPINFO si = {0}; si.cb = sizeof(si); PROCESS_INFORMATION pi = {0}; // start wyUpdate if (!CreateProcess(NULL, szPath, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { // Failed to launch wyUpdate. return false; } // Wait until child process exits. WaitForSingleObject(pi.hProcess, INFINITE); // Get the exit code DWORD exitcode = 0; GetExitCodeProcess(pi.hProcess, &exitcode); // Close process and thread handles. CloseHandle(pi.hProcess); CloseHandle(pi.hThread); // exitcode of 2 means update available return exitcode == 2; }
The following snippet of code uses the UpdateAvailable() function and launch wyUpdate with the argument "/fromservice" so that wyUpdate will run without UI prompts:
if (UpdateAvailable()) { TCHAR szPath[MAX_PATH]; GetModuleDirectory(szPath); PathAppend(szPath, _T("wyUpdate.exe")); // Start wyUpdate and tell we want to update with no UI prompts ShellExecute(NULL, NULL, szPath, _T("/fromservice"), NULL, SW_HIDE); }
Also, notice how we're not exiting from the service when we tell wyUpdate to begin updating. Instead we let wyUpdate shut down your service, that way if anything goes wrong in the update process wyUpdate will roll back the update and restart your service.