testing a program is running

  • Thread starter Thread starter Lloyd Dupont
  • Start date Start date
L

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?
 
Lloyd Dupont said:
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
 
Lloyd Dupont said:
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
 
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 );
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>
 
This is risky, if another application uses the same executable name.

--
Regards,
Nish [VC++ MVP]


Lloyd Dupont said:
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 );
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 said:
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
 
Lloyd said:
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
 
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>
Nishant Sivakumar said:
This is risky, if another application uses the same executable name.

--
Regards,
Nish [VC++ MVP]


Lloyd Dupont said:
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 );
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 said:
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

 
Lloyd Dupont said:
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
 
Back
Top