calling C program from Visual basic and runnig both simultaneously

I need to invoke a C program from Visual basic.This C program does some calculations which takes approx. an hour and write  results in a file. What i need is to invoke this C Program from VB and then control should come back to Visual basic program so that processing is going at the end and C program is writing data in File and user is able to work on UI(Visual basic) as well.
Is it possible?
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Mohammed NasmanSoftware DeveloperCommented:

  Use CreateProcess API to lunch the C application, and use WaitForSingleObject API, to make your VB application wait till the lunched program finish, then the control will back to your VB applicationa will continue it's work

this is not the best option, maybe using Com Exe with Callback function will be better option, but I didn't tried that before

IF you don't want to wait for C program to finish, Just use Shell command to start your C program
You can shell to the program and make it dump the output to a text file using "> filename.txt" at the end of the command line.

Then you can check every so often to see if the app is running. Use the code below to return if its running

Msgbox IsAppRunning("c:\windows\system32\calc.exe")

Private Declare Function GetWindowsDirectory Lib "kernel32" Alias "GetWindowsDirectoryA" ( _
    ByVal lpBuffer As String, _
    ByVal nSize As Long) As Long
Public Declare Function Process32First Lib "kernel32" ( _
    ByVal hSnapshot As Long, _
    lppe As PROCESSENTRY32) As Long
Public Declare Function Process32Next Lib "kernel32" ( _
    ByVal hSnapshot As Long, _
    lppe As PROCESSENTRY32) As Long
Public Declare Function CloseHandle Lib "Kernel32.dll" ( _
    ByVal Handle As Long) As Long
Public Declare Function OpenProcess Lib "Kernel32.dll" ( _
    ByVal dwDesiredAccessas As Long, _
    ByVal bInheritHandle As Long, _
    ByVal dwProcId As Long) As Long
Public Declare Function EnumProcesses Lib "psapi.dll" ( _
    ByRef lpidProcess As Long, _
    ByVal cb As Long, ByRef cbNeeded As Long) As Long
Public Declare Function GetModuleFileNameExA Lib "psapi.dll" ( _
    ByVal hProcess As Long, _
    ByVal hModule As Long, _
    ByVal strModuleName As String, _
    ByVal nSize As Long) As Long
Public Declare Function EnumProcessModules Lib "psapi.dll" ( _
    ByVal hProcess As Long, _
    ByRef lphModule As Long, _
    ByVal cb As Long, ByRef cbNeeded As Long) As Long
Public Declare Function CreateToolhelp32Snapshot Lib "kernel32" ( _
    ByVal dwFlags As Long, _
    ByVal th32ProcessID As Long) As Long
Public Declare Function GetVersionExA Lib "kernel32" ( _
    lpVersionInformation As OSVERSIONINFO) As Integer

   dwSize As Long
   cntUsage As Long
   th32ProcessID As Long           ' This process
   th32DefaultHeapID As Long
   th32ModuleID As Long            ' Associated exe
   cntThreads As Long
   th32ParentProcessID As Long     ' This process's parent process
   pcPriClassBase As Long          ' Base priority of process threads
   dwFlags As Long
   szExeFile As String * 260       ' MAX_PATH
End Type

   dwOSVersionInfoSize As Long
   dwMajorVersion As Long
   dwMinorVersion As Long
   dwBuildNumber As Long
   dwPlatformId As Long           '1 = Windows 95.
                                  '2 = Windows NT

   szCSDVersion As String * 128
End Type

Public Const PROCESS_VM_READ = 16
Public Const MAX_PATH = 260
Public Const SYNCHRONIZE = &H100000
Public Const TH32CS_SNAPPROCESS = &H2&
Public Const hNull = 0

Public Enum ePlatform
    eWin95_98 = 1
    eWinNT = 2
End Enum

Public gDBType As String

Public Function IsAppRunning(pEXEName As String) As Boolean

    On Error Resume Next
    Select Case getVersion()
    Case eWin95_98
            Dim lProc As Long, _
    strName As String
            Dim hSnap As Long, _
    proc As PROCESSENTRY32
            hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
            If hSnap = hNull Then Exit Function
            proc.dwSize = Len(proc)
            ' Iterate through the processes
            lProc = Process32First(hSnap, proc)
            Do While lProc
                strName = StrZToStr(proc.szExeFile)
                If InStr(UCase(strName), UCase( _
    pEXEName)) Then
                    IsApplicationRunning = True
                    Exit Function
                End If
                lProc = Process32Next(hSnap, proc)
    Case eWinNT
        Dim cb As Long
        Dim cbNeeded As Long
        Dim NumElements As Long
        Dim lProcessIDs() As Long
        Dim cbNeeded2 As Long
        Dim lNumElements2 As Long
        Dim lModules(1 To 200) As Long
        Dim lRet As Long
        Dim strModuleName As String
        Dim nSize As Long
        Dim hProcess As Long
        Dim I As Long
        'Get the array containing the process id's for each process object
        cb = 8
        cbNeeded = 96
        Do While cb <= cbNeeded
            cb = cb * 2
            ReDim lProcessIDs(cb / 4) As Long
            lRet = EnumProcesses(lProcessIDs(1), cb, cbNeeded)
        NumElements = cbNeeded / 4
        For I = 1 To NumElements
            'Get a handle to the Process
            hProcess = OpenProcess(PROCESS_QUERY_INFORMATION _
            Or PROCESS_VM_READ, 0, lProcessIDs(I))
            'Got a Process handle
            If hProcess <> 0 Then
                'Get an array of the module handles for the specified
                lRet = EnumProcessModules(hProcess, lModules(1), 200, _
                'If the Module Array is retrieved, Get the ModuleFileName
                If lRet <> 0 Then
                    strModuleName = Space(MAX_PATH)
                    nSize = 500
                    lRet = GetModuleFileNameExA(hProcess, lModules(1), _
                    strModuleName, nSize)
                    strModuleName = Left(strModuleName, lRet)
                    'Check for the client application running
                    If InStr(UCase(strModuleName), _
    UCase(pEXEName)) Then
                        IsApplicationRunning = True
                        Exit Function
                    End If
                    'List1.AddItem Left(strModuleName, lRet)
                End If
            End If
            'Close the handle to the process
            lRet = CloseHandle(hProcess)
    End Select
End Function

Function StrZToStr(pString As String) As String
   StrZToStr = Left$(pString, Len(pString) - 1)
End Function

Public Function getVersion() As ePlatform
   Dim osinfo As OSVERSIONINFO
   Dim lRetVal As Integer
   osinfo.dwOSVersionInfoSize = 148
   osinfo.szCSDVersion = Space$(128)
   lRetVal = GetVersionExA(osinfo)
   getVersion = osinfo.dwPlatformId
End Function


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.