代碼實現VB.NET Smartphone進程啟動案例
學習VB.NET Smartphone時,你可能會遇到VB.net實現Smartphone中進程啟動問題,這里將介紹VB.NET Smartphone進程啟動問題的解決方法,在這里拿出來和大家分享一下。開始時聲明時老是將ShellExecuteEx 和CreateProcess這兩個熟悉得不能再熟悉的Win32在VB 6中的聲明直接粘到程序中,僅是將VB6的long改為NET的int32,結果老是報錯。在網上查了N天資料,才發現原來Win CE的核心API都是在一個coredll.dll文件中,使得我差點沒氣死!
#T#還有一點是SHELLEXECUTEINFO結構中的lpFile這種指向字符串常量的指針由于字符的編碼問題不能象在Win32編程中簡單聲明為String類型,所在必須聲明為Intptr,這樣問題就出現了,使用 ShellExecuteEx函數必須使用微軟在VB.net中不直接提供的指針操作,所以我只好根據網上的資料改寫了一個VB.net對內存指針的封裝類,詳細VB.NET Smartphone代碼及解釋如下(新建一個模塊,將以下代碼粘貼進去即可使用):
- Imports System.Runtime.InteropServices '引及Net框架中對底層操作支持的命名空間
- Public Class clsDAMSMobileMarshal '我寫的內存管理類
- #Region "與內存有關的API聲明"
- REM 以下是與內存有關的移動設備API
- Public Declare Function LocalAlloc Lib "coredll.dll" Alias "LocalAlloc" (ByVal wFlags As Int32, _
- ByVal wBytes As Int32) As IntPtr
- Public Declare Function LocalFree Lib "coredll.dll" Alias "LocalFree" (ByVal hMem As Int32) As Int32
- Public Declare Function LocalLock Lib "coredll.dll" Alias "LocalLock" (ByVal hMem As Int32) As Int32
- Public Declare Function LocalReAlloc Lib "coredll.dll" Alias "LocalReAlloc" (ByVal hMem As IntPtr, _
- ByVal wBytes As Int32, ByVal wFlags As Int32) As IntPtr
- #End Region
- #Region "API常量聲明"
- Public Const LMEM_FIXED = 0
- Public Const LMEM_MOVEABLE = &H2
- Public Const LMEM_ZEROINIT = &H40
- Public Const LPTR = LMEM_FIXED Or LMEM_ZEROINIT
- #End Region
- Public Shared Function fnAllocHLocal(ByVal ni_i32Size As Int32) As IntPtr
- '申請本地內存,返回一個指向該內存塊的指針
- Return LocalAlloc(LPTR, ni_i32Size)
- End Function
- Public Shared Function fnFreeHLocal(ByRef ni_pLocal As IntPtr) As Int32
- REM 釋放指定的內存塊柄
- Dim ti32FunctionReturnValue As Int32
- If ni_pLocal.Equals(IntPtr.Zero) = False Then
- ti32FunctionReturnValue = (LocalFree(ni_pLocal.ToInt32))
- If ti32FunctionReturnValue = 0 Then
- ni_pLocal = IntPtr.Zero
- End If
- End If
- Return (ti32FunctionReturnValue)
- End Function
- Public Shared Function fnReAllocHLocal(ByVal ni_pIn As IntPtr, ByVal ni_i32Size As Int32) As IntPtr
- '對指定的內存塊重新定義大小
- Return LocalReAlloc(ni_pIn, ni_i32Size, LMEM_MOVEABLE)
- End Function
- Public Shared Function fnStringToHLocalUni(ByVal ni_strIn As String) As IntPtr
- '將指定的字符串復制到一個內存塊中,并返回該內存塊的指針,這個指針必須使用fnFreeHLocal函數釋放
- Dim ti32StringBufLength As Int32
- Dim tpTempA As IntPtr
- If Not (ni_strIn Is Nothing) Then
- If ni_strIn.Length = 0 Then
- Return IntPtr.Zero
- Else
- ti32StringBufLength = (ni_strIn.Length + 1) * 2 ' 包括***一個中止字符
- tpTempA = fnAllocHLocal(ti32StringBufLength)
- If tpTempA.Equals(IntPtr.Zero) = False Then '申請內存成功
- Marshal.Copy(ni_strIn.ToCharArray, 0, tpTempA, ni_strIn.Length)
- Return tpTempA
- End If
- End If
- End If
- End Function
- End Class
- 有了這個輔助函數,以下的API調用就簡單了,只需正確聲明即可,以下是ShellExecuteEx及CreateProcess涵數及其結構的正確聲明(同樣是將代碼粘貼到一個新建模塊中即可調用):
- imports System.Runtime.InteropServices
- REM API常數聲明-------------------------
- Public Const SW_SHOWNORMAL = 1
- Public Const gcNORMAL_PRIORITY_CLASS = &H20
- Public Const gcINFINITE = &HFFFF
- Public Const WAIT_TIMEOUT = &H102&
- #Region "Structure SHELLEXECUTEINFO"
- <StructLayout(LayoutKind.Sequential)> _
- Structure SHELLEXECUTEINFO
- Public cbSize As Int32
- Public fMask As Int32
- Public hwnd As IntPtr
- Public lpVerb As IntPtr 'LPCTSTR,這種類型不能聲明為string,只可以老老實實聲明為Intptr
- Public lpFile As IntPtr 'LPCTSTR,這種類型不能聲明為string,只可以老老實實聲明為Intptr
- Public lpParameters As IntPtr 'LPCTSTR,這種類型不能聲明為string,只可以老老實實聲明為Intptr
- Public lpDirectory As IntPtr 'LPCTSTR,這種類型不能聲明為string,只可以老老實實聲明為Intptr
- Public nShow As Int32
- Public hInstApp As IntPtr
- 'Optional members
- Public lpIDList As IntPtr 'LPVOID
- Public lpClass As IntPtr 'LPCTSTR
- Public hkeyClass As Int32
- Public dwHotKey As Int32
- Public hIcon As Int32
- Public hProcess As IntPtr
- Public Sub Dispose()
- '在調用后釋放結構中的內存塊
- clsDAMSMobileMarshal.fnFreeHLocal(Me.lpVerb)
- clsDAMSMobileMarshal.fnFreeHLocal(Me.lpFile)
- clsDAMSMobileMarshal.fnFreeHLocal(Me.lpParameters)
- clsDAMSMobileMarshal.fnFreeHLocal(Me.lpDirectory)
- End Sub
- End Structure
- #End Region
- #Region "Structure STARTUPINFO"
- <StructLayout(LayoutKind.Sequential)> _
- Public Structure STARTUPINFO
- Public cb As Int32
- Public lpReserved As IntPtr
- Public lpDesktop As IntPtr
- Public lpTitle As IntPtr
- Public dwX As Int32
- Public dwY As Int32
- Public dwXSize As Int32
- Public dwYSize As Int32
- Public dwXCountChars As Int32
- Public dwYCountChars As Int32
- Public dwFillAttribute As Int32
- Public dwFlags As Int32
- Public wShowWindow As Int16
- Public cbReserved2 As Int16
- Public lpReserved2 As Int32
- Public hStdInput As Int32
- Public hStdOutput As Int32
- Public hStdError As Int32
- End Structure
- #End Region
- #Region "Structure PROCESS_INFORMATION"
- <StructLayout(LayoutKind.Sequential)> _
- Public Structure PROCESS_INFORMATION
- Public hProcess As IntPtr
- Public hThread As IntPtr
- Public dwProcessId As Int32
- Public dwThreadId As Int32
- End Structure
- #End Region
- REM api函數聲明
- #Region "Function CreateProcess"
- public Overloads Declare Function CreateProcess Lib "coredll.dll" (ByVal imageName As String, _
- ByVal cmdLine As String, _
- ByVal lpProcessAttributes As IntPtr, _
- ByVal lpThreadAttributes As IntPtr, _
- ByVal boolInheritHandles As Int32, _
- ByVal dwCreationFlags As Int32, _
- ByVal lpEnvironment As IntPtr, _
- ByVal lpszCurrentDir As IntPtr, _
- ByRef si As STARTUPINFO, _
- ByRef pi As PROCESS_INFORMATION _
- ) As Integer
- #End Region
- #Region "Function CloseHandle"
- Public Declare Function CloseHandle Lib "CoreDll.dll" (ByVal Handle As IntPtr) As Int32
- #End Region
- #Region "Function WaitForSingleObjectEx"
- Public Declare Function WaitForSingleObjectEx Lib "coredll.dll" (ByVal hHandle As IntPtr, _
- ByVal dwMilliseconds As Int32, _
- ByVal bAlertable As Int32 _
- ) As Int32
- #End Region
- #Region "Function ShellExecuteEx"
- Public Declare Function ShellExecuteEx Lib "coredll