Link to home
Start Free TrialLog in
Avatar of joseph99
joseph99

asked on

(Urgent) Running Some Other Program (Another Exe) From Visual Basic

Hi Experts,

We are making a project, in which the main is a Stock management for a company which is made in VB and it comprises of the 90% part of the project. A simple module was also there which was made by my colleagues in Win32 SDK (using VC++).

Now what I have to do is, since VB Program (Stock One), is the main program (EXE), I am told by my boss, to run the second module (.exe of Win32), from a particular Form-Button from VB. Lets take the button as SHOW MODULE. What I require is when a user click this button, the second exe should run, and my main VB program should gets disabled (inactive), means the user cannot switch to my VB Program unless and until, he/she closes the second module exe, run by it.
Meanwhile the user can work in second exe and when finishes close it, my VB Program should get notification, and whould get enabled and active.

Most important all I have to do in VB, not taking any help of VC. And I am completely Unware Of SDK, so be detailed for any soultion which you suggest.

Also I would like to know that Is there any control also, by which above things can be made possible. Because, then the second module exe will run within VB Control only, and it will look more good.

Best Regards
Joseph

Avatar of TimCottee
TimCottee
Flag of United Kingdom of Great Britain and Northern Ireland image

The following code example when placed in a module should achieve the desired result:

Const INFINITE = &HFFFF
Const STARTF_USESHOWWINDOW = &H1
Private Enum enSW
    SW_HIDE = 0
    SW_NORMAL = 1
    SW_MAXIMIZE = 3
    SW_MINIMIZE = 6
End Enum
Private Type PROCESS_INFORMATION
    hProcess As Long
    hThread As Long
    dwProcessId As Long
    dwThreadId As Long
End Type
Private Type STARTUPINFO
    cb As Long
    lpReserved As String
    lpDesktop As String
    lpTitle As String
    dwX As Long
    dwY As Long
    dwXSize As Long
    dwYSize As Long
    dwXCountChars As Long
    dwYCountChars As Long
    dwFillAttribute As Long
    dwFlags As Long
    wShowWindow As Integer
    cbReserved2 As Integer
    lpReserved2 As Byte
    hStdInput As Long
    hStdOutput As Long
    hStdError As Long
End Type
Private Type SECURITY_ATTRIBUTES
    nLength As Long
    lpSecurityDescriptor As Long
    bInheritHandle As Long
End Type
Private Enum enPriority_Class
    NORMAL_PRIORITY_CLASS = &H20
    IDLE_PRIORITY_CLASS = &H40
    HIGH_PRIORITY_CLASS = &H80
End Enum
Private Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, lpProcessAttributes As SECURITY_ATTRIBUTES, lpThreadAttributes As SECURITY_ATTRIBUTES, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, lpEnvironment As Any, ByVal lpCurrentDriectory As String, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long

Public Function SuperShell(ByVal App As String, ByVal WorkDir As String, dwMilliseconds As Long, Optional ByVal start_size As enSW = SW_NORMAL, Optional ByVal Priority_Class As enPriority_Class = HIGH_PRIORITY_CLASS) As Boolean
    Dim pclass As Long
    Dim sinfo As STARTUPINFO
    Dim pinfo As PROCESS_INFORMATION
    'Not used, but needed
    Dim sec1 As SECURITY_ATTRIBUTES
    Dim sec2 As SECURITY_ATTRIBUTES
    'Set the structure size
    sec1.nLength = Len(sec1)
    sec2.nLength = Len(sec2)
    sinfo.cb = Len(sinfo)
    'Set the flags
    sinfo.dwFlags = STARTF_USESHOWWINDOW
    'Set the window's startup position
    sinfo.wShowWindow = start_size
    'Set the priority class
    pclass = Priority_Class
    'Start the program
    If CreateProcess(vbNullString, App, sec1, sec2, False, pclass, _
    0&, WorkDir, sinfo, pinfo) Then
        'Wait
        WaitForSingleObject pinfo.hProcess, dwMilliseconds
        SuperShell = True
    Else
        SuperShell = False
    End If
End Function

You can call the function in the module using:

    SuperShell "c:\MyProgram\MySecondExe", "c:\MyProgram", 0

As for a control which will do this for you, that is perhaps more problematic. It might be possible immediately after the create process call to identify the window handle that is created by the new program and use the SetParent API call to change it's parent window from the desktop to your VB applications form. This would have the effect of displaying the new application within the host form of the VB application. This is perhaps a risky method as setparent is not always a good thing to use and it would depend very much on the window(s) created by the second application. On the whole I would probably recommend that you don't try this straightaway as without seeing the applications involved I couldn't comment on how well this would work.

Avatar of Ryan Chong
<Listening..>
Avatar of mariab_
mariab_

Hi, TimCottee,

I have tried the code you posted here.

It does not work.

Yest it starts an application, but the strating application is pretty available operational and accessible to the user. And it is possible for the user to perform actions over it even the second application is still running (including close of the first app).

Regards
p.s.
I am using Win2000 Proffesional
Maria,

1. Set a reference to Windows Scripting Host Object Model
2. Try this:

Private Sub Command1_Click()
Dim oShell As IWshShell
   
    Me.Enabled = False
    Set oShell = New IWshShell_Class
    oShell.Run "notepad.exe", 1, True
    MsgBox "I'm back"
   
End Sub
correction:

Private Sub Command1_Click()
Dim oShell As IWshShell
   
    Me.Enabled = False
    Set oShell = New IWshShell_Class
    oShell.Run "notepad.exe", 1, True
    MsgBox "I'm back"
    Me.Enabled = True
   
End Sub
try this

in a module
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal Handle As Long, ByVal dwMilliseconds As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwAccess As Long, ByVal fInherit As Integer, ByVal hObject As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long



Public Function WaitForProcess(taskId As Long, Optional milliseconds As Long = -1) As Boolean
   
    Dim procHandle As Long
   
    Const ProcedureName = "WaitForProcess"
   
    On Error GoTo ErrHandle
   
    procHandle = OpenProcess(&H100000, True, taskId)
    WaitForProcess = WaitForSingleObject(procHandle, milliseconds) <> -1
    CloseHandle procHandle
end function


behind your button
dim lTaskId as long
lTaskId = Shell(yourprogramhere)
WaitForProcess(lTaskId, 1000)
you can also shell to the app,disable the form, and start a timer that checks if second application is still active, if not active , then enable the first application and stop the timer
arana,

When the form is disabled, so is the timer.

gbaren
Hi!

Use this : )

Download...
http://www.vb-helper.com/Howto/minwind.zip
Description: Find a window using its title and minimize it (3K)

OR This (which is much better)

Download...
http://www.vb-helper.com/Howto/findwnd2.zip
Description: See if a window is running in 3 ways (3K)

I suppose cou could find out the window caption/program caption (either from toolbar or Ctrl+Alt+Del window - depending on which of the above code you use) of the other program.  Once you've achieved that, just place the code in a timer (interval 1000, enabled = True) to keep checking for that caption.  If that caption exists, disable your program (Me.Enabled = False).  If not, enable your program (Me.Enabled = True).

That's it!

glass cookie : )

PS. Happy programming : )
Avatar of joseph99

ASKER

Thanks for all for such a good dicussion. I have tried anyone's approach except TimCottee. And waht I get is : mariab. He/She is perfectly right, in what it says. The code by TimCottee works well upto the starting of application, but doesn't disable the main VB-Application.

I haven't tried other approaches, but will try, maximum by tomorrow, and will let you know as soon as possible.

Thanks All Once Again

Best Regards
Joseph

ASKER CERTIFIED SOLUTION
Avatar of TimCottee
TimCottee
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
found some code for that, look longer than cotee's, but maybe not much after removing the comments:

http://www.planetsourcecode.com/xq/ASP/txtCodeId.3716/lngWId.1/qx/vb/scripts/ShowCode.htm
joseph99

Please finalise this question, even if nobody gave you a satisfactory answer - in that case just let me know and I will be happy to refund your points to you.

If someone did give you a satisfactory answer, please accept the comment as the answer. If you are having problems doing that let me know.

Please do *not* ignore this request. To the other participants in the thread - if no response is forthcoming alert me and I will take action.

Regards

modder
Community Support Admin