CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    Nov 2011
    Location
    India
    Posts
    333

    [RESOLVED] Only Running MFC Application List from Taskbar

    Hi,

    I like to find running MFC Process list (ONLY) from taskbar.

    followed this : Enumerating All Processes
    I like to filter the mfc process. How is possible?
    Last edited by saraswathisrinath; September 10th, 2018 at 01:32 AM. Reason: Application list not showed the exe. Wrongly asked .
    Regards,

    SaraswathiSrinath

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,397

    Re: Only Running MFC Application List from Taskbar

    I guess you should check the program dependencies. If there is one of the MFCxx.dll - then there is the MFC process.
    See/search: https://www.google.de/search?newwind....0.FTqk3zNI-qY
    Victor Nijegorodov

  3. #3
    Join Date
    Nov 2011
    Location
    India
    Posts
    333

    Re: Only Running MFC Application List from Taskbar

    Quote Originally Posted by VictorN View Post
    I guess you should check the program dependencies. If there is one of the MFCxx.dll - then there is the MFC process.
    See/search: https://www.google.de/search?newwind....0.FTqk3zNI-qY
    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.
    Regards,

    SaraswathiSrinath

  4. #4
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,397

    Re: Only Running MFC Application List from Taskbar

    Quote Originally Posted by saraswathisrinath View Post
    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.
    1. You should formulate your questions more clear.
    2. Are you banned by Google?
    See https://www.google.de/search?newwind....0.Apuzpb0vqMM
    Victor Nijegorodov

  5. #5
    Join Date
    Nov 2011
    Location
    India
    Posts
    333

    Re: Only Running MFC Application List from Taskbar

    Quote Originally Posted by VictorN View Post
    1. You should formulate your questions more clear.
    2. Are you banned by Google?
    See https://www.google.de/search?newwind....0.Apuzpb0vqMM
    I already found how to enumerate all process from taskbar
    Code:
    std::wcout << L"\n\ncntThreads: " << processEntry.cntThreads << std::endl;
    std::wcout << L"cntUsage: " << processEntry.cntUsage << std::endl;
    std::wcout << L"dwFlags: " << processEntry.dwFlags << std::endl;
    std::wcout << L"dwSize: " << processEntry.dwSize << std::endl;
    std::wcout << L"pcPriClassBase: " << processEntry.pcPriClassBase << std::endl;
    std::wcout << L"szExeFile: " << processEntry.szExeFile << std::endl;
    std::wcout << L"th32DefaultHeapID: " << processEntry.th32DefaultHeapID << std::endl;
    std::wcout << L"th32ModuleID: " << processEntry.th32ModuleID << std::endl;
    std::wcout << L"th32ParentProcessID: " << processEntry.th32ParentProcessID << std::endl;
    std::wcout << L"th32ProcessID: " << processEntry.th32ProcessID << std::endl;
    I like to categorize the process by "User Name".
    I want to kill Particular process which is run by user.
    Attached Images Attached Images  
    Regards,

    SaraswathiSrinath

  6. #6
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,397

    Re: Only Running MFC Application List from Taskbar

    Victor Nijegorodov

  7. #7
    2kaud's Avatar
    2kaud is online now Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,825

    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.

    Sample output from my system

    Code:
     8852   admin1  ApntEx.exe
     4976   admin1  Apoint.exe
    10136   admin1  BrCcUxSys.exe
    12732   admin1  BrCtrlCntr.exe
     9592   admin1  BrotherHelp.exe
    21644   admin1  browserhost.exe
     9436   admin1  BrStMonW.exe
    10148   admin1  BTStackServer.exe
     8928   admin1  BTTray.exe
     9004   admin1  CLOCK.EXE
     6556   admin1  cmd.exe
    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!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  8. #8
    Join Date
    Nov 2011
    Location
    India
    Posts
    333

    Re: Only Running MFC Application List from Taskbar

    Quote Originally Posted by 2kaud View Post
    Personally I don't like EnumProcesses() as you have to pass a fixed size array. I prefer CreateToolhelp32Snapshot().
    Thank you so much. My purpose solved.
    Regards,

    SaraswathiSrinath

  9. #9
    2kaud's Avatar
    2kaud is online now Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,825

    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!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured