Board index » cppbuilder » Spawning and controlling

Spawning and controlling


2005-11-11 11:02:04 PM
cppbuilder46
Hi
From within my application, I would like to spawn an arbitrary third party
application (say foo.exe) in the following way:
1. Check whether foo.exe is already running so that I don't attempt to run
it twice;
2. Spawn foo.exe
3. Make foo's parent my application, so that it displays within one of my
windows;
4. From my app, terminate foo.exe
I can probably cope with (3), but I am at a loss about how to do the rest.
Many thanks in advance,
Denville.
 
 

Re:Spawning and controlling

Denville Longhurst wrote:
Quote
1. Check whether foo.exe is already running so that I don't attempt to run
it twice;
Use acess() to check if the file is writable.
When the program is running, it is not writable.
If the file is marked as read-only, or resides on a CD, then this
method will fail.
Quote
2. Spawn foo.exe
Use CreateProcess()
Quote
4. From my app, terminate foo.exe
CreateProcess() returns handles that can be used to terminate the
process.
 

Re:Spawning and controlling

Denville Longhurst wrote:
Quote
Hi

From within my application, I would like to spawn an arbitrary third party application (say
foo.exe) in the following way:

1. Check whether foo.exe is already running so that I don't attempt to run it twice;
2. Spawn foo.exe
3. Make foo's parent my application, so that it displays within one of my windows;
4. From my app, terminate foo.exe

I can probably cope with (3), but I am at a loss about how to do the rest.
This bunch of code should give you the needed tools. This requires Win2000 or better, however,
since I never implemented backwards compatability.
/*********** PROCCONTROL.H *************/
#ifndef ProcControlH
#define ProcControlH
#include <vcl.h>
#include <Wbemcli.h>
#include <tlhelp32.h>
#define TA_FAILED 0
#define TA_SUCCESS_CLEAN 1
#define TA_SUCCESS_KILL 2
#define TA_SUCCESS_16 3
int __fastcall TerminateAppByName(AnsiString ExeName, int timeout = 2000);
bool __fastcall IsProcessRunning(AnsiString ExeName);
AnsiString __fastcall GetProcessFilePath(AnsiString ExeName);
HWND WINAPI WindowFromFileName(AnsiString ExeName);
void __fastcall LaunchApplication(AnsiString ExeName, bool wait = false);
//---------------------------------------------------------------------------
#endif
/*********** PROCCONTROL.CPP *************/
#include "ProcControl.h"
#include "utilcls.h"
IWbemLocator *pLoc;
IWbemServices *pSvc;
IEnumWbemClassObject *pEnum;
IWbemClassObject *pProcesses;
typedef struct
{
DWORD dwID ;
DWORD dwThread ;
} TERMINFO ;
// Declare Callback Enum Functions.
BOOL CALLBACK TerminateAppEnum( HWND hwnd, LPARAM lParam ) ;
BOOL CALLBACK Terminate16AppEnum( HWND hwnd, LPARAM lParam ) ;
DWORD WINAPI TerminateApp( DWORD dwPID, DWORD dwTimeout ) ;
DWORD WINAPI Terminate16App( DWORD dwPID, DWORD dwThread, WORD w16Task, DWORD dwTimeout );
//---------------------------------------------------------------------------
// IsProgramRunning(AnsiString exefile)
// Determine if program 'exefile' is running.
//---------------------------------------------------------------------------
bool __fastcall IsProcessRunning(AnsiString ExeName)
{
HANDLE hSnap;
PROCESSENTRY32 process;
BOOL f;
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if ( hSnap == NULL )
return false; // NOT RUNNING!!
process.dwSize = sizeof(PROCESSENTRY32);
f = Process32First(hSnap, &process);
while ( f )
{
AnsiString file(ExtractFileName(process.szExeFile));
if ( file.AnsiCompareIC(ExeName) == 0 )
{
CloseHandle(hSnap);
return true; // PROGRAM IS RUNNING!
}
f = Process32Next(hSnap, &process);
}
CloseHandle(hSnap);
return false; // NOT RUNNING!!
}
//---------------------------------------------------------------------------
// IsProgramRunning(AnsiString exefile)
// Determine if program 'exefile' is running.
// Return the full path to the executable if it IS running, else NULL.
//---------------------------------------------------------------------------
int __fastcall TerminateAppByName(AnsiString ExeName, int timeout)
{
DWORD dwID = 0;
GetWindowThreadProcessId(WindowFromFileName(ExeName), &dwID) ;
int ret = TerminateApp( dwID, timeout );
return ret;
/*
if(ret == TA_FAILED)
OutputDebugString("The shutdown failed");
if(ret == TA_SUCCESS_CLEAN)
OutputDebugString("The process was shutdown using WM_CLOSE.");
if(ret == TA_SUCCESS_KILL)
OutputDebugString("The process was shut down with TerminateProcess().");
*/
}
//---------------------------------------------------------------------------
bool __fastcall InitCom()
{
HRESULT hres;
hres = CoInitializeEx(0, COINIT_MULTITHREADED); //Initialize COM.
if ( FAILED(hres) )
{
ShowMessage("Failed to initialize COM library. Error code = "+IntToHex((int)hres,8));
return false;
}
hres = CoInitializeSecurity(
NULL, // security descriptor
-1, // use this simple setting
NULL, // use this simple setting
NULL, // reserved
RPC_C_AUTHN_LEVEL_CONNECT, // Windows NT 4/Windows 2000 authentication level
RPC_C_IMP_LEVEL_IMPERSONATE, // impersonation level
NULL, // use this simple setting
EOAC_NONE, // no special capabilities
0); // reserved
if ( FAILED(hres) )
{
ShowMessage("Failed to initialize security. Error code = "+IntToHex((int)hres,8));
CoUninitialize();
return false;
}
return true;
}
//---------------------------------------------------------------------------
AnsiString __fastcall GetProcessFilePath(AnsiString ExeName)
{
AnsiString ExePath = NULL;
HRESULT hres;
pLoc = 0;
//IWbemLocator interface for obtaining the initial namespace pointer to
//the Windows Management on a particular host computer.
hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)
&pLoc);
if ( FAILED(hres) )
{
ShowMessage("Failed to create IWbemLocator object. Err code = "+IntToHex((int)hres,8));
CoUninitialize();
return NULL;
}
pSvc = 0;
hres = pLoc->ConnectServer(L"\\\\.\\root\\cimv2", NULL, NULL, 0, NULL, 0, 0, &pSvc);
if ( FAILED(hres) )
{
ShowMessage("Could not connect. Error code = "+IntToHex((int)hres,8));
CoUninitialize();
return NULL;
}
// Set the proxy so that impersonation of the client occurs.
hres = CoSetProxyBlanket(pSvc,
RPC_C_AUTHN_WINNT, // NTLM authentication service
RPC_C_AUTHZ_NONE, // default authorization service...
NULL, // no mutual authentication
RPC_C_AUTHN_LEVEL_CONNECT, // authentication level
RPC_C_IMP_LEVEL_IMPERSONATE, // impersonation level
NULL, // use current token
EOAC_NONE); // no special capabilities
if ( FAILED(hres) )
{
ShowMessage("Could not set proxy blanket. Error code = "+IntToHex((int)hres,8));
pSvc->Release();
pLoc->Release();
CoUninitialize();
return NULL;
}
BSTR className = SysAllocString(L"Win32_Process");
hres = pSvc->GetObject(className, 0, NULL, &pProcesses, NULL );
//Retrieves an class object.
ULONG puReturned;
//Create instance for enumeration ports
hres=pSvc->CreateInstanceEnum( className, NULL, NULL, &pEnum );
//no need in variable className now.
SysFreeString(className);
if ( hres != 0 )
{
ShowMessage("Error");
return NULL;
}
// Retrieve the objects in the result set.
for ( ;; )
{
ULONG uReturned = 0;
hres = pEnum->Next(
WBEM_INFINITE, // Time out
1, // One object
&pProcesses,
&uReturned
);
if ( uReturned == 0 )
{
break;
}
IWbemClassObject *pObj1;
VARIANT Val;
VARIANT Val1;
VARIANT Val2;
VARIANT Val3;
VariantInit(&Val);
VariantInit(&Val1);
VariantInit(&Val2);
VariantInit(&Val3);
CIMTYPE pvtType;
BSTR Name1 = SysAllocString(L"ExecutablePath");
BSTR Name2 = SysAllocString(L"Name");
BSTR Name3 = SysAllocString(L"Handle");
LPSTR PathToProcess1=0;
LPSTR NameProc1=0;
LPSTR Handle1=0;
hres=pProcesses->Get(Name1,0,&Val1,&pvtType,NULL);
if ( Val1.vt == VT_NULL )
PathToProcess1="UNKNOWN";
else
PathToProcess1=WideToAnsi(Val1.bstrVal);
hres=pProcesses->Get(Name2,0,&Val2,&pvtType,NULL);
if ( Val2.vt == VT_NULL )
NameProc1="UNKNOWN";
else
NameProc1=WideToAnsi(Val2.bstrVal);
hres=pProcesses->Get(Name3,0,&Val3,&pvtType,NULL);
if ( Val3.vt == VT_NULL )
continue;
else
Handle1=WideToAnsi(Val3.bstrVal);
SysFreeString(Name1);
SysFreeString(Name2);
SysFreeString(Name3);
VariantClear(&Val);
VariantClear(&Val1);
VariantClear(&Val2);
VariantClear(&Val3);
if ( !stricmp(NameProc1, ExeName.c_str()) )
ExePath = PathToProcess1;
if ( Handle1 )
delete []Handle1;
if ( PathToProcess1 && (AnsiString(PathToProcess1) != "UNKNOWN") )
delete []PathToProcess1;
if ( NameProc1 )
delete []NameProc1;
}
return ExePath;
}
/*-------------------------------------------------------------
BaseFileNamePtr(const char *full_name)
Get the address of the base file name
from a string which may contain a path
Returns a pointer to the base file name
Calling parameters
full_name the name of the file
Win API functions used
none
Other functions used
strrchr
Globals and constants used
none
-------------------------------------------------------------*/
static char *WINAPI BaseFileNamePtr(const char *full_name)
{
char *p = strrchr((char *) full_name, '\\');
if ( p )
{
++p;
} else
{
p = (char *) full_name;
}
return p;
}
//---------------------------------------------------------------------------
//-------------------------------------------------------------
// ProcIDOrHwnd is a union used for communication
// with the Enum Windows procedure
//-------------------------------------------------------------
union ProcIDOrHwnd
{
DWORD proc_id;
HWND hwnd;
};
/*-------------------------------------------------------------
EWProc(HWND hwnd, LPARAM l)
Service procedure for an EnumWindows call
Compare the process id for the owner of the
window to that passed by the caller and
if they match, save the window handle in the
union whose address is the calling parameter
Calling parameters
hwnd handle of a window that was found
by the EnumWindows function
l address of a ProcIDOrHwnd union
which contains the process id of the
window to be found
On return the union's hwnd member will be the
handle of the found window. If none was found
then it will be the process id.
Win API functions used
GetWindowThreadProcessId
Other functions used
none
Globals and constants used
none
-------------------------------------------------------------*/
static BOOL EWProc(HWND hwnd, LPARAM l)
{
DWORD proc_id;
ProcIDOrHwnd *pih = reinterpret_cast<ProcIDOrHwnd*>(l);
GetWindowThreadProcessId(hwnd, &proc_id);
if ( proc_id == pih->proc_id )
{
pih->hwnd = hwnd;
return FALSE;
}
return TRUE;
}
/*---------------------------------------------------------------------------
WindowFromFile(const char *file_name)
Find a window which was created by a program
whose file name is given
Calling arguments
file_name The name of the file. It may
contain a path, but the path
part is not used.
Returns the HWND of the window which was found
or NULL if no window was found
Windows API functions used
CreateToolhelp32Snapshot
Process32First
Process32Next
CloseHandle
EnumWindows
Other functions used
BaseFileNamePtr
stricmp
Globals and constants used
none
-------------------------------------------------------------*/
HWND WINAPI WindowFromFileName(AnsiString ExeName)
{
HWND found_hwnd = NULL;
HANDLE snap_hand =
CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if ( (int) snap_hand != -1 )
{
DWORD proc_id = 0;
PROCESSENTRY32 pe32;
char *base_file_name = BaseFileNamePtr(ExeName.c_str());
OutputDebugString(base_file_name);
pe32.dwSize = sizeof(pe32);
// cycle through each process
if ( Process32First(snap_hand, &pe32) )
{
do
{
char *base_name = BaseFileNamePtr(pe32.szExeFile);
// if the process' file name is the same capture
// the process id and break out of the loop
if ( !stricmp(base_file_name, base_name) )
{
proc_id = pe32.th32ProcessID;
break;
}
} while ( Process32Next(snap_hand, &pe32) );
CloseHandle(snap_hand);
}
// if a process id was found
if ( proc_id )
{
ProcIDOrHwnd pih;
pih.proc_id = proc_id;
// find a window owned by that process
EnumWindows((WNDENUMPROC)(EWProc), reinterpret_cast<LPARAM>(&pih));
// if a window was found
if ( pih.proc_id != proc_id )
{
found_hwnd = pih.hwnd; // save the window handle to return to caller
}
}
}
return found_hwnd;
}
//---------------------------------------------------------------------------
void __fastcall LaunchApplication(AnsiString ExeName, bool wait)
{
String CmdLine = ExeName;
if ( !FileExists(CmdLine) )
{
MessageDlg(CmdLine +AnsiString(" does not exist!"), mtError, TMsgDlgButtons() << mbOK, 0);
return;
}
Application->ProcessMessages();
// initialize STARTUPINFO struct
STARTUPINFO si;
memset(&si, 0, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOWNORMAL;
PROCESS_INFORMATION ProcessInfo;
if ( CreateProcess
(
NULL, // pointer to name of executable module
CmdLine.c_str(), // pointer to command line string
NULL, // pointer to process security attributes
NULL, // pointer to thread security attributes
true, // handle inheritance flag
NORMAL_PRIORITY_CLASS, // creation flags
NULL, // pointer to new environment block
ExtractFilePath(Application->ExeName).c_str(), // pointer to current directory name
&si, // pointer to STARTUPINFO
&ProcessInfo // pointer to PROCESS_INFORMATION
) )
{ // body of the if...
if ( wait )
WaitForSingleObject(ProcessInfo.hProcess, 20000); // Wait for it to be ready
Application->ProcessMessages();
CloseHandle(ProcessInfo.hProcess); // done with these
CloseHandle(ProcessInfo.hThread);
}
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
BOOL CALLBACK TerminateAppEnum( HWND hwnd, LPARAM lParam )
{
DWORD dwID ;
GetWindowThreadProcessId(hwnd, &dwID) ;
if ( dwID == (DWORD)lParam )
{
PostMessage(hwnd, WM_CLOSE, 0, 0) ;
}
return TRUE ;
}
/*----------------------------------------------------------------
DWORD WINAPI TerminateApp( DWORD dwPID, DWORD dwTimeout )
Purpose: Shut down a 32-Bit Process (or 16-bit process under Win95)
Parameters: dwPID Process ID of the process to shut down.
dwTimeout Wait time in milliseconds before shutting down process.
Return Value:
TA_FAILED - If the shutdown failed.
TA_SUCCESS_CLEAN - If the process was shutdown using WM_CLOSE.
TA_SUCCESS_KILL - if the process was shut down with TerminateProcess().
NOTE: See header for these defines.
---------------------------------------------------------------------------*/
DWORD WINAPI TerminateApp( DWORD dwPID, DWORD dwTimeout )
{
HANDLE hProc ;
DWORD dwRet ;
// If we can't open the process with PROCESS_TERMINATE rights,
// then we give up immediately.
hProc = OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, dwPID);
if ( hProc == NULL )
{
return TA_FAILED ;
}
// TerminateAppEnum() posts WM_CLOSE to all windows whose PID
// matches your process's.
EnumWindows((WNDENUMPROC)TerminateAppEnum, (LPARAM) dwPID) ;
// Wait on the handle. If it signals, great. If it times out,
// then you kill it.
if ( WaitForSingleObject(hProc, dwTimeout)!=WAIT_OBJECT_0 )
dwRet=(TerminateProcess(hProc,0)?TA_SUCCESS_KILL:TA_FAILED);
else
dwRet = TA_SUCCESS_CLEAN ;
CloseHandle(hProc);
return dwRet ;
}
//---------------------------------------------------------------------------
--
-Michael Gillen
 

{smallsort}

Re:Spawning and controlling

Thanks, I didn't know about access().
The stumbling block here was to find the HWND from the process information
so I could send a close message. I gather I must enumerate all running
processes to find the process id then get the handle.
And I thought it would be easy!
Thanks for taking the trouble to reply,
Sincerely
Denville.
"Bob Gonder" < XXXX@XXXXX.COM >wrote in message
Quote
Denville Longhurst wrote:

>1. Check whether foo.exe is already running so that I don't attempt to run
>it twice;

Use acess() to check if the file is writable.
When the program is running, it is not writable.
If the file is marked as read-only, or resides on a CD, then this
method will fail.

>2. Spawn foo.exe

Use CreateProcess()

>4. From my app, terminate foo.exe

CreateProcess() returns handles that can be used to terminate the
process.


 

Re:Spawning and controlling

"Denville Longhurst" < XXXX@XXXXX.COM >wrote:
Quote
Thanks, I didn't know about access().

The stumbling block here was to find the HWND from the process information
so I could send a close message. I gather I must enumerate all running
processes to find the process id then get the handle.
Well, if you're doing that, then you might as well find the executable
name for the process as well. (Given that access() may or may not be
very useful at all - it's not as though the only reason you wouldn't
able to write to a file be that it is a running program.)
Alan Bellingham
--
Team Thai Kingdom
<url:www.borland.com/newsgroups/>Borland newsgroup descriptions
<url:www.borland.com/newsgroups/netiquette.html>netiquette
 

Re:Spawning and controlling

Thanks again
Denville
"Alan Bellingham" < XXXX@XXXXX.COM >wrote in message
Quote
"Denville Longhurst" < XXXX@XXXXX.COM >wrote:

>Thanks, I didn't know about access().
>
>The stumbling block here was to find the HWND from the process information
>so I could send a close message. I gather I must enumerate all running
>processes to find the process id then get the handle.

Well, if you're doing that, then you might as well find the executable
name for the process as well. (Given that access() may or may not be
very useful at all - it's not as though the only reason you wouldn't
able to write to a file be that it is a running program.)

Alan Bellingham
--
Team Thai Kingdom
<url:www.borland.com/newsgroups/>Borland newsgroup descriptions
<url:www.borland.com/newsgroups/netiquette.html>netiquette
 

Re:Spawning and controlling

Good grief !!
Well, thanks for that, I'll work my way through it
Most sincerely,
Denville.
"Michael Gillen" < XXXX@XXXXX.COM >wrote in message
Quote
Denville Longhurst wrote:

>Hi
>
>From within my application, I would like to spawn an arbitrary third
>party application (say
>foo.exe) in the following way:
>
>1. Check whether foo.exe is already running so that I don't attempt to
>run it twice;
>2. Spawn foo.exe
>3. Make foo's parent my application, so that it displays within one of my
>windows;
>4. From my app, terminate foo.exe
>
>I can probably cope with (3), but I am at a loss about how to do the
>rest.


This bunch of code should give you the needed tools. This requires Win2000
or better, however,
since I never implemented backwards compatability.


/*********** PROCCONTROL.H *************/
#ifndef ProcControlH
#define ProcControlH

#include <vcl.h>
#include <Wbemcli.h>
#include <tlhelp32.h>

#define TA_FAILED 0
#define TA_SUCCESS_CLEAN 1
#define TA_SUCCESS_KILL 2
#define TA_SUCCESS_16 3


int __fastcall TerminateAppByName(AnsiString ExeName, int timeout = 2000);
bool __fastcall IsProcessRunning(AnsiString ExeName);
AnsiString __fastcall GetProcessFilePath(AnsiString ExeName);
HWND WINAPI WindowFromFileName(AnsiString ExeName);
void __fastcall LaunchApplication(AnsiString ExeName, bool wait = false);


//---------------------------------------------------------------------------
#endif

/*********** PROCCONTROL.CPP *************/
#include "ProcControl.h"
#include "utilcls.h"

IWbemLocator *pLoc;
IWbemServices *pSvc;
IEnumWbemClassObject *pEnum;
IWbemClassObject *pProcesses;

typedef struct
{
DWORD dwID ;
DWORD dwThread ;
} TERMINFO ;

// Declare Callback Enum Functions.
BOOL CALLBACK TerminateAppEnum( HWND hwnd, LPARAM lParam ) ;
BOOL CALLBACK Terminate16AppEnum( HWND hwnd, LPARAM lParam ) ;


DWORD WINAPI TerminateApp( DWORD dwPID, DWORD dwTimeout ) ;
DWORD WINAPI Terminate16App( DWORD dwPID, DWORD dwThread, WORD w16Task,
DWORD dwTimeout );

//---------------------------------------------------------------------------
// IsProgramRunning(AnsiString exefile)
// Determine if program 'exefile' is running.
//---------------------------------------------------------------------------
bool __fastcall IsProcessRunning(AnsiString ExeName)
{
HANDLE hSnap;
PROCESSENTRY32 process;
BOOL f;

hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if ( hSnap == NULL )
return false; // NOT RUNNING!!

process.dwSize = sizeof(PROCESSENTRY32);
f = Process32First(hSnap, &process);

while ( f )
{
AnsiString file(ExtractFileName(process.szExeFile));
if ( file.AnsiCompareIC(ExeName) == 0 )
{
CloseHandle(hSnap);
return true; // PROGRAM IS RUNNING!
}
f = Process32Next(hSnap, &process);
}
CloseHandle(hSnap);
return false; // NOT RUNNING!!
}

//---------------------------------------------------------------------------
// IsProgramRunning(AnsiString exefile)
// Determine if program 'exefile' is running.
// Return the full path to the executable if it IS running, else NULL.
//---------------------------------------------------------------------------
int __fastcall TerminateAppByName(AnsiString ExeName, int timeout)
{
DWORD dwID = 0;
GetWindowThreadProcessId(WindowFromFileName(ExeName), &dwID) ;
int ret = TerminateApp( dwID, timeout );
return ret;
/*
if(ret == TA_FAILED)
OutputDebugString("The shutdown failed");
if(ret == TA_SUCCESS_CLEAN)
OutputDebugString("The process was shutdown using WM_CLOSE.");
if(ret == TA_SUCCESS_KILL)
OutputDebugString("The process was shut down with TerminateProcess().");
*/
}

//---------------------------------------------------------------------------
bool __fastcall InitCom()
{
HRESULT hres;

hres = CoInitializeEx(0, COINIT_MULTITHREADED); //Initialize COM.

if ( FAILED(hres) )
{
ShowMessage("Failed to initialize COM library. Error code =
"+IntToHex((int)hres,8));
return false;
}

hres = CoInitializeSecurity(
NULL, // security descriptor
-1, // use this simple setting
NULL, // use this simple setting
NULL, // reserved
RPC_C_AUTHN_LEVEL_CONNECT, // Windows NT 4/Windows 2000 authentication
level
RPC_C_IMP_LEVEL_IMPERSONATE, // impersonation level
NULL, // use this simple setting
EOAC_NONE, // no special capabilities
0); // reserved

if ( FAILED(hres) )
{
ShowMessage("Failed to initialize security. Error code =
"+IntToHex((int)hres,8));
CoUninitialize();
return false;
}
return true;
}

//---------------------------------------------------------------------------
AnsiString __fastcall GetProcessFilePath(AnsiString ExeName)
{
AnsiString ExePath = NULL;

HRESULT hres;
pLoc = 0;

//IWbemLocator interface for obtaining the initial namespace pointer to
//the Windows Management on a particular host computer.
hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID *)
&pLoc);

if ( FAILED(hres) )
{
ShowMessage("Failed to create IWbemLocator object. Err code =
"+IntToHex((int)hres,8));
CoUninitialize();
return NULL;
}

pSvc = 0;
hres = pLoc->ConnectServer(L"\\\\.\\root\\cimv2", NULL, NULL, 0, NULL, 0,
0, &pSvc);

if ( FAILED(hres) )
{
ShowMessage("Could not connect. Error code = "+IntToHex((int)hres,8));
CoUninitialize();
return NULL;
}

// Set the proxy so that impersonation of the client occurs.
hres = CoSetProxyBlanket(pSvc,
RPC_C_AUTHN_WINNT, // NTLM authentication service
RPC_C_AUTHZ_NONE, // default authorization service...
NULL, // no mutual authentication
RPC_C_AUTHN_LEVEL_CONNECT, // authentication level
RPC_C_IMP_LEVEL_IMPERSONATE, // impersonation level
NULL, // use current token
EOAC_NONE); // no special capabilities



if ( FAILED(hres) )
{
ShowMessage("Could not set proxy blanket. Error code =
"+IntToHex((int)hres,8));
pSvc->Release();
pLoc->Release();
CoUninitialize();
return NULL;
}

BSTR className = SysAllocString(L"Win32_Process");

hres = pSvc->GetObject(className, 0, NULL, &pProcesses, NULL );
//Retrieves an class object.

ULONG puReturned;

//Create instance for enumeration ports

hres=pSvc->CreateInstanceEnum( className, NULL, NULL, &pEnum );

//no need in variable className now.
SysFreeString(className);

if ( hres != 0 )
{
ShowMessage("Error");
return NULL;
}

// Retrieve the objects in the result set.
for ( ;; )
{

ULONG uReturned = 0;

hres = pEnum->Next(
WBEM_INFINITE, // Time out
1, // One object
&pProcesses,
&uReturned
);

if ( uReturned == 0 )
{
break;
}

IWbemClassObject *pObj1;

VARIANT Val;
VARIANT Val1;
VARIANT Val2;
VARIANT Val3;
VariantInit(&Val);
VariantInit(&Val1);
VariantInit(&Val2);
VariantInit(&Val3);

CIMTYPE pvtType;
BSTR Name1 = SysAllocString(L"ExecutablePath");
BSTR Name2 = SysAllocString(L"Name");
BSTR Name3 = SysAllocString(L"Handle");
LPSTR PathToProcess1=0;
LPSTR NameProc1=0;
LPSTR Handle1=0;


hres=pProcesses->Get(Name1,0,&Val1,&pvtType,NULL);

if ( Val1.vt == VT_NULL )
PathToProcess1="UNKNOWN";
else
PathToProcess1=WideToAnsi(Val1.bstrVal);


hres=pProcesses->Get(Name2,0,&Val2,&pvtType,NULL);
if ( Val2.vt == VT_NULL )
NameProc1="UNKNOWN";
else
NameProc1=WideToAnsi(Val2.bstrVal);

hres=pProcesses->Get(Name3,0,&Val3,&pvtType,NULL);
if ( Val3.vt == VT_NULL )
continue;
else
Handle1=WideToAnsi(Val3.bstrVal);

SysFreeString(Name1);
SysFreeString(Name2);
SysFreeString(Name3);
VariantClear(&Val);
VariantClear(&Val1);
VariantClear(&Val2);
VariantClear(&Val3);

if ( !stricmp(NameProc1, ExeName.c_str()) )
ExePath = PathToProcess1;

if ( Handle1 )
delete []Handle1;
if ( PathToProcess1 && (AnsiString(PathToProcess1) != "UNKNOWN") )
delete []PathToProcess1;
if ( NameProc1 )
delete []NameProc1;

}
return ExePath;
}

/*-------------------------------------------------------------
BaseFileNamePtr(const char *full_name)

Get the address of the base file name
from a string which may contain a path

Returns a pointer to the base file name

Calling parameters
full_name the name of the file

Win API functions used
none

Other functions used
strrchr

Globals and constants used
none
-------------------------------------------------------------*/
static char *WINAPI BaseFileNamePtr(const char *full_name)
{
char *p = strrchr((char *) full_name, '\\');

if ( p )
{
++p;
} else
{
p = (char *) full_name;
}

return p;
}
//---------------------------------------------------------------------------

//-------------------------------------------------------------
// ProcIDOrHwnd is a union used for communication
// with the Enum Windows procedure
//-------------------------------------------------------------
union ProcIDOrHwnd
{
DWORD proc_id;
HWND hwnd;
};

/*-------------------------------------------------------------
EWProc(HWND hwnd, LPARAM l)

Service procedure for an EnumWindows call
Compare the process id for the owner of the
window to that passed by the caller and
if they match, save the window handle in the
union whose address is the calling parameter

Calling parameters
hwnd handle of a window that was found
by the EnumWindows function
l address of a ProcIDOrHwnd union
which contains the process id of the
window to be found

On return the union's hwnd member will be the
handle of the found window. If none was found
then it will be the process id.

Win API functions used
GetWindowThreadProcessId

Other functions used
none

Globals and constants used
none
-------------------------------------------------------------*/
static BOOL EWProc(HWND hwnd, LPARAM l)
{
DWORD proc_id;
ProcIDOrHwnd *pih = reinterpret_cast<ProcIDOrHwnd*>(l);

GetWindowThreadProcessId(hwnd, &proc_id);

if ( proc_id == pih->proc_id )
{
pih->hwnd = hwnd;
return FALSE;
}

return TRUE;
}
/*---------------------------------------------------------------------------
WindowFromFile(const char *file_name)

Find a window which was created by a program
whose file name is given

Calling arguments
file_name The name of the file. It may
contain a path, but the path
part is not used.

Returns the HWND of the window which was found
or NULL if no window was found

Windows API functions used
CreateToolhelp32Snapshot
Process32First
Process32Next
CloseHandle
EnumWindows

Other functions used
BaseFileNamePtr
stricmp

Globals and constants used
none
-------------------------------------------------------------*/
HWND WINAPI WindowFromFileName(AnsiString ExeName)
{
HWND found_hwnd = NULL;
HANDLE snap_hand =
CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if ( (int) snap_hand != -1 )
{
DWORD proc_id = 0;
PROCESSENTRY32 pe32;
char *base_file_name = BaseFileNamePtr(ExeName.c_str());
OutputDebugString(base_file_name);

pe32.dwSize = sizeof(pe32);

// cycle through each process
if ( Process32First(snap_hand, &pe32) )
{
do
{
char *base_name = BaseFileNamePtr(pe32.szExeFile);

// if the process' file name is the same capture
// the process id and break out of the loop
if ( !stricmp(base_file_name, base_name) )
{
proc_id = pe32.th32ProcessID;
break;
}
} while ( Process32Next(snap_hand, &pe32) );

CloseHandle(snap_hand);
}

// if a process id was found
if ( proc_id )
{
ProcIDOrHwnd pih;
pih.proc_id = proc_id;
// find a window owned by that process
EnumWindows((WNDENUMPROC)(EWProc), reinterpret_cast<LPARAM>(&pih));

// if a window was found
if ( pih.proc_id != proc_id )
{
found_hwnd = pih.hwnd; // save the window handle to return to caller
}
}
}
return found_hwnd;
}
//---------------------------------------------------------------------------
void __fastcall LaunchApplication(AnsiString ExeName, bool wait)
{
String CmdLine = ExeName;
if ( !FileExists(CmdLine) )
{
MessageDlg(CmdLine +AnsiString(" does not exist!"), mtError,
TMsgDlgButtons() << mbOK, 0);
return;
}

Application->ProcessMessages();

// initialize STARTUPINFO struct
STARTUPINFO si;
memset(&si, 0, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOWNORMAL;
PROCESS_INFORMATION ProcessInfo;
if ( CreateProcess
(
NULL, // pointer to name of executable module
CmdLine.c_str(), // pointer to command line string
NULL, // pointer to process security attributes
NULL, // pointer to thread security attributes
true, // handle inheritance flag
NORMAL_PRIORITY_CLASS, // creation flags
NULL, // pointer to new environment block
ExtractFilePath(Application->ExeName).c_str(), // pointer to current
directory name
&si, // pointer to STARTUPINFO
&ProcessInfo // pointer to PROCESS_INFORMATION
) )
{ // body of the if...
if ( wait )
WaitForSingleObject(ProcessInfo.hProcess, 20000); // Wait for it to be
ready
Application->ProcessMessages();
CloseHandle(ProcessInfo.hProcess); // done with these
CloseHandle(ProcessInfo.hThread);
}
}
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
BOOL CALLBACK TerminateAppEnum( HWND hwnd, LPARAM lParam )
{
DWORD dwID ;

GetWindowThreadProcessId(hwnd, &dwID) ;

if ( dwID == (DWORD)lParam )
{
PostMessage(hwnd, WM_CLOSE, 0, 0) ;
}

return TRUE ;
}
/*----------------------------------------------------------------
DWORD WINAPI TerminateApp( DWORD dwPID, DWORD dwTimeout )

Purpose: Shut down a 32-Bit Process (or 16-bit process under Win95)
Parameters: dwPID Process ID of the process to shut down.
dwTimeout Wait time in milliseconds before shutting down process.
Return Value:
TA_FAILED - If the shutdown failed.
TA_SUCCESS_CLEAN - If the process was shutdown using WM_CLOSE.
TA_SUCCESS_KILL - if the process was shut down with TerminateProcess().
NOTE: See header for these defines.
---------------------------------------------------------------------------*/
DWORD WINAPI TerminateApp( DWORD dwPID, DWORD dwTimeout )
{
HANDLE hProc ;
DWORD dwRet ;

// If we can't open the process with PROCESS_TERMINATE rights,
// then we give up immediately.
hProc = OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, dwPID);

if ( hProc == NULL )
{
return TA_FAILED ;
}

// TerminateAppEnum() posts WM_CLOSE to all windows whose PID
// matches your process's.
EnumWindows((WNDENUMPROC)TerminateAppEnum, (LPARAM) dwPID) ;

// Wait on the handle. If it signals, great. If it times out,
// then you kill it.
if ( WaitForSingleObject(hProc, dwTimeout)!=WAIT_OBJECT_0 )
dwRet=(TerminateProcess(hProc,0)?TA_SUCCESS_KILL:TA_FAILED);
else
dwRet = TA_SUCCESS_CLEAN ;
CloseHandle(hProc);
return dwRet ;
}
//---------------------------------------------------------------------------

--
-Michael Gillen