Getting compilation error for "tlhelp32.h" in MinGW g++ compiler - c++

I am writing a simple C++ app that checks whether a given exe file example:'a.exe' is running or not(windows OS), I have googled and found some code in the below link.
http://stackoverflow.com/questions/3355379/how-do-i-find-out-if-a-exe-is-running-in-c
The code mentioned above uses a header file "tlhelp32.h". I just copied the code and did some necessary changes then complied it in MinGW , there comes the next problem, all of the datatypes mentioned in that header files are errored out
ex: 'DWORD' does not name a type, 'LONG' does not name a type, 'WCHAR' does not name a type,'CHAR' does not name a type
I never faced this kind of issues before where an existed header file is failed to compile (yes it exist I've checked it).
really appreciate any help on this.
code below:
#include <tlhelp32.h>
int main()
{
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,"a.exe") == 0) // Did we find our process?
{
bProcessFound = true;
iDone = 0;
}
}
if(!bProcessFound) // if we didn't find it running...
{
startProcess("C:\\MinGW\\"+"a.exe",""); // start it
}
Sleep(iTime*10); // delay x amount of seconds.
}
return 0;
}

As Richard Critten said adding "Windows.h" before "tlhelp32" resolves the issue and more over a function startprocess() in the above code has never existed so use shellexecute() to make it work
ex: ShellExecute(NULL, "open", "c:\MinGW\a.exe", NULL, NULL, SW_SHOWDEFAULT);

Related

How to get information about a file for programming on windows

In Linux, we can use the function stat() to get a file info, and use the type st.mode to judge the rights of the file before we can do some operation on it. In windows, I make a lot of attempts, but little help.
At first, I want to use the function GetSecurityInfo, but I can't get the handle argument. I did find some solutions, but they all need use fopen function which is exactly what I want to avoid. Becasue I want to not do anything substantial with the file until I can determine what permissions it has.
Then I try the GetFileSecurityA function, but useless. The following is my code, and I get an error code 998 from getlasterror
void GetFilesInfo(std::string& path)
{
char *path1 = new char[1024];
strcpy(path1, path.c_str());
SECURITY_INFORMATION FLAGS = ATTRIBUTE_SECURITY_INFORMATION;
PSECURITY_DESCRIPTOR file_security_descriptor = new char[1024];
LPDWORD minNeedWords = 0;
if(GetFileSecurityA(path1, FLAGS, file_security_descriptor, 1024, minNeedWords) == 0)
error_die("GetFileInfo");
else
std::cout << file_security_descriptor << std::endl;
}
The answer is as previous comments said. I answered the question for completion.
#include <Windows.h>
void main()
{
TCHAR FileName[] = {L"C:\\Users\\Path\\To\\FileName.extension" };
DWORD LengthNeeded = 0;
SECURITY_DESCRIPTOR* sp = (SECURITY_DESCRIPTOR*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,100);
BOOL rs = GetFileSecurity(FileName, ATTRIBUTE_SECURITY_INFORMATION, sp,100,&LengthNeeded);
if (!rs)
{
DWORD e = GetLastError();
//return;
}
HeapFree(GetProcessHeap(), 0,sp);
}

EnumProcesses - weird behaviour

I have some weird behaviour while using WIndows API function EnumProcesses()
I have a function to determine wether a process with a certain name is already running which delivery different results wether I open the .executable manually (doubleclick) or open it via shell.
When I open it via shell it detects its running only 1 time (itself) and all is fine. When I open it using doubleclick on the .exe file however the function is returning true (already running) because the loop lists me the same process twice.
For the following code-snipped it is to mention that:
this->thisExecutableFile
contains argv[0] (initialised from running the program) to get the own process-name as you can see here:
int main(int argc, char* argv[])
{
ClientUpdate* update = ClientUpdate::getInstance();
update->setThisExecutableFile(argv[0]);
if (update->clientUpdateProcessIsRunning() == false) {
...
My goal is to find out if another instance of this process is already running and in this case exit it.
Here is my code:
bool ClientUpdate::clientUpdateProcessIsRunning()
{
bool retVal = false;
uint16_t processCount = 0;
unsigned long aProcesses[1024], cbNeeded, cProcesses;
if(!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))
return false;
cProcesses = cbNeeded / sizeof(unsigned long);
for(unsigned int i = 0; i < cProcesses; i++) {
if (aProcesses[i] == 0) {
continue;
}
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, aProcesses[i]);
wchar_t buffer[50];
GetModuleBaseNameW(hProcess, 0, buffer, 50);
CloseHandle(hProcess);
std::wstring tempBuffer(buffer);
std::string tempStringBuffer(tempBuffer.begin(), tempBuffer.end());
boost::filesystem::path p(this->thisExecutableFile);
if(_strcmpi(p.filename().string().c_str(), tempStringBuffer.c_str()) == 0) {
processCount++;
if(processCount > 1) {
retVal = true;
break;
}
}
}
return retVal;
}
I know that the base-path is different when using doubleclick on the file or calling it via shell. (shell produces only filename while doubleclick passes entire path + filename into argv[0]) but I fixed that issue using
boost::filesystem::path p(this->thisExecutableFile);
p.fileName()
Which returns the correct filename (without path) in both cases I checked using print.
I am pretty puzzled why EnumProcesses() returns me the same file twice when calling the file via doubleclick instead of shell. Its not spawning two processed and in taskmanager I dont see anything like this either.
Is this a bug or I need to know something about the method I couldnt find in docs?
Thanks to the hint by Richard Critten I was able to fix it. My method is much smaller now and easier. (Also probably also alot more performant then scanning entire process-stack.) :D
Here is the solution
bool ClientUpdate::clientUpdateProcessIsRunning()
{
HANDLE hMutex = CreateMutexA(NULL, TRUE, "client-updater-mtx");
DWORD dwErr = GetLastError();
return dwErr == ERROR_ALREADY_EXISTS;
}
Thanks!

How do you run external programs with parameters without the cmd window showing up in Windows?

I just asked a question earlier today because I wanted to run an executable file that takes parameters from my C++ code and it wasn't working.
It works now, but I'm still having problems since I thought I was going the right way about this, but it seems like what I want to accomplish can't be done the way I'm approaching it...
This is my corrected code from my other question:
#include <stdlib.h>
#include <conio.h>
int main (){
system("\"\"C:\\Users\\Adam\\Desktop\\pdftotext\" -layout \"C:\\Users\\Adam\\Desktop\\week 4.pdf\"\"");
_getch();
}
which is me running "pdftotext -layout myfile.pdf" as if I was running it from a CMD window.
The thing is, I don't actually want the cmd to show up since I have a GUI interface on top of it and I want to display a nicer progress bar instead of seeing the windows pop-up for every file I need to parse.
I looked around and either I don't understand what I'm reading since I'm relatively new to C++, or I just didn't find what I was looking for. I found that using CreateProcess, I should be able to do this, but after copying some code I found somewhere else, the cmd window pops-up anyway.
I'd like it if someone could give me the name of a function I could use to accomplish something like this or if someone could give some example code for this small case in the code I posted since I'm not sure I understand everything as I should, being new to C++ and all.
Edit: As requested in a comment, the code for CreateProcess that I tried is what I found at this url:
http://www.goffconcepts.com/techarticles/development/cpp/createprocess.html
Which is (with my own parameters that I think should go there):
#include <windows.h>
#include <string>
#include <conio.h>
size_t ExecuteProcess(std::wstring FullPathToExe, std::wstring Parameters, size_t SecondsToWait)
{
size_t iMyCounter = 0, iReturnVal = 0, iPos = 0;
DWORD dwExitCode = 0;
std::wstring sTempStr = L"";
/* - NOTE - You should check here to see if the exe even exists */
/* Add a space to the beginning of the Parameters */
if (Parameters.size() != 0)
{
if (Parameters[0] != L' ')
{
Parameters.insert(0,L" ");
}
}
/* The first parameter needs to be the exe itself */
sTempStr = FullPathToExe;
iPos = sTempStr.find_last_of(L"\\");
sTempStr.erase(0, iPos +1);
Parameters = sTempStr.append(Parameters);
/* CreateProcessW can modify Parameters thus we allocate needed memory */
wchar_t * pwszParam = new wchar_t[Parameters.size() + 1];
if (pwszParam == 0)
{
return 1;
}
const wchar_t* pchrTemp = Parameters.c_str();
wcscpy_s(pwszParam, Parameters.size() + 1, pchrTemp);
/* CreateProcess API initialization */
STARTUPINFOW siStartupInfo;
PROCESS_INFORMATION piProcessInfo;
memset(&siStartupInfo, 0, sizeof(siStartupInfo));
memset(&piProcessInfo, 0, sizeof(piProcessInfo));
siStartupInfo.cb = sizeof(siStartupInfo);
if (CreateProcessW(const_cast<LPCWSTR>(FullPathToExe.c_str()),
pwszParam, 0, 0, false,
CREATE_DEFAULT_ERROR_MODE, 0, 0,
&siStartupInfo, &piProcessInfo) != false)
{
/* Watch the process. */
dwExitCode = WaitForSingleObject(piProcessInfo.hProcess, (SecondsToWait * 1000));
}
else
{
/* CreateProcess failed */
iReturnVal = GetLastError();
}
/* Free memory */
delete[]pwszParam;
pwszParam = 0;
/* Release handles */
CloseHandle(piProcessInfo.hProcess);
CloseHandle(piProcessInfo.hThread);
return iReturnVal;
}
int main(void){
ExecuteProcess(L"C:\\Users\\Adam\\Desktop\\pdftotext", L"-layout \"C:\\Users\\Adam\\Desktop\\week 4.pdf\"", 0);
_getch();
}
I'm a little bit overwhelmed since it uses some things I've never used before, but I think I understand the core (keyword: think). It doesn't solve my problem, though, because the cmd shows up and by retesting it I actually noticed that the cmd doesn't even run the .exe and doesn't give me an error message.
I hope this bit of code helps... I didn't want to look into it further since it seemed like I wasn't even going in the right direction.
Use CreateProcess instead of system.
--EDIT--
the code for CreateProcess that I tried is what I found at this url:
The code is a mess, I'd advise to avoid that url in future.
At the end of "CreateProcess" article is a link named "Creating Processes", which contains simpler example that is easier to read. Use it as a starting point.
After adding the following lines for siStartupInfo, cmd window won't pop up any more with my own test *.exe.
siStartupInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
siStartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
siStartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
siStartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
siStartupInfo.wShowWindow = SW_HIDE;
But I have another problem. As I try to run some other executable, whose command line would be
TEST.exe <input-file> output-file
in a cmd window, WaitForSingleObject() return 258, and GetLastError() return 1813 ("The specified resource type cannot be found in the image file.").
See system() and CreateProcess() / CreateProcessW() for more details.
Any ideas would be highly appreciated!
The only way I found how to execute an external program is:
system("start C:\file path\ file");
The only problem is that the file or directory can't have spaces.

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.

How do I find out if a .exe is running in 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.