is possible? Shell a Program and Pause it?
(run a program and quickly pause it before show window)
Printable View
is possible? Shell a Program and Pause it?
(run a program and quickly pause it before show window)
I doubt it. How would your app or the O/S know how to pause executing code. I can think of some potential options, but the code would be extremely advanced and include global hooking, DLL injection, subclassing the other processes message loop -- if it would even work.
Maybe if you provide far more details of what you are attempting to do, other workarounds might be offered.
i don' think so
when u shell aprogram u let the DOS - OS control it.
after the shell u cannt control what what u run.
Why do you want to do that anyway??
You may consider starting the program minimized so that it doesn't come to the foreground.
LaVolpe is right when he says that you can stop a shell but that depends on what are you trying to shell...
For example, if you are trying to shell notepad then by the time you try to hook into it, it will be launched... however if you are trying to shell an application which takes some time to run, yes, you can stop/terminate it...
Ok here is something that I tried...
Description: The only Application which I remember takes time is Acrobat (It keeps on loading api's and other stuff unless you have turned that option off) So I experimented with it and successfully terminated it before it launched...
Requirements: One form with two commandbutton (Command1 and Command2), Acrobat exe or any other program that takes time to load. If you choose any other program, amend it in the code.
Note: Remember to click the 2nd Commandbutton in less than a second else Acrobat will launch
Hope this helps...Code:Option Explicit
Private Declare Function CreateToolhelp32Snapshot Lib "kernel32" _
(ByVal dwFlags As Long, ByVal th32ProcessID As Long) As Long
Private Declare Function Process32First Lib "kernel32" (ByVal hSnapshot As _
Long, lppe As tagPROCESSENTRY32) As Boolean
Private Declare Function Process32Next Lib "kernel32" (ByVal hSnapshot As Long, _
lppe As tagPROCESSENTRY32) As Boolean
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess _
As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As _
Long, ByVal uExitCode As Long) As Long
Private Const MAX_PATH As Integer = 1024
Private Const TH32CS_SNAPPROCESS As Integer = 2
Private Const INVALID_HANDLE_VALUE As Long = -1
Private Const PROCESS_TERMINATE As Long = 1
Private Type tagPROCESSENTRY32
dwSize As Long
cntUsage As Long
th32ProcessID As Long
th32DefaultHeapID As Long
th32ModuleID As Long
cntThreads As Long
th32ParentProcessID As Long
pcPriClassBase As Long
dwFlags As Long
szExeFile As String * 1024
End Type
Private Sub Command1_Click()
Dim Pid As Long, flnm As String
'~~> Replace this with the relevant Application
flnm = "C:\Program Files\Adobe\Acrobat 6.0\Acrobat\Acrobat.exe"
'~~> Execute Acrobat.Exe
Pid = Shell(flnm, vbNormalFocus)
End Sub
Private Sub Command2_Click()
'~~> Kill Acrobat.Exe before it launches
TerminateProcByname ("Acrobat.exe")
End Sub
Public Sub TerminateProcByname(lpname As String)
Dim LngRet As Long, LngRet2 As Long, Lngprocid As Long
Dim ProcEntry As tagPROCESSENTRY32
If Len(Trim(lpname)) = 0 Then Exit Sub
LngRet = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
If Not LngRet = INVALID_HANDLE_VALUE Then
ProcEntry.dwSize = Len(ProcEntry)
End If
If Process32First(LngRet, ProcEntry) Then
Do
If Not ProcEntry.th32ProcessID = 0 Then
If InStr(1, ProcEntry.szExeFile, lpname, vbTextCompare) Then
Lngprocid = ProcEntry.th32ProcessID
LngRet = OpenProcess(PROCESS_TERMINATE, 0, Lngprocid)
If Not LngRet = 0 Then
If Not TerminateProcess(LngRet, LngRet2) = 0 Then _
MsgBox "Shell Terminated: " & ProcEntry.szExeFile
Else
MsgBox "Permission denied!", vbInformation
End If
End If
End If
Loop While Process32Next(LngRet, ProcEntry)
End If
End Sub
ps: Though I like Pradeep's idea but I am currently trying to pause and then resume the shell... lets see what can I achieve...
Have a search for SuspendThread, perhaps that should work for you. I have this small utility that catches the opening of applications of choice and when caught it is being suspended until the correct password is provided.
Edit:
Here are the necessary stuffs needed, in a module.
Sample usage:Code:Option Explicit
Private Type THREADENTRY32
dwSize As Long
cntUsage As Long
th32ThreadID As Long
th32OwnerProcessID As Long
tpBasePri As Long
tpDeltaPri As Long
dwFlags As Long
End Type
Private Declare Function CreateToolhelp32Snapshot Lib "kernel32.dll" ( _
ByVal dwFlags As Long, _
ByVal th32ProcessID As Long) As Long
Private Declare Function CloseHandle Lib "kernel32.dll" ( _
ByVal hObject As Long) As Long
Private Declare Function OpenThread Lib "kernel32.dll" ( _
ByVal dwDesiredAccess As Long, _
ByVal bInheritHandle As Boolean, _
ByVal dwThreadId As Long) As Long
Private Declare Function ResumeThread Lib "kernel32.dll" ( _
ByVal hThread As Long) As Long
Private Declare Function SuspendThread Lib "kernel32.dll" ( _
ByVal hThread As Long) As Long
Private Declare Function Thread32First Lib "kernel32.dll" ( _
ByVal hSnapshot As Long, _
ByRef lpte As THREADENTRY32) As Boolean
Private Declare Function Thread32Next Lib "kernel32.dll" ( _
ByVal hSnapshot As Long, _
ByRef lpte As THREADENTRY32) As Boolean
Private Const TH32CS_SNAPPROCESS As Long = &H2
Private Const THREAD_SUSPEND_RESUME As Long = &H2
Private Const TH32CS_SNAPTHREAD As Long = &H4
Public Thread() As THREADENTRY32
Public Sub SuspendThreads(ByVal ProcessID As Long)
Dim lCount As Long
Dim i As Long
lCount = Thread32_Enum(Thread(), ProcessID)
For i = 0 To lCount
If Thread(i).th32OwnerProcessID = ProcessID Then
Thread_Suspend CLng(Thread(i).th32ThreadID)
End If
Next
End Sub
Private Sub Thread_Suspend(ByVal ProcessID As Long)
Dim hThread As Long
Dim lSuspendCount As Long
hThread = OpenThread(THREAD_SUSPEND_RESUME, False, ProcessID)
lSuspendCount = SuspendThread(hThread)
End Sub
Private Function Thread32_Enum(ByRef Thread() As THREADENTRY32, ByVal lProcessID As Long) As Long
Dim THREADENTRY32 As THREADENTRY32
Dim hSnapshot As Long
Dim lThread As Long
ReDim Thread(0)
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, lProcessID) ': 'If hSnapShot = INVALID_HANDLE_VALUE Then Call Err_Dll(Err.LastDllError, "CreateToolHelp32Snapshoot ::: INVALID_HANDLE_VALUE failed", sLocation, "Thread32_Enum")
THREADENTRY32.dwSize = Len(THREADENTRY32)
If Thread32First(hSnapshot, THREADENTRY32) = False Then
Thread32_Enum = -1
Exit Function
Else
ReDim Thread(lThread)
Thread(lThread) = THREADENTRY32
End If
Do
If Thread32Next(hSnapshot, THREADENTRY32) = False Then
Exit Do
Else
lThread = lThread + 1
ReDim Preserve Thread(lThread)
Thread(lThread) = THREADENTRY32
End If
Loop
Thread32_Enum = lThread
End Function
Public Sub ResumeThreads(ByVal ProcessID As Long)
Dim lCount As Long
Dim i As Long
lCount = Thread32_Enum(Thread(), ProcessID)
For i = 0 To lCount
If Thread(i).th32OwnerProcessID = ProcessID Then
Thread_Resume CLng(Thread(i).th32ThreadID)
End If
Next
End Sub
Private Sub Thread_Resume(ByVal ProcessID As Long)
Dim hThread As Long
Dim lSuspendCount As Long
hThread = OpenThread(THREAD_SUSPEND_RESUME, False, ProcessID)
lSuspendCount = ResumeThread(hThread) ': If lSuspendCount = -1 Then Err_Dll Err.LastDllError, "OpenThread failed", sLocation, "Suspend_Thread"
End Sub
Code:Option Explicit
Private ID As Long
Private Sub cmdResume_Click()
If ID > 0 Then
ResumeThreads ID
End If
End Sub
Private Sub cmdShell_Click()
ID = Shell("Notepad.exe", vbMaximizedFocus)
End Sub
Private Sub cmdSuspend_Click()
If ID > 0 Then
SuspendThreads ID
End If
End Sub
thanks thanks thanks to every body
special thanks to dee-u
its workedQuote:
Code:
SuspendThreads Process_ID
To resume a thread:
Code:
ResumeThreads Process_ID
but how can i run a application and quickly get pid to suspend it?
do you have idea?
The SHELL command returns a handle to the window.Quote:
Originally Posted by kakablack
You can pass that handle to this procedure to get it's ProcessID
vb Code:
Function WindowToProcessId(ByVal hWnd As Long) As Long Dim lpProc As Long Call GetWindowThreadProcessId(hWnd, lpProc) WindowToProcessId= lpProc End Function
I actually modified my code so show a working sample, have a look!
heheQuote:
I actually modified my code so show a working sample, have a look!
are you vb brother! :)
Большое спасибо профессиональные брата
many thanks men
What does that mean?Quote:
Originally Posted by kakablack
Thank you brother, professional
:D