Home All Groups Group Topic Archive Search About

testing a program is running

Author
19 Dec 2005 12:38 AM
Lloyd Dupont
I'm writing my installer which, of course, is a win32 app (no .NET)
I would like to test tthe program is already running (in case of
reinstall/upgrade) and prompt the user to stop the application.

How do I do that?

Basically I would like somthing like Process.GetProcessByName() but with
win32 calls.
Any idea?

Author
19 Dec 2005 1:43 AM
William DePalo [MVP VC++ ]
"Lloyd Dupont" <net.galador@ld> wrote in message
news:%23ewagSDBGHA.4084@TK2MSFTNGP12.phx.gbl...
> I'm writing my installer which, of course, is a win32 app (no .NET)
> I would like to test tthe program is already running (in case of
> reinstall/upgrade) and prompt the user to stop the application.
>
> How do I do that?

You need a sentinel of some kind - something whose existence indicates your
application's presence.

Some applications look for windows often by class name - say one generated
by the likes of GUIDGEN.EXE. Others might look for a similarly named mutex,
registry key, whatever.

Regards,
Will
Author
19 Dec 2005 2:21 AM
Holger Grund
"Lloyd Dupont" <net.galador@ld> wrote
> I'm writing my installer which, of course, is a win32 app (no .NET)
> I would like to test tthe program is already running (in case of
> reinstall/upgrade) and prompt the user to stop the application.
>
> How do I do that?
>
> Basically I would like somthing like Process.GetProcessByName() but with
> win32 calls.

As Will has already pointed out there might be better ways to achieve what
you want. But if you really insist on Win32 equivalent for the .NET API
you might want to take a look at
- Toolhelp (this is a bit fragile but works on down-level platforms)
s. Process32First et. al.
- PSAPI
s. EnumProcesses
- NtQuerySystemInformation

-hg
Author
19 Dec 2005 4:25 AM
Lloyd Dupont
Win32 is required, it will be an InnoSetup installer function...
I did it like that:
=====================================
__declspec( dllexport ) int __stdcall IsRunning(char procName[])
{
    DWORD processes[4048], i, num;
    if ( !EnumProcesses( processes, sizeof(processes), &num ) )
        return 0;

num = num / sizeof(DWORD);
for(i=0; i<num; i++)
{
  HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
            PROCESS_VM_READ,
            FALSE, processes[i] );
  if( !hProcess )
   continue;

  HMODULE hMod;
  DWORD tmp;
  BOOL found = FALSE;
  if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), &tmp) )
  {
   TCHAR thisName[MAX_PATH];
   GetModuleBaseName( hProcess, hMod, thisName,
sizeof(thisName)/sizeof(TCHAR) );
   found = _tcscmp(thisName, procName) ? FALSE : TRUE;
  }
     CloseHandle( hProcess );

  if(found)
   return TRUE;
}
return FALSE;
}
=====================================

--
Regards,
Lloyd Dupont

NovaMind development team
NovaMind Software
Mind Mapping Software
<www.nova-mind.com>
Show quote
"Holger Grund" <holger.gr***@remove.ix-n.net> wrote in message
news:uyftfGEBGHA.2356@tk2msftngp13.phx.gbl...
> "Lloyd Dupont" <net.galador@ld> wrote
>> I'm writing my installer which, of course, is a win32 app (no .NET)
>> I would like to test tthe program is already running (in case of
>> reinstall/upgrade) and prompt the user to stop the application.
>>
>> How do I do that?
>>
>> Basically I would like somthing like Process.GetProcessByName() but with
>> win32 calls.
>
> As Will has already pointed out there might be better ways to achieve what
> you want. But if you really insist on Win32 equivalent for the .NET API
> you might want to take a look at
> - Toolhelp (this is a bit fragile but works on down-level platforms)
> s. Process32First et. al.
> - PSAPI
> s. EnumProcesses
> - NtQuerySystemInformation
>
> -hg
>
Author
19 Dec 2005 3:42 PM
Nishant Sivakumar
This is risky, if another application uses the same executable name.

--
Regards,
Nish [VC++ MVP]


Show quote
"Lloyd Dupont" <net.galador@ld> wrote in message
news:eQwCDRFBGHA.2512@TK2MSFTNGP09.phx.gbl...
> Win32 is required, it will be an InnoSetup installer function...
> I did it like that:
> =====================================
> __declspec( dllexport ) int __stdcall IsRunning(char procName[])
> {
>    DWORD processes[4048], i, num;
>    if ( !EnumProcesses( processes, sizeof(processes), &num ) )
>        return 0;
>
> num = num / sizeof(DWORD);
> for(i=0; i<num; i++)
> {
>  HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
>            PROCESS_VM_READ,
>            FALSE, processes[i] );
>  if( !hProcess )
>   continue;
>
>  HMODULE hMod;
>  DWORD tmp;
>  BOOL found = FALSE;
>  if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), &tmp) )
>  {
>   TCHAR thisName[MAX_PATH];
>   GetModuleBaseName( hProcess, hMod, thisName,
> sizeof(thisName)/sizeof(TCHAR) );
>   found = _tcscmp(thisName, procName) ? FALSE : TRUE;
>  }
>     CloseHandle( hProcess );
>
>  if(found)
>   return TRUE;
> }
> return FALSE;
> }
> =====================================
>
> --
> Regards,
> Lloyd Dupont
>
> NovaMind development team
> NovaMind Software
> Mind Mapping Software
> <www.nova-mind.com>
> "Holger Grund" <holger.gr***@remove.ix-n.net> wrote in message
> news:uyftfGEBGHA.2356@tk2msftngp13.phx.gbl...
>> "Lloyd Dupont" <net.galador@ld> wrote
>>> I'm writing my installer which, of course, is a win32 app (no .NET)
>>> I would like to test tthe program is already running (in case of
>>> reinstall/upgrade) and prompt the user to stop the application.
>>>
>>> How do I do that?
>>>
>>> Basically I would like somthing like Process.GetProcessByName() but with
>>> win32 calls.
>>
>> As Will has already pointed out there might be better ways to achieve
>> what
>> you want. But if you really insist on Win32 equivalent for the .NET API
>> you might want to take a look at
>> - Toolhelp (this is a bit fragile but works on down-level platforms)
>> s. Process32First et. al.
>> - PSAPI
>> s. EnumProcesses
>> - NtQuerySystemInformation
>>
>> -hg
>>
>
>
Author
20 Dec 2005 12:31 AM
Lloyd Dupont
in my case:
1. Mutex name collision would be just as likely, wouldn't they?
2. it's not a 8 letters word (it's "NovaMindEditor.exe")
3. who cares! it's just to popup a message box: "please leave $(APPLICATION)
before continuing"

--
Regards,
Lloyd Dupont

NovaMind development team
NovaMind Software
Mind Mapping Software
<www.nova-mind.com>
Show quote
"Nishant Sivakumar" <nish@nospam.asianetindia.com> wrote in message
news:ePbbeKLBGHA.976@TK2MSFTNGP15.phx.gbl...
> This is risky, if another application uses the same executable name.
>
> --
> Regards,
> Nish [VC++ MVP]
>
>
> "Lloyd Dupont" <net.galador@ld> wrote in message
> news:eQwCDRFBGHA.2512@TK2MSFTNGP09.phx.gbl...
>> Win32 is required, it will be an InnoSetup installer function...
>> I did it like that:
>> =====================================
>> __declspec( dllexport ) int __stdcall IsRunning(char procName[])
>> {
>>    DWORD processes[4048], i, num;
>>    if ( !EnumProcesses( processes, sizeof(processes), &num ) )
>>        return 0;
>>
>> num = num / sizeof(DWORD);
>> for(i=0; i<num; i++)
>> {
>>  HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
>>            PROCESS_VM_READ,
>>            FALSE, processes[i] );
>>  if( !hProcess )
>>   continue;
>>
>>  HMODULE hMod;
>>  DWORD tmp;
>>  BOOL found = FALSE;
>>  if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), &tmp) )
>>  {
>>   TCHAR thisName[MAX_PATH];
>>   GetModuleBaseName( hProcess, hMod, thisName,
>> sizeof(thisName)/sizeof(TCHAR) );
>>   found = _tcscmp(thisName, procName) ? FALSE : TRUE;
>>  }
>>     CloseHandle( hProcess );
>>
>>  if(found)
>>   return TRUE;
>> }
>> return FALSE;
>> }
>> =====================================
>>
>> --
>> Regards,
>> Lloyd Dupont
>>
>> NovaMind development team
>> NovaMind Software
>> Mind Mapping Software
>> <www.nova-mind.com>
>> "Holger Grund" <holger.gr***@remove.ix-n.net> wrote in message
>> news:uyftfGEBGHA.2356@tk2msftngp13.phx.gbl...
>>> "Lloyd Dupont" <net.galador@ld> wrote
>>>> I'm writing my installer which, of course, is a win32 app (no .NET)
>>>> I would like to test tthe program is already running (in case of
>>>> reinstall/upgrade) and prompt the user to stop the application.
>>>>
>>>> How do I do that?
>>>>
>>>> Basically I would like somthing like Process.GetProcessByName() but
>>>> with win32 calls.
>>>
>>> As Will has already pointed out there might be better ways to achieve
>>> what
>>> you want. But if you really insist on Win32 equivalent for the .NET API
>>> you might want to take a look at
>>> - Toolhelp (this is a bit fragile but works on down-level platforms)
>>> s. Process32First et. al.
>>> - PSAPI
>>> s. EnumProcesses
>>> - NtQuerySystemInformation
>>>
>>> -hg
>>>
>>
>>
>
>
Author
20 Dec 2005 2:42 AM
William DePalo [MVP VC++]
"Lloyd Dupont" <net.galador@ld> wrote in message
news:OeNaGzPBGHA.2356@tk2msftngp13.phx.gbl...
> in my case:
> 1. Mutex name collision would be just as likely, wouldn't they?

Well, maybe. :-)

Go to the

    bin\

subdirectory of the Platform SDK folder. Run GUIDGEN.EXE. Check radio button
#4 - registry format. Click the "New Guid" and "Copy" buttons. Then copy the
string from the clipboard into your application as a window class name,
mutex name, registry key name whatever you like. The chance of a collision
with someone else's name is vanishingly small.



Regards,
Will
Author
19 Dec 2005 5:16 PM
Tamas Demjen
Lloyd Dupont wrote:
> Win32 is required, it will be an InnoSetup installer function...
> I did it like that:

I'd consider Will's recommendation. Register a unique window class for
your application, and simply use FindWindow to find it. Or you could use
a named mutex with a unique name to check if the application is running
or not, but it's not going to return the window handle.

Tom

AddThis Social Bookmark Button