Link to home
Start Free TrialLog in
Avatar of joesmow
joesmow

asked on

VB.NET error using "createProcess" api call "Object reference not set to an instance of an object"

Hi

I am having a problem calling the api function "CreateProcess" to open another executable.  I brought this module from vb6 where everything worked fine.  I'm sure its something i missed.  Below is the .net code i am using.  See the "StartProcess" function at the end.

Thanks in advance




Imports System.Runtime.InteropServices

Module modProcesses


    Structure PROCESS_INFORMATION
        Dim hProcess As Int32
        Dim hThread As Int32
        Dim dwProcessId As Int32
        Dim dwThreadId As Int32
    End Structure

    Structure STARTUPINFO
        Dim cb As Int32
        Dim lpReserved As Long
        Dim lpDesktop As Long
        Dim lpTitle As Long
        Dim dwX As Int32
        Dim dwY As Int32
        Dim dwXSize As Int32
        Dim dwYSize As Int32
        Dim dwXCountChars As Int32
        Dim dwYCountChars As Int32
        Dim dwFillAttribute As Int32
        Dim dwFlags As Int32
        Dim wShowWindow As Int16
        Dim cbReserved2 As Int16
        Dim lpReserved2 As Byte
        Dim hStdInput As Int32
        Dim hStdOutput As Int32
        Dim hStdError As Int32
    End Structure



    'Shell Constants
    Public Const NORMAL_PRIORITY_CLASS As Long = &H20&
    Public Const INFINITE As Long = -1&

    Public Const STATUS_WAIT_0 As Long = &H0
    Public Const WAIT_OBJECT_0 As Long = STATUS_WAIT_0


    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

    Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hProcess As Long, ByVal dwMilliseconds As Long) As Long
    Private Declare Function InputIdle Lib "user32" Alias "WaitForInputIdle" (ByVal hProcess As Long, ByVal dwMilliseconds As Long) As Long
    Private Declare Auto Function CreateProcessA Lib "kernel32" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, ByVal lpProcessAttributes As Int32, ByVal lpThreadAttributes As Int32, _
                                    ByVal bInheritHandles As Int32, ByVal dwCreationFlags As Int32, ByVal lpEnvironment As Int32, ByVal lpCurrentDirectory As Int32, _
                                    ByVal lpStartupInfo As STARTUPINFO, _
                                    ByVal lpProcessInformation As PROCESS_INFORMATION) As Int32

    Public Function SyncShell(ByVal CommandLine As String, Optional ByVal Timeout As Long = 0, Optional ByVal WaitForInputIdle As Boolean = False, Optional ByVal Hide As Boolean = False) As Boolean
        Dim hProcess As Long
        Dim ret As Long
        Dim nMilliseconds As Long

        If Timeout > 0 Then
            nMilliseconds = Timeout
        Else
            nMilliseconds = INFINITE
        End If

        hProcess = StartProcess(CommandLine, Hide)

        If WaitForInputIdle Then
            'Wait for the shelled application to finish setting up its UI:
            ret = InputIdle(hProcess, nMilliseconds)
        Else
            'Wait for the shelled application to terminate:
            ret = WaitForSingleObject(hProcess, nMilliseconds)
        End If
        CloseHandle(hProcess)

        SyncShell = (ret = WAIT_OBJECT_0)
    End Function


    Private Function StartProcess(ByVal CommandLine As String, Optional ByVal Hide As Boolean = False) As Long
        Const STARTF_USESHOWWINDOW As Long = &H1
        Const SW_HIDE As Long = 0

        Dim proc As New PROCESS_INFORMATION
        Dim Start As New STARTUPINFO
        Dim retval As Int32



        'Initialize the STARTUPINFO structure:
        Start.cb = Len(Start)
        If Hide Then
            Start.dwFlags = STARTF_USESHOWWINDOW
            Start.wShowWindow = SW_HIDE
        End If

       
       '***************error on this line "Object reference not set to an instance of an object"
        retval = CreateProcessA("test", CommandLine, 0&, 0&, 1&, NORMAL_PRIORITY_CLASS, 0&, 0&, Start, proc)

        StartProcess = proc.hProcess
    End Function




End Module
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Hi joesmow,

Did you know you can get all of that functionality in just a couple lines of code using .Nets Process class?  Here are some code snippets:

        Dim myProcess As New Process
        Dim myStartInfo As New ProcessStartInfo("notepad.exe")

        myStartInfo.WindowStyle = ProcessWindowStyle.Hidden

        myProcess.Start(myStartInfo)

        myProcess.WaitForInputIdle() ' wait infinitely for idle state
        myProcess.WaitForInputIdle(5000) ' wait 5 seconds for idle state

        myProcess.WaitForExit() ' wait infinitely for exit
        myProcess.WaitForExit(5000) ' wait 5 seconds for exit

~IM
Avatar of joesmow
joesmow

ASKER

no, i didn't know that, thanks for telling me about it.

i have one problem with it though. i am using the following  and i get an error "No Process is associated with this object" when i call "myProcess.WaitForExit()".  Any ideas why, i know the process is still running because it is sitting on a yes/no/quit prompt

 Dim myProcess As New Process
         
            Dim myStartInfo As New ProcessStartInfo(Application.StartupPath & "\CabArc.exe", "x " & """" & Application.StartupPath & "\" & FileName & """")
            myStartInfo.WindowStyle = ProcessWindowStyle.Normal

            myProcess.Start(myStartInfo)

            myProcess.WaitForExit()
ASKER CERTIFIED SOLUTION
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America 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
Avatar of joesmow

ASKER

thanks alot IM

If you know of any good links to find out about .net classes that make api calls such as this one unnecessary i would appreciate it.

Thanks again for the quick answer