-3

Currently I am working on a mfc application and it should be named as setup.exe and done as well.Before getting into where I got struck ,I will let you what I had done. First I must prevent multiple Instances of my application.In the primary stage I created an event and checking ::getlasterror() whether the setup.exe already exists or not and if the .exe exists I am showing a messagebox.So,how many time I run the exe that many times the message boxes will get repeated. So,Instead of displaying that many messageboxes.I got a thought like,If my setup.exe is already existing then bring it to the front of the screen.So,I tried like this and it is working good enough.But here arised my actual problem i.e,Once I was installing some windows setup.exe and it's installation is going and in the meantime I tried running my setup.exe then I am getting the windows setup.exe to the front but not my application "setup.exe". This is actually I implemented in InitInstance as follows,

BOOL CMyApp::InitInstance()
{
   CWinApp::InitInstance();
   AppIsAllreadyRunning();
   return TRUE;
}

BOOL CMyApp::AppIsAllreadyRunning(BOOL bShow/*=TRUE*/)
{
   BOOL bRunning = FALSE;

   WCHAR szAppName[MAX_PATH] = {0};
  ::wcscpy_s(szAppName, MAX_PATH, theApp.m_pszExeName);
  ::wcscat_s(szAppName, MAX_PATH, L".exe");
   DWORD dwOwnPID = ::GetProcessId(::GetCurrentProcess());
   HANDLE hSnapShot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
   PROCESSENTRY32* processInfo = new PROCESSENTRY32;
   processInfo->dwSize = sizeof(PROCESSENTRY32);
   int index = 0;
   while(::Process32Next(hSnapShot, processInfo) != FALSE)
   {
     if(!::wcscmp(processInfo->szExeFile, szAppName))
      {
        if(processInfo->th32ProcessID != dwOwnPID)
        {
            if(bShow)
      ::EnumWindows(ShowAppEnum, processInfo->th32ProcessID);

            bRunning = TRUE;
            break;
        }
     }
  }
    ::CloseHandle(hSnapShot);
    delete processInfo;
    return bRunning;

}

 BOOL CALLBACK ShowAppEnum(HWND hwnd, LPARAM lParam)
{
  DWORD dwID = 0;
  ::GetWindowThreadProcessId(hwnd, &dwID) ;
  if(dwID == (DWORD)lParam)
  {
    if (!::IsWindowVisible(hwnd))
        ::ShowWindow(hwnd,SW_SHOW); 
    ::SetForegroundWindow(hwnd);
  }
  return TRUE;
}

This is how I tried.Can anyone please let me know how can make my setup.exe different from other setup.exe,When I run my setup.exe it should only come to the front,as I explained above like first if I run a different setup.exe and some installing is going on and in the sametime if I run my setup.exe it has to get launched or if it already exists it has to come on to the front.But a different setup.exe which is already running is popping up to the front(this should not happen).

Siva
  • 1,281
  • 2
  • 19
  • 41
  • Have you tried the DDE approach? – Rowland Shaw Sep 16 '14 at 14:35
  • No,I didn't.Actually I am newbie to mfc and I am not sure how to use it.Should We need override CWinApp::OnDDEComand(LPTSTR lpszCommand) ? If so,will please elaborate how to use this to get the setup.exe to front is it exists ,if it is not there the – Siva Sep 16 '14 at 15:15
  • 1
    http://blogs.msdn.com/b/vcblog/archive/2011/02/18/10131430.aspx – Hans Passant Sep 16 '14 at 15:50
  • @Hans Passant, still I am facing the same issue. – Siva Sep 17 '14 at 06:00
  • possible duplicate of [Preventing multiple instances of my application](http://stackoverflow.com/questions/8799646/preventing-multiple-instances-of-my-application) – dns Sep 04 '15 at 08:41

1 Answers1

1

In CYourApp.h:

extern const CString g_sMutexName;

In CYourApp.cpp:

const CString g_sMutexName = _T("TRA-LA-LA-LA-YOURUNIQUE_ID");


BOOL CYourApp::InitInstance()
{
CWnd* pWnd = CWnd::FindWindow(g_sMutexName, NULL);

if(NULL != pWnd)
{
    // A prevous running instance already created a window with the given class name.
    // Bring it to front then return. 
    pWnd->ShowWindow(SW_SHOWNA);
    if(pWnd->IsIconic())
        pWnd->ShowWindow(SW_RESTORE);
    pWnd->SetForegroundWindow();
    return FALSE;
}

AfxEnableControlContainer();

// Standard initialization
// If you are not using these features and wish to reduce the size
//  of your final executable, you should remove from the following
//  the specific initialization routines you do not need.
 ...

}

in your CMainFrame.cpp:

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if(! CFrameWnd::PreCreateWindow(cs))
    return FALSE;
// TODO: Modify the Window class or styles here by modifying
//  the CREATESTRUCT cs

WNDCLASS wclass;
::ZeroMemory(&wclass, sizeof(WNDCLASS));
wclass.style = CS_DBLCLKS;
wclass.hCursor = ::AfxGetApp()->LoadStandardCursor(IDC_ARROW);
wclass.hIcon = ::AfxGetApp()->LoadIcon(IDR_MAINFRAME);
wclass.lpfnWndProc = ::DefWindowProc;
wclass.lpszClassName = g_sMutexName;
::AfxRegisterClass(&wclass);

cs.lpszClass = g_sMutexName;

return TRUE;
}

And when try to open another instance of your app, the existing one will be active ...

Flaviu.

Flaviu_
  • 1,285
  • 17
  • 33
  • I am using a property sheet not an MDI or SDI application.In app class as you mentioned CWnd* pWnd = CWnd::FindWindow(g_sMutexName, NULL); pWnd is always returning null.The code within if block not at all hitting.In Wizard sheet class I added precreatewindow but it is never being called.This is a propertysheet application. – Siva Sep 17 '14 at 15:24
  • Ok, you don't have PreCreateWindow there, but you must have something right before creating window ... there, you can setup class name as mutex ... – Flaviu_ Sep 18 '14 at 06:29
  • Check all the projects from here: http://www.microsoft.com/msj/archive/S252.aspx ... unzipp them, and check UNDR0296 project ... behave like you want. :) – Flaviu_ Sep 22 '14 at 13:41