Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

How To Create a Self-Restartable Application

, 21 Aug 2006 CPOL
This article describes the way to add restarting support to your Win32 applications.
restartableapp_demo.zip
RestartableApp_Demo
Release
RestartableApp.exe
res
RestartableApp.exe.manifest
RestartableApp.ico
restartableapp_src.zip
RestartableApp_src
#include "stdafx.h"
#include "RestartAPI.h"

// Global Variables
HANDLE g_RA_hMutexOtherRestarting = NULL;	// Mutex
BOOL g_RA_bWasRestarted = FALSE;			// Restarted Flag

BOOL RA_CheckProcessWasRestarted()
{
	return g_RA_bWasRestarted;
}

BOOL RA_CheckForRestartProcessStart()
{
	// Simple find substring in command line
	LPTSTR szCmdLine = ::GetCommandLine();
	return ::StrStr(szCmdLine, RA_CMDLINE_RESTART_PROCESS) != NULL;
}

BOOL RA_WaitForPreviousProcessFinish()
{
	// App restarting
	BOOL AlreadyRunning;
	// Try to Create Mutex
	g_RA_hMutexOtherRestarting = ::CreateMutex( NULL, FALSE, RA_MUTEX_OTHER_RESTARTING);
	DWORD dwLastError = ::GetLastError();
	AlreadyRunning = (dwLastError == ERROR_ALREADY_EXISTS || dwLastError == ERROR_ACCESS_DENIED);
	if ( AlreadyRunning )
	{
		// Waiting for previous instance release mutex
		::WaitForSingleObject(g_RA_hMutexOtherRestarting, INFINITE);
		::ReleaseMutex(g_RA_hMutexOtherRestarting);
		g_RA_bWasRestarted = TRUE;
	}
	::CloseHandle(g_RA_hMutexOtherRestarting);
	g_RA_hMutexOtherRestarting = NULL;
	return TRUE;
}

BOOL RA_DoRestartProcessFinish()
{
	// Releasing mutex signal that process finished
	DWORD dwWaitResult = WaitForSingleObject(g_RA_hMutexOtherRestarting, 0);
	if (dwWaitResult == WAIT_TIMEOUT)
		::ReleaseMutex(g_RA_hMutexOtherRestarting);
	::CloseHandle(g_RA_hMutexOtherRestarting);
	g_RA_hMutexOtherRestarting = NULL;
	return (dwWaitResult == WAIT_TIMEOUT);
}
BOOL RA_ActivateRestartProcess()
{
	// Restart App
	BOOL AlreadyRunning;
	g_RA_hMutexOtherRestarting = ::CreateMutex( NULL, TRUE, RA_MUTEX_OTHER_RESTARTING);
	DWORD dwLastError = ::GetLastError();
	AlreadyRunning = (dwLastError == ERROR_ALREADY_EXISTS || dwLastError == ERROR_ACCESS_DENIED);
	if (AlreadyRunning)
	{
		::WaitForSingleObject(g_RA_hMutexOtherRestarting, INFINITE);
		::ReleaseMutex(g_RA_hMutexOtherRestarting);
		::CloseHandle(g_RA_hMutexOtherRestarting);
		return FALSE;
	}

	TCHAR szAppPath[MAX_PATH] = {0};
	::GetModuleFileName(NULL, szAppPath, MAX_PATH);

	STARTUPINFO				si = {0};
	PROCESS_INFORMATION		pi = {0};
	si.cb = sizeof(STARTUPINFO);
	// Create New Instance command line
	::PathQuoteSpaces(szAppPath);
	::lstrcat(szAppPath, _T(" "));
	::lstrcat(szAppPath, RA_CMDLINE_RESTART_PROCESS); // Add command line key for restart
	// Create another copy of processS
	return ::CreateProcess(NULL, szAppPath, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Alexander D. Alexeev
Software Developer (Senior)
Russian Federation Russian Federation
No Biography provided

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141223.1 | Last Updated 21 Aug 2006
Article Copyright 2006 by Alexander D. Alexeev
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid