Results 1 to 16 of 16

Thread: Closing an application with only its file name

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2002
    Posts
    269

    Closing an application with only its file name

    Hi guys,

    I have been trying to do this from visual basic for a few days and can't manage to get it working.

    All I have is the programs .exe, no caption, no hwnd etc.

    I am not very experienced in c++ so bare with me.

    I had vb code that would tell me if eg. "abc123.exe" was currently running. It also could tell me the programs path but I couldn't adapt it o giving me a hwnd to close the program.

    Any help would be greatly appreciated!!
    THX
    KT

  2. #2
    PowerPoster sunburnt's Avatar
    Join Date
    Feb 2001
    Location
    Boulder, Colorado
    Posts
    1,403
    Here's my idea:(MSDN: Enumerate all processes)

    This will tell you the process id and name of all running applications. When you find your application, you can find all windows that are children of the desktop, and check their process ID against the one you've obtained via GetWindowThreadProcessId. When you've found it you can close it in a variety of ways.
    Every passing hour brings the Solar System forty-three thousand miles closer to Globular Cluster M13 in Hercules -- and still there are some misfits who insist that there is no such thing as progress.

  3. #3
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    You can also use TerminateProcess if you REALLY want to kill a process - note however that this doesn't give the process any chance to do cleaning or saving data.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  4. #4

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2002
    Posts
    269
    Thanks for the help guys,

    I am such a noob when it comes to VC++

    I managed to finally find a .h file that that microsoft code needed, then I compiled in Visual Studio 6 and it was saying it couldn't find definitions for different things.

    Am I doing something wrong?

    KT

  5. #5
    PowerPoster sunburnt's Avatar
    Join Date
    Feb 2001
    Location
    Boulder, Colorado
    Posts
    1,403
    no, I had that problem too. You need to link with the library of the same name as that header (I forgot what it was: psiapi?). You can do that with this line:
    Code:
    #pragma comment(lib, "thefilename.lib")
    Edit: here's what I came up with.
    Code:
    #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
    #include <string.h>
    #include <stdlib.h>
    #include "psapi.h"
    #pragma comment (lib, "psapi")
    
    DWORD GetProcessIdFromName(LPSTR lpszName, BOOL bCaseSensitive);
    BOOL  KillProcess(DWORD dwProcessId, DWORD dwExitCode);
    
    int main()
    {
    	// while an instance of notepad is open
    	while(DWORD dwProc = GetProcessIdFromName("notepad.exe", FALSE))
    	{
    		// destroy!
    		KillProcess(dwProc, 0);
    	}
    
    	return 0;
    }
    
    BOOL KillProcess(DWORD dwProcessId, DWORD dwExitCode)
    {
    	// open process with rights to terminate
    	HANDLE hProc = OpenProcess(PROCESS_TERMINATE , FALSE, dwProcessId);
    
    	if (hProc)
    	{	
    		if (TerminateProcess(hProc, dwExitCode))
    		{
    			CloseHandle(hProc);
    			return TRUE;
    		}
    		CloseHandle(hProc);
    	}
    
    	// either OpenProcess or TerminateProcess failed.
    	return FALSE;
    }
    
    
    DWORD GetProcessIdFromName(LPSTR lpszName, BOOL bCaseSensitive)
    {
    	DWORD dwBytes;		// number of bytes returned
    	DWORD dwIDs[512];	// Process IDs.
    	DWORD dwCount;		// number of IDs returned
    
    	if (!bCaseSensitive)
    		strlwr(lpszName);
    	
    	if (EnumProcesses(dwIDs, sizeof(dwIDs), &dwBytes))
    	{
    		dwCount = dwBytes / sizeof(DWORD);
    		for(int i = 0; i < dwCount; i++)
    		{
    			// open process
    			// this will fail on some system processes
    			//like the Idle Process
    			HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
    					PROCESS_VM_READ, FALSE,
    					dwIDs[i]);
    
    			if (hProcess)
    			{
    				char szProcessName[256];
    				HMODULE hModule;
    
    				if (EnumProcessModules(hProcess, &hModule,
    						sizeof(hModule), &dwBytes))
    				{
    					GetModuleBaseName(hProcess, hModule,
    							szProcessName,
    							sizeof(szProcessName));
    					
    					if (!bCaseSensitive)
    						strlwr(szProcessName);
    					
    					if (!strcmp(szProcessName, lpszName))
    					{
    						CloseHandle(hProcess);
    						return dwIDs[i];
    					}
    				}
    
    				CloseHandle(hProcess);
    			}
    
    		}
    	}
    
    	// didn't find the process, or something went wrong.
    	return NULL;
    }
    Last edited by sunburnt; Apr 5th, 2007 at 12:50 PM.
    Every passing hour brings the Solar System forty-three thousand miles closer to Globular Cluster M13 in Hercules -- and still there are some misfits who insist that there is no such thing as progress.

  6. #6

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2002
    Posts
    269
    Wow thats pretty impressive, works fine now that I found the psapi files.

    Now all I need is a UI. Is there any good guides to making a simple UI.

    All I really need is to know how to work with check boxes and text boxes so the user can type in the program name, and check a check box if they want to disable it or not.

    I would search but I don't know whats the best guide to read.

    Is it hard?

    I am so used to check1 = whatever, thats probably 40 lines in c++ eh?

    Thanks again,
    KT

  7. #7
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    I think it's one line in C++, just the line is 4 times as long.

    The easiest way would be a dialog. Learn to use the dialog editor and read up on DialogBox.
    GetDlgItemText, GetDlgItem and SendMessage are good topics too, as are the windows controls (not common controls, those are more advanced and not what you need here).
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  8. #8

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2002
    Posts
    269
    Thanks, reading some stuff on dialogs now.

    One more problem, is there a way to get the path of the file that I am looking for. Say I have two abc.exe running and I only want to close the one thats in c:\program files for example.

    When the process is found, whats the best way to see where that process is on disk. I have some vb code that will do it but this c++ code doesn't allow that.

    thx
    KT

  9. #9
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    In the code, extend the szProcessName buffer to MAX_PATH, and replace GetModuleBaseName by GetModuleFileName.
    Then it only works with fully specified paths.

    Of course, if two instances of the same app are running, the code chooses the one to close more or less randomly.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  10. #10

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2002
    Posts
    269
    OMG thats great.

    I would love to know how all this works but it works.

    Cheers man, u are truly a God.

    KT

  11. #11
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Ok, here's a commented version of the thing. I also made some changes to the code to make it UNICODE compatible.

    In general there are 3 types of important handles for such stuff:
    1) Process handles. You can manipulate whole processes with this (a process is the common owner of all threads and modules of this process). Process handles are process-local: the handle for a process has a different value in one process than in another. That's why there are also process IDs, which are globally unique.
    2) Module handles. Those refer to the various code files (exes and dlls) that are loaded by one process. Module handles are process-local.
    3) Window handles. Those refer to windows. They are global.

    Originally posted by sunburnt

    Code:
    #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
    #include <tchar.h>
    #include <psapi.h>
    #pragma comment (lib, "psapi")
    
    // CHANGE HERE!!!
    DWORD GetProcessIdFromName(LPCTSTR lpszName, BOOL bCaseSensitive);
    BOOL  KillProcess(DWORD dwProcessId, DWORD dwExitCode);
    BOOL  CloseProcess(DWORD dwProcessId);
    
    int main()
    {
    	// while an instance of notepad is open
    	while(DWORD dwProc = GetProcessIdFromName(_T("c:\\winnt\\notepad.exe"), FALSE))
    	{
    		// destroy!
    		KillProcess(dwProc, 0);
    	}
    
    	return 0;
    }
    
    // This kills a process given its ID.
    BOOL KillProcess(DWORD dwProcessId, DWORD dwExitCode)
    {
    	// open process with rights to terminate
    	// opening a process means
    	// obtaining a local process handle
    	// given the ID.
    	HANDLE hProc = OpenProcess(PROCESS_TERMINATE , FALSE, dwProcessId);
    
    	// if opening succeeded
    	if (hProc)
    	{
    		// try to kill it
    		if (TerminateProcess(hProc, dwExitCode))
    		{
    			CloseHandle(hProc);
    			return TRUE;
    		}
    		CloseHandle(hProc);
    	}
    
    	// either OpenProcess or TerminateProcess failed.
    	return FALSE;
    }
    
    #define IDCOUNT 512
    
    // this gets the process ID for a given filename
    // CHANGE HERE!!!
    DWORD GetProcessIdFromName(LPCTSTR lpszName, BOOL bCaseSensitive)
    {
    	DWORD dwBytes;		// number of bytes returned
    	DWORD dwIDs[IDCOUNT];	// Process IDs.
    	DWORD dwCount;		// number of IDs returned
    
    	if (EnumProcesses(dwIDs, sizeof(dwIDs), &dwBytes))
    	{
    		dwCount = dwBytes / sizeof(DWORD);
    		for(int i = 0; i < dwCount; i++)
    		{
    			// open process
    			// this will fail on some system processes
    			//like the Idle Process
    
    			// again: convert ID to handle
    			HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
    					PROCESS_VM_READ, FALSE,
    					dwIDs[i]);
    
    			if (hProcess)
    			{
    				// A buffer for the filename.
    				// MAX_PATH is the maximum amount of characters that may
    				// appear in a Win9x path, and usually not even on NT
    				// are there files with longer paths.
    				TCHAR szProcessName[MAX_PATH];
    				HMODULE hModule;
    
    				// Get the various files loaded by the process.
    				if (EnumProcessModules(hProcess, &hModule,
    						sizeof(hModule), &dwBytes))
    				{
    					int cmp;
    					// get the fully qualified name of the file
    					GetModuleFileNameEx(hProcess, hModule,
    							szProcessName,
    							MAX_PATH);
    
    					// compare it to the wanted name
    					if (bCaseSensitive)
    						cmp = _tcscmp(szProcessName, lpszName);
    					else
    						cmp = _tcsicmp(szProcessName, lpszName);
    					
    					// if they are equal, return the ID of this process
    					if (cmp == 0)
    					{
    						CloseHandle(hProcess);
    						return dwIDs[i];
    					}
    				}
    
    				CloseHandle(hProcess);
    			}
    
    		}
    	}
    
    	// didn't find the process, or something went wrong.
    	return 0;	// IDs are not pointers, so no sense in returning the pointer
    				// value NULL
    }
    Last edited by CornedBee; Jun 18th, 2003 at 05:51 PM.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  12. #12

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2002
    Posts
    269
    Thanks MAN!!

    Works great, especially now that I can put a full path as input.

    I used the FILE-NEW-MFC exe to create a window and text box, button etc and tried adding this great working code but its giving errors already. Can I add a window to this code I have without having to go through a mfc wizard or is it too difficult that way.

    Strange how it works fine on its own but put it in with other code and it blows up.

    KT

  13. #13
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    In an MFC project it is hard to add a windows that doesn't use MFC.

    I made a slight change to the code to solve the problem you brought up in the other thread.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  14. #14

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2002
    Posts
    269
    OK the modified

    while(DWORD dwProc = GetProcessIdFromName(_T("c:\\winnt\\notepad.exe"), FALSE))

    works but when I put in my own

    while(DWORD dwProc = GetProcessIdFromName(_T(filename), FALSE))

    it blows up again. Whats wrong with the code posted in the other thread?

    KT

  15. #15

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2002
    Posts
    269
    OK

    I have decided to go back and try this in vb seeing as creating windows and the like is much simpler

    The only code I got to do this in VB doesn't work in Windows NT\XP though, why would this be?

    Most of the code looks very similar to this c++ code, I don't know what I have to change to get it to work for me in XP. The only thing the vb code won't do for me is to actually close the window.

    KT

  16. #16
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    The _T is only used for literals. All other times make sure you pass in a const TCHAR * (also known as LPCTSTR).
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

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