[SOLVED]how to check if power point is already opened by Qt
-
I don't think Qt has any class for enumerating all running process on the system.
So I guess you'll have to make your own solution.
As you are talking about Power Point, I assume you are on the Windows platform.
In this case, you would use the Win32 API or more specifically the PSAPI:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms684894(v=vs.85).aspx
--
This will give you the list of all processes:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682629(v=vs.85).aspxThe handle to each process ID can be obtained via:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms684320(v=vs.85).aspxPath of the process can be obtain from the handle via:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683198(v=vs.85).aspxPulling these together should be straight forward ;-)
-
I try it with this function
@bool Dialog::matchProcessName( DWORD processID, QString processName)
{
TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");// Get a handle to the process. HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID ); // Get the process name. if (NULL != hProcess ) { HMODULE hMod; DWORD cbNeeded; if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) ) { GetModuleBaseName( hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(TCHAR) ); } }
// TCHAR* pstrName = _T(szProcessName);
// String st = pstrName;
// Compare process name with your string bool matchFound = !_tcscmp( szProcessName , processName.toStdString().c_str() ); // Release the handle to the process. CloseHandle( hProcess ); return matchFound;
}@
and I got error
error: C2664: 'strcmp' : cannot convert parameter 1 from 'TCHAR [260]' to 'const char *'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style castany help...
-
I was just doing the same thing a few hours ago.The following function should do the trick:
@bool isRunning(const QString &process) {
QProcess tasklist;
tasklist.start(
"tasklist",
QStringList() << "/NH"
<< "/FO" << "CSV"
<< "/FI" << QString("IMAGENAME eq %1").arg(process));
tasklist.waitForFinished();
QString output = tasklist.readAllStandardOutput();
return output.startsWith(QString(""%1").arg(process));
}@Just remember to include QProcess in your files.And give it the name of the process you want to check for.Hope this helps
-
Getting the list of open processes is fairly simple.. From what I understand you want to see if PPT was opened from your application. In this case you should check PPTs parent process id and if it is the same as your application that means it was opened by your application. :)
-
IYAM the QProcess and the Win32 API are not the same. What musimbate is doing is running an application that is "connected" to Qt via the QProgress class. What is desired here is a notification if power point is already open on the system. What Mulder says contains the solution. If the power point should be started from the application itself the use of QProcess is the way to go.
About the error in the last post, try to use Qt classes ;-) Make a new QString, give it the szProcessName char buffer and do a simple QString compare. That's what I would try.
Greetz
-
As far as I understood, Eslam mahgoub wants to find out whether Power Point is already running on the computer, so he has to enumerate all running processes. For this purpose, QProcess doesn't help at all :-(
QProcess can create a new process. And it can check whether that process is still running or not. But it can not connect to any process that is already running on the system!
Thus, what he wants/needs to do has no existing class in Qt , to my knowledge. Therefore he will have to write it himself. And this necessarily requires using the native API, i.e. Win32 API on Windows.
After all, Qt also extensively uses the Win32 API on Windows, it's just hidden inside the Qt code ;-)
--
About the strcmp() problem:
When your application is built as Unicode, which is the right thing to do nowadays, then the TCHAR macro resolves to "wchar_t" rather than "char", so you need to use wcscmp() instead of strcmp() here!
Or even better, to make you code work with ANSI and Unicode, use the _tcscmp() macro, which will resolve to strcmp() or wcscmp() as needed...
--
Alternatively:
Use GetModuleBaseNameW() (note the ...W postfix) and wchar_t and wcscmp() directly.
--
Try this:
@bool Dialog::matchProcessName( DWORD processID, QString processNameToMatch)
{
QString processName;
bool matchFound = false;HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID );if (NULL != hProcess )
{
HMODULE hMod;
DWORD cbNeeded;
wchar_t szProcessName[MAX_PATH];if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) ) { if(GetModuleBaseNameW( hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(TCHAR) ) > 0) { processName = QString::fromUtf16((unsigned short*) szProcessName); } } CloseHandle( hProcess );
}
if(!processName.isEmpty())
{
matchFound = processnName.endsWith(processNameToMatch, Qt::CaseSensitive)
}return matchFound;
}@ -
Thank You Gays ,
First musimbate I think "Tasklist" is a good idea but really I can't control of the process and your code is work I want just to focus on the application "power point" when it running.
Thanks b1gsnak3,Jeroentje@home.
Second MuldeR your solution I find That error
dialog.obj:-1: error: LNK2019: unresolved external symbol _GetModuleBaseNameW@16 referenced in function "public: bool __thiscall Dialog::matchProcessName(unsigned long,class QString)" (?matchProcessName@Dialog@@QAE_NKVQString@@@Z)
dialog.obj:-1: error: LNK2019: unresolved external symbol _EnumProcessModules@16 referenced in function "public: bool __thiscall Dialog::matchProcessName(unsigned long,class QString)" (?matchProcessName@Dialog@@QAE_NKVQString@@@Z)
I solved by adding That lib to project
@win32:LIBS += -L "C:/Program Files (x86)/Microsoft SDKs/Windows/v7.0A/Lib/" -lPsapi@
and I defined some problem in yours (function)
@bool Dialog::matchProcessName( DWORD processID, QString processNameToMatch)
{
QString processName;
bool matchFound = false;HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID );if (NULL != hProcess )
{
HMODULE hMod;
DWORD cbNeeded;
wchar_t szProcessName[MAX_PATH];if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) ) { if(GetModuleBaseNameW( hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(TCHAR) ) > 0) { processName = QString::fromUtf16((unsigned short*) szProcessName); } } CloseHandle( hProcess );
}
if(!processNameToMatch.isEmpty())
{
matchFound = processName.endsWith(processNameToMatch, Qt::CaseInsensitive);
int match = processName.compare(processNameToMatch,Qt::CaseInsensitive);
qDebug()<<match;
}return matchFound;
}
@and it's Work ^_^
Thank you all Thanks. -
Qt::CaseInsensitive, that's what I meant ;-)
Also I used endsWith() because I though GetModuleBaseNameW() returns the full path. It might not be the case. Anyway, I was thinking about QueryFullProcessImageName(), which is preferred nowadays.
[quote]The GetModuleBaseName function is primarily designed for use by debuggers and similar applications ... If the module list in the target process is corrupted or is not yet initialized, or if the module list changes during the function call as a result of DLLs being loaded or unloaded, GetModuleBaseName may fail or return incorrect information ... To retrieve the base name of the main executable module for a remote process, use QueryFullProcessImageName function to retrieve the module name and then use the strrchr function as described in the previous paragraph. This is more efficient and more reliable than calling GetModuleBaseName with a NULL module handle. [/quote]