June 17, 2024, 07:42:03 AM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


One program controlling another.

Started by LarryMc, October 27, 2010, 09:51:58 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

LarryMc

Here's what I want to do.

run a program, say, from a desktop lnk. lets's call it oneprog.exe and I have no idea what the title will be.

Have my IWB program to test to see if "oneprog.exe" is running and if it is shut it down (like is done in task manager).

Gotta be a way.

LarryMc
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Copex


sorry the code is messy.

if you copy and compile the code, the last line should say 'file not found' then load the calculator program (win7)  and it shoud close it down.

hope it helps, there are a few ways to do the same task, this is the one that worked for me.

'
'requires Sapero's Windows include files
'---------------------------------------
'
'this code works better on Win32 than Win64 - can anyone fix it :-)
'
$ifndef WIN32
$define WIN32
$endif

$ifdef WIN32
$define WIN32_LEAN_AND_MEAN
$endif

$include "windowssdk.inc"
$include "Psapi.inc"
$include "TlHelp32.inc"

DWORD aProcesses[1024], cbNeeded, cProcesses, procId, bProcess[512]
handle hProcess, hTokenSelf, hProcSelf

OPENCONSOLE

'// Get PID (Process ID) From window name and kill process.
'//--------------------------------------------------------

/*
hWnd = FindWindowA(NULL,"Calculator")

if hWnd >0
_GetWindowThreadProcessId(hWnd, &procId)
killProcess(procId)
ENDIF
*/

'// Get number of running Processes used by findProcessIdByName()
'
'EnumProcesses( aProcesses, len(aProcesses), &cbNeeded )
'cProcesses = cbNeeded/len(DWORD)

'// set privilages ( Not sure i got this working 100% still getting "access denied" errors
hProcSelf = OpenProcess( PROCESS_ALL_ACCESS,FALSE,GetCurrentProcessId() )
OpenProcessToken(hProcSelf,TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY ,&hTokenSelf)

'SetPrivilege( hTokenSelf, SE_TCB_NAME, TRUE )
'SetPrivilege( hTokenSelf, SE_IMPERSONATE_NAME, TRUE )

SetPrivilege(hTokenSelf,"SeDebugPrivilege",true)

'//check each PID and get filename.
'for i = 0 to cProcesses
' findProcessIdByName(aProcesses[i])
'next i

'// find process id from exe using CreateToolhelp32Snapshot & Kill the process, some process auto restart.
'
'retval = findPIDByName("explorer.exe")
retval = findPIDByName("calc.exe")

if retval <>0
killProcess(retval)
ELSE
print "Process Not Found."
ENDIF

'// terminate this program


print "Press any key to get the hell out of here"
WAITCON

CLOSECONSOLE
END




sub findPIDByName(string fileNameToFindPID),int
'// required by fined PIDByName
const TH32CS_SNAPHEAPLIST =0x00000001
const TH32CS_SNAPPROCESS =0x00000002
const TH32CS_SNAPTHREAD =0x00000004
const TH32CS_SNAPMODULE =0x00000008
const TH32CS_SNAPMODULE32 =0x00000010
const TH32CS_SNAPALL =(TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE)
const TH32CS_INHERIT =0x80000000
const PROCESS_ALL_ACCESS =0x1F0FFF


type PROCESSENTRY32
uint dwSize
uint cntUsage
uint th32ProcessID
uint th32DefaultHeapID
uint th32ModuleID
uint cntThreads
uint th32ParentProcessID
uint pcPriClassBase
uint dwFlags
istring szExeFile[259]
endtype

def pe:PROCESSENTRY32
string item,PID
int retval, x = 0


hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0)
pe.dwSize=len(pe)
retval=Process32First(hSnapshot,pe)

do

if LCASE$(pe.szExeFile) = LCASE$(fileNameToFindPID)
CloseHandle(hSnapshot)
return pe.th32ProcessID
ENDIF
item = pe.szExeFile
PID = STR$(pe.th32ProcessID)

print "["+pid+"] "+item

x++

dwPriorityClass = 0

   hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pe.th32ProcessID)

    if hProcess = NULL
      print error("Open Process Fail findpidbyname ")
    else
   
      dwPriorityClass = GetPriorityClass(hProcess)

      if dwPriorityClass <>0
'print dwPriorityClass
ELSE
print error("dwPriorityClass")
endif
CloseHandle(hProcess)

/*' Print process Info
    print "process ID        = ",pe.th32ProcessID
    print "thread count      = ",pe.cntThreads
    print "parent process ID = ",pe.th32ParentProcessID
    print "Priority Base     = ",pe.pcPriClassBase
print "Priority Class    = ",dwPriorityClass
*/
endif

pe.dwSize=len(PROCESSENTRY32)
retval=Process32Next(hSnapshot,pe)

until retval = false

CloseHandle(hSnapshot)
return 0
ENDSUB

sub findProcessIdByName(int processID),INT

int ret
string szProcessName

szProcessName = SPACE$(255)

hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE,processID )

if hProcess <>0

ret = EnumProcessModules( hProcess, bProcess[0], len(bProcess), &cbNeeded)

if ret <>0
ret = GetModuleBaseName(hProcess, bProcess[0], szProcessName,len(szProcessName))
' ret = GetModuleFileNameEx(hProcess, bProcess[0], szProcessName,len(szProcessName))


if ret <>0
print szProcessName
ELSE
print error("GetModule")
ENDIF

ELSE
error("EnumProcessModules")
ENDIF
CloseHandle( hProcess )
ELSE
print error( "Openprocess Failed"+str$(processID))
ENDIF
return 0
ENDSUB

sub killProcess(int PID)

HANDLE hProc

hProc = OpenProcess(PROCESS_ALL_ACCESS|PROCESS_TERMINATE, FALSE, PID)

          if hProc <>0

               if TerminateProcess(hProc, 0) <>0
                    MessageBox (NULL, "CLOSED", "CLOSED", @MB_ICONSTOP)
               else
                    MessageBox (NULL, error("SUB KillProcess "), "NOT CLOSED PID"+str$(procId), @MB_ICONSTOP)
                  CloseHandle(hProc)
   endif
          else
               MessageBox (NULL, error("SUB KillProcess "),"I CANT CLOSE "+str$(procId),@MB_ICONSTOP)
  ENDIF
ENDSUB


sub SetPrivilege(HANDLE hToken, string lpszPrivilege,INT bEnablePrivilege)

TYPE TOKEN_PRIVILEGES
DEF PrivilegeCount:INT
DEF LowPart:INT
DEF HighPart:INT
DEF Attributes:INT
ENDTYPE


def tp:TOKEN_PRIVILEGES
def luid:LUID

if LookupPrivilegeValue(NULL,lpszPrivilege,&luid ) = 0
error("LookupPrivilegeValue error: ")
return FALSE
ENDIF

tp.PrivilegeCount = 1
tp.Privileges[0].Luid = luid

    if bEnablePrivilege = true
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED
else
tp.Privileges[0].Attributes = 0
ENDIF

'// Enable the privilege or disable all privileges.

if AdjustTokenPrivileges(hToken,FALSE, &tp, LEN(TOKEN_PRIVILEGES), 0, 0) =0
error("AdjustTokenPrivileges error:")
  return FALSE
ENDIF

if GetLastError() = ERROR_NOT_ALL_ASSIGNED

  print "The token does not have the specified privilege."
  return FALSE
ENDIF

return TRUE

ENDSUB

SUB error(string errorCall),string 

   INT CodeErrorId, nBufferSize, flag
   STRING sBuffer,retError 

   nBufferSize = 1024
   sBuffer = String$(nBufferSize, Chr$(0))
   flag=FORMAT_MESSAGE_FROM_SYSTEM

   CodeErrorId=GetLastError()

   FormatMessage(flag, NULL,CodeErrorId,LANG_NEUTRAL, sBuffer, nBufferSize ,NULL )
retError = errorCall+" / "+sBuffer+" / ErrorID = "+str$(CodeErrorID)

return retError

endsub
-
I really should learn how to use a spell checker! though im not sure how it will help someone who can not spell?
-
Except where otherwise noted, content Posted By Copex is
licensed under a Creative Commons Attribution 3.0 License

http://creativecommons.org/licenses/by/3.0/

LarryMc

Thanks Copex,

I'll have to study that for a while to see if I understand it all.

LarryMc
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

sapero

October 28, 2010, 06:40:03 AM #3 Last Edit: October 28, 2010, 06:44:07 AM by sapero
I have yet another version with some console feedback :)
$include "windowssdk.inc"
$include "Psapi.inc"
$include "TlHelp32.inc"

' usage:
ShellExecute(0, 0, "notepad.exe", 0, 0, SW_SHOW)
ShellExecute(0, 0, "notepad.exe", 0, 0, SW_SHOW)
ShellExecute(0, 0, "notepad.exe", 0, 0, SW_SHOW)
MESSAGEBOX 0, "Click OK to close all notepads", ""
KillExeByPath("%WINDIR%\\system32\\notepad.exe")


sub KillExeByPath(string fullpath1),BOOL
PROCESSENTRY32 pe
THREADENTRY32  te
istring szPath[MAX_PATH]
istring fullpath[MAX_PATH]
int successCount = 0

ExpandEnvironmentStrings(&fullpath1, &fullpath, MAX_PATH)

HANDLE hFile = CreateFile(fullpath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0)
if (hFile <> INVALID_HANDLE_VALUE)
' not running
CloseHandle(hFile)
return TRUE
endif

HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD, 0)
if (hSnap <> INVALID_HANDLE_VALUE)

pe.dwSize = len(pe)
DWORD dwThisProcessId = GetCurrentProcessId()
if (Process32First(hSnap, &pe))
do
if (pe.th32ProcessID <> dwThisProcessId)
print "process id ", pe.th32ProcessID
' check exe path
HANDLE hProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, pe.th32ProcessID)
if (hProcess)
if (GetModuleFileNameEx(hProcess, 0, &szPath, MAX_PATH) and !lstrcmpi(szPath, fullpath))
print " - found process"
' process found. Find a window and close it.
te.dwSize = len(te)
if (Thread32First(hSnap, &te))
do
if (te.th32OwnerProcessID = pe.th32ProcessID)
print " - thread ", te.th32ThreadID
' enumerate windows
EnumThreadWindows(te.th32ThreadID, &EnumThreadWndProc, 0)
endif
' if process terminated, quit DO-UNTIL
if (!WaitForSingleObject(hProcess, 0))
successCount++
print " - program has terminated"
goto quit_do
endif
until (!Thread32Next(hSnap, &te))
quit_do:
endif
' if this process is still running
if (WaitForSingleObject(hProcess, 0))
print " - terminating"
if (TerminateProcess(hProcess, STILL_ACTIVE))
successCount++
print " - ok"
endif
endif
endif
CloseHandle(hProcess)
endif
endif
until (!Process32Next(hSnap, &pe))
endif
CloseHandle(hSnap)
endif
return successCount
endsub


sub EnumThreadWndProc(HWND hwnd, LPARAM lParam),BOOL
print " - found window (closing)"
EndTask(hwnd, FALSE, TRUE/*terminate when WM_CLOSE times-out*/)
return TRUE
endsub

Copex

October 29, 2010, 04:03:27 AM #4 Last Edit: October 29, 2010, 04:12:16 AM by Copex
Quote from: sapero on October 28, 2010, 06:40:03 AM
I have yet another version with some console feedback :)


works using winxp - vista/windows 7 fails to close notepad you get the list of process id's printed to the console window and then the program ends.

i have never got my head round ms security privileges....

http://msdn.microsoft.com/en-us/library/ms684880%28v=VS.85%29.aspx
 
-
I really should learn how to use a spell checker! though im not sure how it will help someone who can not spell?
-
Except where otherwise noted, content Posted By Copex is
licensed under a Creative Commons Attribution 3.0 License

http://creativecommons.org/licenses/by/3.0/

sapero

There are multiple ways to terminate a process:
1. Post WM_QUIT message to the queue of all threads, then wait a bit.
2. Send WM_CLOSE message (with a timeout) to all windows in this process
...
99. Create a remote thread in ExitProcess function, TerminateProcess, UnmapViewOfFile(exe module), debugger attach+stop

sub KillExeByPath(string fullpath1),BOOL
PROCESSENTRY32 pe
THREADENTRY32  te
istring szPath[MAX_PATH]
istring fullpath[MAX_PATH]
int successCount = 0, ThreadId

ExpandEnvironmentStrings(&fullpath1, &fullpath, MAX_PATH)

HANDLE hFile = CreateFile(fullpath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0)
if (hFile <> INVALID_HANDLE_VALUE)
' not running
CloseHandle(hFile)
return TRUE
endif

HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD, 0)
if (hSnap <> INVALID_HANDLE_VALUE)

pe.dwSize = len(pe)
DWORD dwThisProcessId = GetCurrentProcessId()
if (Process32First(hSnap, &pe))
do
if (pe.th32ProcessID <> dwThisProcessId)
print "process id ", pe.th32ProcessID
' check exe path
HANDLE hProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, pe.th32ProcessID)
if (hProcess)
if (GetModuleFileNameEx(hProcess, 0, &szPath, MAX_PATH) and !lstrcmpi(szPath, fullpath))
print " * well-matched"
' process found. Post WM_QUIT message to all threads in this process
te.dwSize = len(te)
BOOL QuitPosted = FALSE
if (Thread32First(hSnap, &te))
do
if (te.th32OwnerProcessID = pe.th32ProcessID)
print " - posting WM_QUIT to thread ", te.th32ThreadID
if (PostThreadMessage(te.th32ThreadID, WM_QUIT, 0, 0)) then QuitPosted = TRUE
endif
until (!Thread32Next(hSnap, &te))
endif

' wait a while for PostThreadMessage
DWORD dwWaitResult = WaitForSingleObject(hProcess, IIF(QuitPosted, 1000, 0))

if (QuitPosted and (dwWaitResult = WAIT_TIMEOUT))
print " - PostThreadMessage timed out"
endif

if (dwWaitResult)
' post WM_CLOSE message to all windows created by this thread
if (Thread32First(hSnap, &te))
do
if (te.th32OwnerProcessID = pe.th32ProcessID)
print " - enumerating windows in thread ", te.th32ThreadID
' enumerate windows
EnumThreadWindows(te.th32ThreadID, &EnumThreadWndProc, 0)
endif
until (!Thread32Next(hSnap, &te))
endif
endif

' if the process is still running
if (WaitForSingleObject(hProcess, 0))
print " - terminating with remote thread"
HANDLE hThread = CreateRemoteThread(hProcess,0,0,&ExitProcess,0,0,&ThreadId)
if (hThread)
WaitForSingleObject(hThread, 5000)
CloseHandle(hThread)
endif
endif

' if the process is still running
if (WaitForSingleObject(hProcess, 0))
TerminateProcess(hProcess, STILL_ACTIVE)
endif
endif

if (!WaitForSingleObject(hProcess, 0))
successCount++
print " + program terminated"
endif
CloseHandle(hProcess)
endif
endif
until (!Process32Next(hSnap, &pe))
endif
CloseHandle(hSnap)
endif
return successCount
endsub


sub EnumThreadWndProc(HWND hwnd, LPARAM lParam),BOOL
DWORD_PTR dwResult
print " - closing window 0x",HEX$(hwnd)
if (!SendMessageTimeout(hwnd, WM_CLOSE, 0, 0, SMTO_ABORTIFHUNG, 500, &dwResult))
dwResult = GetLastError()
select (dwResult)
case 0
print "SendMessageTimeout timed out"
endselect
endif
return TRUE
endsub


In notepad, even if you type some text and do not save it, the first method with WM_QUIT terminates notepad without asking for "do you want to save".
In my previous example, EndTask api combines WM_CLOSE message + wait + TerminateProcess. It is used also in the task manager in Applications tab, at least on XP.

Copex

Quote from: sapero on October 29, 2010, 02:14:15 PM
There are multiple ways to terminate a process:
1. Post WM_QUIT message to the queue of all threads, then wait a bit.
2. Send WM_CLOSE message (with a timeout) to all windows in this process
...
99. Create a remote thread in ExitProcess function, TerminateProcess, UnmapViewOfFile(exe module), debugger attach+stop

In notepad, even if you type some text and do not save it, the first method with WM_QUIT terminates notepad without asking for "do you want to save".
In my previous example, EndTask api combines WM_CLOSE message + wait + TerminateProcess. It is used also in the task manager in Applications tab, at least on XP.

win7 & vista you have to set the access token to be able to terimate or end a process.
-
I really should learn how to use a spell checker! though im not sure how it will help someone who can not spell?
-
Except where otherwise noted, content Posted By Copex is
licensed under a Creative Commons Attribution 3.0 License

http://creativecommons.org/licenses/by/3.0/