I was mean, An application runs by user (Ex: sample.exe ). I like to print the application names like test.exe, sample.exe which runs manually by user.
Other than I wont like to disturn system mfc application/process.
Re: Only Running MFC Application List from Taskbar
Originally Posted by saraswathisrinath
I was mean, An application runs by user (Ex: sample.exe ). I like to print the application names like test.exe, sample.exe which runs manually by user.
Other than I wont like to disturn system mfc application/process.
Re: Only Running MFC Application List from Taskbar
Personally I don't like EnumProcesses() as you have to pass a fixed size array. I prefer CreateToolhelp32Snapshot(). Consider
Code:
#include <iostream>
#include <iomanip>
#include <map>
#include <memory>
#include <string>
#include <algorithm>
#include <cctype>
#include <windows.h>
#include <tlHelp32.h>
using namespace std;
// Details of a process - add more members as needed
struct ProcInfo
{
string username;
string image;
DWORD procid;
ProcInfo(const string& un, const string& in, DWORD pid) : username(un), image(in), procid(pid) {}
};
using Procs = multimap<string, ProcInfo>;
// Create a multimap container of processes which have an associated user name with image name as key
Procs GetProcs()
{
// RAII for HANDLE
class myHandle
{
public:
myHandle(HANDLE h) : hand(h) {}
~myHandle() { CloseHandle(hand); }
operator HANDLE() const noexcept { return hand; }
HANDLE* operator&() noexcept { return &hand; }
private:
HANDLE hand;
};
// Convert to all lowercase
const static auto tolowerstr = [](string str) {
transform(str.begin(), str.end(), str.begin(), [](auto ch) {return static_cast<char>(tolower(ch)); });
return str;
};
Procs processes;
const myHandle hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapShot == INVALID_HANDLE_VALUE)
//cout << "Cannot create process snapshot - error " << GetLastError() << endl;
return processes;
auto processInfo = make_unique<PROCESSENTRY32>();
processInfo->dwSize = sizeof(PROCESSENTRY32);
while (Process32Next(hSnapShot, processInfo.get())) {
const myHandle hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, processInfo->th32ProcessID);
if (hProcess == NULL) {
//cout << "Cannot open process " << processInfo->th32ProcessID << " Error " << GetLastError() << endl;
continue;
}
myHandle hToken = NULL;
if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) {
//cout << "Cannot open process token for process " << processInfo->th32ProcessID << " Error " << GetLastError() << endl;
continue;
}
DWORD dwLength = 0;
// This will cause an error so don't bother checking!
GetTokenInformation(hToken, TokenUser, (LPVOID)NULL, 0, &dwLength);
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
//cout << "Cannot obtain token information for process " << processInfo->th32ProcessID << " Error " << GetLastError() << endl;
continue;
}
const auto ptumem = make_unique<char[]>(dwLength);
const auto ptu = reinterpret_cast<PTOKEN_USER>(ptumem.get());
if (!GetTokenInformation(hToken, TokenUser, (LPVOID)ptu, dwLength, &dwLength)) {
//cout << "Cannot obtain token information for process " << processInfo->th32ProcessID << " Error " << GetLastError() << endl;
continue;
}
SID_NAME_USE SidType;
char lpName[MAX_PATH];
char lpDomain[MAX_PATH];
DWORD dwName = MAX_PATH;
DWORD dwDomain = MAX_PATH;
if (LookupAccountSid(NULL, ptu->User.Sid, lpName, &dwName, lpDomain, &dwDomain, &SidType))
processes.emplace(tolowerstr(processInfo->szExeFile), ProcInfo{lpName, processInfo->szExeFile, processInfo->th32ProcessID});
}
return processes;
}
int main()
{
// Obtain process details
const auto processes = GetProcs();
for (const auto& p : processes)
cout << setw(5) << p.second.procid << '\t' << p.second.username << '\t' << p.second.image << endl;
}
This will generate a multimap (in image name order) of process info for those processes that have an associated user name and for test purposes display them. From the multimap generated it will be easy to obtain required info.
Last edited by 2kaud; September 10th, 2018 at 01:29 PM.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
Re: [RESOLVED] Only Running MFC Application List from Taskbar
For completeness re the original question, consider
Code:
#include <iostream>
#include <iomanip>
#include <map>
#include <memory>
#include <string>
#include <string_view>
#include <algorithm>
#include <cctype>
#include <list>
#include <filesystem>
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
#include <tlHelp32.h>
using namespace std;
// Details of a process - add more members as needed
struct ProcInfo
{
string username;
string image;
string fullname;
DWORD procid;
list<string> mods;
ProcInfo(const string& un, const string& in, const string& full, DWORD pid, list<string> m) : username(un), image(in), fullname(full), procid(pid), mods(move(m)) {}
};
// RAII for HANDLE
class myHandle
{
public:
myHandle(HANDLE h) : hand(h) {}
~myHandle() { CloseHandle(hand); }
operator HANDLE() const noexcept { return hand; }
HANDLE* operator&() noexcept { return &hand; }
private:
HANDLE hand;
};
using Procs = multimap<string, ProcInfo>;
// Convert to all lowercase
string tolower(string str) {
transform(str.begin(), str.end(), str.begin(), [](auto ch) {return static_cast<char>(tolower(ch)); });
return str;
};
// Obtain required privilege
bool ObtainPriv(string_view p_priv)
{
if (myHandle hAccessToken = NULL; OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hAccessToken))
if (LUID luidPrivilegeLUID; LookupPrivilegeValue(NULL, p_priv.data(), &luidPrivilegeLUID)) {
TOKEN_PRIVILEGES tpTokenPrivilege;
tpTokenPrivilege.PrivilegeCount = 1;
tpTokenPrivilege.Privileges[0].Luid = luidPrivilegeLUID;
tpTokenPrivilege.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (AdjustTokenPrivileges(hAccessToken, FALSE, &tpTokenPrivilege, sizeof(TOKEN_PRIVILEGES), NULL, NULL))
return true;
}
return false;
}
string GetUserName()
{
DWORD size = 0;
GetUserName(NULL, &size);
string name(size, 0);
GetUserName(name.data(), &size);
name.erase(name.find_last_not_of((char)0) + 1); // GetUserName() returns NULL padded
return name;
}
// Create a multimap container of processes which have an associated user name with image name as key
Procs GetProcs(size_t& exesize, size_t& usersize)
{
exesize = 0;
usersize = 0;
Procs processes;
const myHandle hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapShot == INVALID_HANDLE_VALUE) {
//cout << "Cannot create process snapshot - error " << GetLastError() << endl;
return processes;
}
const auto processInfo = make_unique<PROCESSENTRY32>();
processInfo->dwSize = sizeof(PROCESSENTRY32);
while (Process32Next(hSnapShot, processInfo.get())) {
string fullpath = processInfo->szExeFile;
list<string> mods;
exesize = max(exesize, fullpath.size());
const myHandle mSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, processInfo->th32ProcessID);
if (mSnapShot != INVALID_HANDLE_VALUE) {
auto moduleInfo = make_unique<MODULEENTRY32>();
moduleInfo->dwSize = sizeof(MODULEENTRY32);
if (Module32First(mSnapShot, moduleInfo.get()))
fullpath = moduleInfo->szExePath;
while (Module32Next(mSnapShot, moduleInfo.get()))
mods.emplace_back(moduleInfo->szExePath);
}
const myHandle hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, processInfo->th32ProcessID);
char lpName[MAX_PATH] = {0};
char lpDomain[MAX_PATH] = {0};
if (hProcess) {
myHandle hToken = NULL;
if (OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) {
DWORD dwLength = 0;
// This will cause an error so don't bother checking!
GetTokenInformation(hToken, TokenUser, (LPVOID)NULL, 0, &dwLength);
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
const auto ptumem = make_unique<char[]>(dwLength);
const auto ptu = reinterpret_cast<PTOKEN_USER>(ptumem.get());
if (GetTokenInformation(hToken, TokenUser, (LPVOID)ptu, dwLength, &dwLength)) {
SID_NAME_USE SidType;
DWORD dwName = MAX_PATH;
DWORD dwDomain = MAX_PATH;
if (LookupAccountSid(NULL, ptu->User.Sid, lpName, &dwName, lpDomain, &dwDomain, &SidType))
usersize = max(usersize, strlen(lpName));
}
}
}
}
processes.emplace(tolower(processInfo->szExeFile), ProcInfo {lpName, processInfo->szExeFile, fullpath, processInfo->th32ProcessID, mods});
}
return processes;
}
int main(int argc, char* argv[])
{
bool usrflg = false; // if specified only for current user
bool mfcflg = false; // if specified only for mfc programs
bool fullflg = false; // if specified also show full path for exe
// Quick way to parse options
for (size_t a = 1; a < argc; ++a) {
if (strcmp(argv[a], "/user") == 0)
usrflg = true;
if (strcmp(argv[a] , "/mfc") == 0)
mfcflg = true;
if (strcmp(argv[a], "/full") == 0)
fullflg = true;
}
ObtainPriv("SeDebugPrivilege"); // Try to obtain privileges. Only works if running As Administrator
size_t exesize = 0;
size_t usersize = 0;
const auto user = GetUserName(); // Get current user name
const auto processes = GetProcs(exesize, usersize); // Get current list of processes and max size of the exe and user names
// Display required processes
for (const auto& p : processes)
if (bool out = !mfcflg; !usrflg || (p.second.username == user)) {
if (mfcflg)
for (const auto& m : p.second.mods)
if (tolower(filesystem::path(m).filename().string()).substr(0, 3) == "mfc") {
out = true;
break;
}
if (out) {
cout << setw(5) << left << p.second.procid << '\t' << setw(usersize) << p.second.username << '\t' << setw(exesize) << p.second.image;
if (fullflg)
cout << '\t' << p.second.fullname;
cout << endl;
}
}
}
If used with no options displays all accessible processes. If used with /user only displays processors for the logged on user. If used with /mfc only displays those processes that use mfc. If used with /full then also displays the full path for the .exe . All options can be combined in any order.
Note that if run as a normal user, this might not include all the processes (even some for the current user) depending upon how the process security is set. To include all processes run this program As Administrator.
Also note that this is c++17 code and that to obtain both 32 and 64 bit .exe's, the program needs to be compiled as 64 bit.
Last edited by 2kaud; September 11th, 2018 at 11:50 AM.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.