How do I find out if a .exe is running in c++? - c++

How can you find out if an executable is running on Windows given the process name, e.g. program.exe?

The C++ standard library has no such support. You need an operating system API to do this. If this is Windows then you'd use CreateToolhelp32Snapshot(), followed by Process32First and Process32Next to iterate the running processes. Beware of the inevitable race condition, the process could have exited by the time you found it.

I just created one using Hans suggestion. Works like a champ!
Oh and here is the basic code.
Please you will have to add CStrings sAppPath and sAppName.
StartProcess is a small function that uses CreateProcess and returns the PID(not used here). You will need to replace it.
This is not a complete program, just the code to find if the program is running using Hans suggestion. A fun test is to set the path to c:\windows\ and the app to notepad.exe and set it for 10 seconds.
#include <tlhelp32.h>
PROCESSENTRY32 pe32 = {0};
HANDLE hSnap;
int iDone;
int iTime = 60;
bool bProcessFound;
while(true) // go forever
{
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
pe32.dwSize = sizeof(PROCESSENTRY32);
Process32First(hSnap,&pe32); // Can throw away, never an actual app
bProcessFound = false; //init values
iDone = 1;
while(iDone) // go until out of Processes
{
iDone = Process32Next(hSnap,&pe32);
if (strcmp(pe32.szExeFile,sAppName) == 0) // Did we find our process?
{
bProcessFound = true;
iDone = 0;
}
}
if(!bProcessFound) // if we didn't find it running...
{
startProcess(sAppPath+sAppName,""); // start it
}
Sleep(iTime*1000); // delay x amount of seconds.
}

Assumptions: since you mention '.exe', you want this for some flavor of Windows. You want to write a program in C++ to determine whether a program with a particular executable name is running (regardless of the language used to implement the target program).
Enumerate the running processes using either the Toolhelp API or the process status API. Compare the name of the executable for each running process to the one you're looking for (and be aware that there may be more than one process with that executable name).

hProcessInfo = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID );
do{
if(strcmp(pe32.szExeFile,"process.exe") == 0)
{
processfound = true;
break;
}
}while( Process32Next( hProcessSnap, &pe32 ) );
If you don't want to get process detail from code just press Ctrl+Alt+Del and check process list.

Related

Windows limit CPU usage using JobObject not working on all computers

I am using JobObject to limit my process cpu usage. I am running my code on two computers running windows 10. On one machine it's working but on the other it's not working although all WINAPI calls return successfully. This my code:
string jobName = "test_job";
HANDLE hJobObject = NULL;
hJobObject = CreateJobObject(NULL, jobName.c_str());
if (hJobObject == NULL) {
return -1;
}
JOBOBJECT_CPU_RATE_CONTROL_INFORMATION cpuRateInfo;
cpuRateInfo.ControlFlags = JOB_OBJECT_CPU_RATE_CONTROL_ENABLE | JOB_OBJECT_CPU_RATE_CONTROL_HARD_CAP;
cpuRateInfo.CpuRate = 10 * 100;
if (!SetInformationJobObject(hJobObject, JobObjectCpuRateControlInformation, &cpuRateInfo, sizeof(JOBOBJECT_CPU_RATE_CONTROL_INFORMATION))) {
return -1;
}
HANDLE currentProcessHandle = GetCurrentProcess();
if (!AssignProcessToJobObject(hJobObject, currentProcessHandle)) {
return -1;
}
Any idea what cause this issue?
You should first verify that the current process works under an existing job control.
Add these lines of codeļ¼š
BOOL bInJob = FALSE;
IsProcessInJob(GetCurrentProcess(),NULL,&bInJob);
if (bInJob)
{
MessageBox(NULL,L"Process is in Job!",TEXT(""),MB_ICONINFORMATION | MB_OK);
return 0;
}
Since a process belongs to one job object, it cannot be assigned to another job object.
In addition, In Windows-enabled UAC systems, processes without
prompt privileges are added to a default compatibility system
JobObject, so a process must be created using the
CREATE_BREAKAWAY_FROM_JOB parameter to separate the process from the
default JobObject.
Hope to help you.

winsock and new thread does not release memory

I have a really strange problem. Looking for the cause on the web and try everything. Nothing helps.
First case:
(This works exactly as expected. Windows task manager shows the constant memory size, and does not increase.)
unsigned long WINAPI thfun(void * arg)
{
::Sleep(50);
::ExitThread(0);
return 0;
}
int main(int argc, const wchar_t ** argv)
{
HANDLE th = 0;
DWORD thid, err;
while (true)
{
th = ::CreateThread(0, 0, thfun, 0, 0, &thid);
if (!th)
{
err = ::GetLastError();
}
::WaitForSingleObject(th, INFINITE);
}
return 0;
}
Second case:
unsigned long WINAPI thfun(void * arg)
{
::Sleep(50);
::ExitThread(0);
return 0;
}
int main(int argc, const wchar_t ** argv)
{
WORD ver;
WSADATA wsadata;
ver = MAKEWORD(2, 2);
if (WSAStartup(ver, &wsadata)) return 1;
::Sleep(50);
HANDLE th = 0;
DWORD thid, err;
while (true)
{
th = ::CreateThread(0, 0, thfun, 0, 0, &thid);
if (!th)
{
err = ::GetLastError();
}
::WaitForSingleObject(th, INFINITE);
}
return 0;
}
If I call any function from winsock least once created threads do not release memory.
Windows task manager shows ever-growing memory of my application.
What should I do so that I achieve the same behavior as in the first case when I use winsock?
I use visual studio 2013
Thank you very much for any help
You do not close your thread handles. A common error.
Your core loop should look like that:
while (true)
{
th = ::CreateThread(0, 0, thfun, 0, 0, &thid);
if (!th)
{
err = ::GetLastError();
}
::WaitForSingleObject(th, INFINITE);
CloseHandle(th);
}
That problem exists in both of your examples. That memory grow of the second sample can be a side effect.
ExitThread(0) is never a good idea and I do not understand why Microsoft recommand it for C. As the Winsock API should not have any destructor, it should not be a problem. Nevertheless, do not use it.
UPDATE
I tested your code as release on a Windows 7 64bit SP1 System with Antivira personal installed (my gaming machine). Also on my Windows 8 VM (parallels). Both system did not show the problems you described and show in your video. This is IMHO good news for you, because it seems a problem of your installation and not a general problem.
The video shows a leak of only a few bytes per ended thread and strict linear growing per thread. This looks for me like thread associated information, usually stored nowadays in TLS (Thread Local Storage). Also it only appears when you init The WSASocket system. If the WSASocket system itself would be the problem, we would found reports of it for sure(but I didn't). I believe a hook DLL is causing that problem, a DLL is informed over the DllMain of any started or ended thread of the process. Any virus scanner or keyboard addon(!) can cause such a problem as they usually use hook DLLs and manipulate IOs like pipes and sockets.
Unfortunatly I only know one way to find out:
Make a release canditate of your sample. Make sure the problem exist.
Make a clean install of Windows 7
Install step by step the environment you use on your produktive system. Make sure you restart the Computer after every step.
Hopefully find the culprit.
Deactivating or uninstall hooks may help but need not. Unfortunately installing programs on windows system is maximal inversive.
Sorry for not heaving the easy answer.

Why does GetProcessImageFileName return null instead of the address of the process?

I am trying to pool the list of all processes in Qt.For this purpose i am using Windows API.
the following code demonstrates my effort so far:
QList<QString> frmProcess::GetAllRunningProcesses()
{
HANDLE hSysSnapshot = NULL;
HANDLE processHandle;
PROCESSENTRY32 proc;
proc.dwSize = sizeof(proc);
hSysSnapshot = CreateToolhelp32Snapshot ( TH32CS_SNAPPROCESS, 0 );
Process32First(hSysSnapshot,&proc);
proc.dwSize = sizeof(proc);
ui->listWidget->clear();
LPWSTR processPath;
list.clear();
do
{
//This block of code is to get each process's path and store it in a list
//PROCESS_ALL_ACCESS is commented out since it fails the program on start-up
processHandle = OpenProcess( /*PROCESS_ALL_ACCESS*/PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, proc.th32ProcessID );
GetProcessImageFileName(processHandle,processPath,MAX_PATH);
procpaths.append(QString::fromWCharArray(processPath));
list.append(QString::fromWCharArray(proc.szExeFile));
} while(Process32Next(hSysSnapshot,&proc));
CloseHandle( hSysSnapshot );
return list;
}
In the code posted above, I am trying to get as much as information i can get on a process, for this i am pooling the process names with the help of CreateToolhelp32Snapshot and then get their path with GetProcessImageFileName. And all of this happen in a timer tick event each milliseconds.
If i run the program , after couple of seconds it crashes, I get segmentation fault.
I also tried debugging since i couldn't get any path relating to any process!
And to my surprise i only get empty strings for path of each process!
What am i doing wrong?
Your GetProcessImageFileName does not receive a proper argument. processPath has to point to valid buffer.
TCHAR processPath[MAX_PATH] = { 0 };
GetProcessImageFileName(processHandle, processPath, _countof(processPath));
Also, you want to check returned value to see if you succeeded or not.

C++ Interrupts?

I was wondering if C++ had any way of doing interrupts. I want one program to store information in a text file, while the other one prints a statement depending on what is in the text file. Since I want it to be as accurate as possible, I need the print program to be interrupted when the update program updates the file.
C++ itself doesn't give this capability, it knows nothing of other programs that may or may not be running.
What you need to look into is IPC (inter-process communications), something your operating system will probably provide.
Things like signals, shared memory, semaphores, message queues and so on.
Since you seem to be using the file itself as the method of delivering content to the other process, signals are probably the way to go. You would simply raise a signal from process A to process B and a signal handler would run in the latter.
Of course this all depends on which operating system you're targeting.
If you are using Windows you can use FindFirstChangeNotification.
Here's some old code I have. This is run in it's own thread:
DWORD CDiskWatcher::Run(void *vpParameter)
{
CFileNotifyInterface *pIface = (CFileNotifyInterface *)vpParameter;
HANDLE handles[2];
handles[0] = m_hQuitEvent;
handles[1] = ::FindFirstChangeNotification(m_szPath, FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE|FILE_NOTIFY_CHANGE_FILE_NAME);
DWORD dwObject;
if (INVALID_HANDLE_VALUE != handles[1]) {
do {
// Wait for the notification
dwObject = ::WaitForMultipleObjects(2, handles, FALSE, INFINITE);
if (WAIT_OBJECT_0 + 1 == dwObject) {
// Continue waiting...
::FindNextChangeNotification(handles[1]);
pIface->FireFileSystemChange(m_szPath);
}
} while (WAIT_OBJECT_0 != dwObject);
// Close handle
::FindCloseChangeNotification(handles[1]);
}
return 0;
}
Note m_hQuitEvent is created with CreateEvent() and CFileNotifyInterface is for callbacks:
class CFileNotifyInterface
{
public:
virtual void FireFileSystemChange(const char *szPath) = 0;
};

Close handle to a mutex in another process

I want to close a handle to a mutex located in another process, so I can run more than one instance of the application.
I already know this can be done, see Process Explorer. Example: Windows Minesweeper (Windows 7) uses a mutex to only allow one game, so I thought I would use it as an example since it's pre-installed with Windows and therefore easier for you guys to guide me.
The mutex that I need to close is \Sessions\1\BaseNamedObjects\Oberon_Minesweeper_Singleton, which I found using Process Explorer.
After closing this mutex I was able to launch two games of Minesweeper, but I want to do this in my program using C++.
After some searching I have found that I might need the API DuplicateHandle. So far I haven't been able to close the handle on this mutex.
Here is my code so far:
#include <Windows.h>
#include <iostream>
using namespace std;
void printerror(LPSTR location){
printf("Error: %s_%d", location, GetLastError());
cin.get();
}
int main(){
DWORD pid = 0;
HWND hMineWnd = FindWindow("Minesweeper", "Minesveiper");
GetWindowThreadProcessId(hMineWnd, &pid);
HANDLE hProc =OpenProcess(PROCESS_DUP_HANDLE, 0, pid);
if(hProc == NULL){
printerror("1");
return 1;
}
HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, TRUE, "Oberon_Minesweeper_Singleton");
if(hMutex == NULL){
printerror("2");
return 2;
}
if(DuplicateHandle(hProc, hMutex, NULL, 0, 0, FALSE, DUPLICATE_CLOSE_SOURCE) == 0){
printerror("3");
return 3;
}
if(CloseHandle(hMutex) == 0){
printerror("4");
return 4;
}
return 0;
}
This code returns 0, but the mutex is still there, and I am not able to launch more games of Minesweeper. I think some of my parameters to DuplicateHandle are wrong.
The second argument to DuplicateHandle expects "an open object handle that is valid in the context of the source process", however I believe the handle you're passing in would only be valid within the current process (OpenMutex creates a new handle to an existing mutex object). You'll likely need to determine what the mutex's handle is in the remote process, and use that value when calling DuplicateHandle.