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.InteropServ ices
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(hProce ss, 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
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.InteropServ
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(hProce
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
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(Applicati on.Startup Path & "\CabArc.exe", "x " & """" & Application.StartupPath & "\" & FileName & """")
myStartInfo.WindowStyle = ProcessWindowStyle.Normal
myProcess.Start(myStartInf o)
myProcess.WaitForExit()
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()".
Dim myProcess As New Process
Dim myStartInfo As New ProcessStartInfo(Applicati
myStartInfo.WindowStyle = ProcessWindowStyle.Normal
myProcess.Start(myStartInf
myProcess.WaitForExit()
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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
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
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.
myStartInfo.WindowStyle = ProcessWindowStyle.Hidden
myProcess.Start(myStartInf
myProcess.WaitForInputIdle
myProcess.WaitForInputIdle
myProcess.WaitForExit() ' wait infinitely for exit
myProcess.WaitForExit(5000
~IM