Click here to Skip to main content
15,897,371 members
Articles / Programming Languages / C++

Avoid Multiple Instances of Windows Application with SingleInstanceGuard

Rate me:
Please Sign up or sign in to vote.
3.92/5 (20 votes)
21 Oct 2010CPOL16 min read 54.3K   629   27  
A simple utility class that helps maintain one instance of your application and allows other instances to transfer the data processing to it before they close
// 
// SingleInstanceGuard
//
// This is a simple utility class that enables Windows applications to maintain just one 
// running instance. The other instances can transfer their data to the running instance.
// before closing.
//
// Designed and Coded by Vinay MS aka bleedingfingers
//
// Oct 2 2010
//
// Version 1.1
//
// --------------------------
//
// Changes from Version 1.0
//        
// ** Added a public function :
//     void SetTargetWindow(HWND h)
//    Reason: 
//     Bug fix: 
//    Reported by:
//     Victor Nijegorodov http://www.codeproject.com/KB/cpp/Sig.aspx?msg=3637250#xx3637250xx
//    Bug description: 
//     The function AlertTheRunningInstance(...) used to post SIGM_ALERT directly to the
//     thread of the running instance. That made the message to go unnoticed if the running
//     instance was in a modal loop. Apart from that, if data was supposed to be shared, owing 
//     to the alert mechanism, the other instances would go into a deadlock and remain in the 
//     memory.
//    Solution:
//     With this function, a GUI app can indicate the target window to which the message would
//     be posted and not to the thread.
//    Revision date:
//     Oct 19 2010
// 
/////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once

#include <windows.h>
#include <string>

class SingleInstanceGuard
{
public:
	class Exception
	{
	public:
		enum REASON 
		{ 
			DIFFERENT_GUARDS, 
			UNABLE_TO_CHECK,
			UNABLE_TO_READ,
			UNABLE_TO_WRITE,
			UNABLE_TO_ALERT,
			SHARING_WITH_SELF, 
			DATA_TOO_BIG, 
			OPERATION_NOT_SUPPORTED
		};
		REASON m_r;
		Exception(REASON r):m_r(r){}
	};

	// This is the alert message that would be sent to the running instance by the other instances
	static UINT SIGM_ALERT;

	SingleInstanceGuard(const char *pID, long nSharedDataSize=-1);
	~SingleInstanceGuard();	

	void SetTargetWindow(HWND h);
	bool AlreadyRunning();
	template<class DATA> SingleInstanceGuard& operator << (const DATA &d){return Write((void*)&d, sizeof(d));}
	SingleInstanceGuard& operator << (const std::string &s);
	template<class DATA> bool operator >> (DATA &d){return Read((void*)&d, sizeof(d));}	
	bool operator >> (std::string &s);
	void AlertTheRunningInstance();
	
private:
	SingleInstanceGuard& Write(void *pData, int nize);
	bool Read(void *pData, int nize);
};
// These are unsupported and must not be used.and hence implemented to explicitly disallow
void operator<<(SingleInstanceGuard &t, char *p);
void operator>>(SingleInstanceGuard &t, char *p);

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)



Comments and Discussions