CreateProcess, using Visual Basic, doesn't create a process

Jim Webb 41 Reputation points
2023-08-26T09:03:31.3366667+00:00

I'm having difficulties with using CreateProcess in Visual Basic. The purpose is to open NotePad in a particular place on the screen and with a specific size. This the code I am using so far (after many errors & tests):

Structure SECURITY_ATTRIBUTES
	Dim nLength As Integer
	Dim lpSecurityDescriptor As IntPtr
End Structure

Enum CreationFlags
	CreateSuspended = &H4
	DetachedProcess = &H8
	CreateNoWindow = &H8000000
	ExtendedStartupInfoPresent = &H80000
End Enum

Structure STARTUPINFO
	Dim cb As Integer
	Dim lpReserved As String
	Dim lpDesktop As String
	Dim lpTitle As String
	Dim dwX As Integer
	Dim dwY As Integer
	Dim dwXSize As Integer
	Dim dwYSize As Integer
	Dim dwXCountChars As Integer
	Dim dwYCountChars As Integer
	Dim dwFillAttributes As Integer
	Dim dwFlags As Integer
	Dim wShowWindow As Integer
	Dim cbReserved As Integer
	Dim lpReserved2 As Integer
	Dim hStdInput As Integer
	Dim hStdOutput As Integer
	Dim hStdErr As Integer
End Structure

Structure STARTUPINFOEX
	Dim StartupInfo As STARTUPINFO
	Dim lpAttributeList As IntPtr
End Structure

Structure PROCESS_INFORMATION
	Dim hProcess As IntPtr
	Dim hThread As IntPtr
	Dim dwProcessId As Integer
	Dim dwThreadId As Integer
End Structure

Const EXTENDED_STARTUPINFO_PRESENT As UInteger = &H80000

Const STARTF_USEPOSITION = &H4          ' The dwX & dwY members contain additional information.
Const STARTF_USESHOWWINDOW = &H1        ' The wShowWindow member contains additional information.
Const STARTF_USESIZE = &H2              ' The dwXSize & dwYSize members contain additional information.

<DllImport("kernel32.dll", SetLastError:=True)>
Shared Function CreateProcess(lpApplicationName As String,
							  lpCommandLine As String,
							  ByRef lpProcessAttributes As SECURITY_ATTRIBUTES,
							  ByRef lpThreadAttributes As SECURITY_ATTRIBUTES,
							  bInheritHandles As Boolean,
							  dwCreationFlags As UInt32,
							  lpEnvironment As IntPtr,
							  lpCurrentDirectory As String,
							  ByRef lpStartupInfo As STARTUPINFO,
							  ByRef lpProcessInformation As PROCESS_INFORMATION) As Boolean
End Function

Friend Shared Sub StartupNotepad()

	Dim retValue As Boolean
	Dim Application As String = "notepad"
	Dim CommandLine As String = ""
	Dim pInfo As PROCESS_INFORMATION = New PROCESS_INFORMATION()
	Dim sInfo As STARTUPINFO = New STARTUPINFO()
	Dim pSec As SECURITY_ATTRIBUTES = New SECURITY_ATTRIBUTES()
	Dim tSec As SECURITY_ATTRIBUTES = New SECURITY_ATTRIBUTES()
	pSec.nLength = pSec.lpSecurityDescriptor.ToInt32
	tSec.nLength = tSec.lpSecurityDescriptor.ToInt32
	Dim CreationFlags As UInt32 = EXTENDED_STARTUPINFO_PRESENT
	Dim Environ As IntPtr
	Dim ThisDir As String = Environment.CurrentDirectory
	sInfo.dwX = 10
	sInfo.dwY = 10
	sInfo.dwXSize = 100
	sInfo.dwYSize = 400
	sInfo.dwFlags = STARTF_USEPOSITION + STARTF_USESIZE + STARTF_USESHOWWINDOW
	sInfo.lpReserved = ""
	sInfo.cb = Len(sInfo)

	retValue = CreateProcess(Application, CommandLine, pSec, tSec, False, CreationFlags, Environ, vbNull, sInfo, pInfo)

End Sub

I don't appear to be getting any error messages but retValue returns false every time and no new NotePad window appears when I call StartupNotepad. Any clues as to what I am (clearly) doing wrong would be appreciated.

Developer technologies VB
Developer technologies Visual Studio Other
0 comments No comments
{count} votes

Accepted answer
  1. Castorix31 90,521 Reputation points
    2023-08-26T10:20:28.46+00:00

    This test works for me (except position/size, read from registry for Notepad as I commented...) :

            Dim pSec As SECURITY_ATTRIBUTES = New SECURITY_ATTRIBUTES()
            Dim tSec As SECURITY_ATTRIBUTES = New SECURITY_ATTRIBUTES()
            pSec.nLength = Marshal.SizeOf(pSec)
            tSec.nLength = Marshal.SizeOf(tSec)
            'Dim sApplicationName = "C:\WINDOWS\system32\notepad.exe"
            Dim sApplicationName = Nothing
            Dim sCommandLine = "notepad.exe"
            Dim nCreationFlags = NORMAL_PRIORITY_CLASS
            Dim sInfo As STARTUPINFO = New STARTUPINFO()
            sInfo.cb = Marshal.SizeOf(sInfo)
            sInfo.dwFlags = STARTF_USEPOSITION Or STARTF_USESIZE Or STARTF_USESHOWWINDOW
            sInfo.wShowWindow = SW_SHOWNORMAL
            ' Ignored : read from HKEY_CURRENT_USER\SOFTWARE\Microsoft\Notepad
            sInfo.dwX = 10
            sInfo.dwY = 10
            sInfo.dwXSize = 100
            sInfo.dwYSize = 400
            Dim pInfo As PROCESS_INFORMATION = New PROCESS_INFORMATION()
            Dim bRet = CreateProcess(sApplicationName, sCommandLine, pSec, tSec, False, nCreationFlags, IntPtr.Zero, Nothing, sInfo, pInfo)
            If (Not bRet) Then
                Dim nErr = Marshal.GetLastWin32Error()
                ' ...
            End If
    

    With :

       <DllImport("Kernel32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
        Public Shared Function CreateProcess(lpApplicationName As String, lpCommandLine As String, ByRef lpProcessAttributes As SECURITY_ATTRIBUTES,
                                             ByRef lpThreadAttributes As SECURITY_ATTRIBUTES, bInheritHandles As Boolean, dwCreationFlags As UInteger,
                                             lpEnvironment As IntPtr, lpCurrentDirectory As String,
                                             <[In]> ByRef lpStartupInfo As STARTUPINFO, <Out> ByRef lpProcessInformation As PROCESS_INFORMATION) As Boolean
        End Function
    
    
        <StructLayout(LayoutKind.Sequential)>
        Public Structure SECURITY_ATTRIBUTES
            Public nLength As Integer
            Public lpSecurityDescriptor As IntPtr
            Public bInheritHandle As Integer
        End Structure
    
        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
        Public Structure STARTUPINFO
            Public cb As Integer
            Public lpReserved As String
            Public lpDesktop As String
            Public lpTitle As String
            Public dwX As Integer
            Public dwY As Integer
            Public dwXSize As Integer
            Public dwYSize As Integer
            Public dwXCountChars As Integer
            Public dwYCountChars As Integer
            Public dwFillAttribute As Integer
            Public dwFlags As Integer
            Public wShowWindow As Short
            Public cbReserved2 As Short
            Public lpReserved2 As IntPtr
            Public hStdInput As IntPtr
            Public hStdOutput As IntPtr
            Public hStdError As IntPtr
        End Structure
    
        <StructLayout(LayoutKind.Sequential)>
        Public Structure PROCESS_INFORMATION
            Public hProcess As IntPtr
            Public hThread As IntPtr
            Public dwProcessId As Integer
            Public dwThreadId As Integer
        End Structure
    
        Public Const NORMAL_PRIORITY_CLASS = &H20
    
        Public Const STARTF_USESHOWWINDOW = &H1
        Public Const STARTF_USESIZE = &H2
        Public Const STARTF_USEPOSITION = &H4
        Public Const STARTF_USECOUNTCHARS = &H8
        Public Const STARTF_USEFILLATTRIBUTE = &H10
        Public Const STARTF_RUNFULLSCREEN = &H20  ' ignored for non-x86 platforms
        Public Const STARTF_FORCEONFEEDBACK = &H40
        Public Const STARTF_FORCEOFFFEEDBACK = &H80
        Public Const STARTF_USESTDHANDLES = &H100
        Public Const STARTF_USEHOTKEY = &H200
        Public Const STARTF_TITLEISLINKNAME = &H800
        Public Const STARTF_TITLEISAPPID = &H1000
        Public Const STARTF_PREVENTPINNING = &H2000
        Public Const STARTF_UNTRUSTEDSOURCE = &H8000
    
        Public Const SW_SHOWNORMAL = 1
    
    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.