bright, fresh software
Downloads  |  Buy

How to Silently update a Windows Service

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.

Use the AutomaticUpdater control

If you have a .NET application (C#, VB.NET, etc.) then you can add fully integrated automatic updating to your app. You can silently check for updates, download them, and install the updates without bothering your users. Learn more about the automatic updater here.

Silently Updating a Windows Service without using the AutomaticUpdater

If you don't want to use the AutomaticUpdater control (or can't because your app isn't a .NET app) you can still silently update services. It involves 2 steps:

Checking for updates

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.

Silently updating a Windows Service app

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:

Example C++ code

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;
}

Updating in a Windows Service

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.