Could Not load sms.dll
- Hi ,
I'm using windows mobile 6.0 and VS 2005. I 'm trying to built an application which will send sms.
I have tried a lot of things.
First I have created a device application in VS 2005
I have added references in my project and also I have put the following lines of code in me form
Imports Microsoft.WindowsMobile.PocketOutlook
Imports Microsoft.WindowsMobile.PocketOutlook.MessageInterception
Then I have tried the following code
Dim VBMobileSMS As New SmsMessage("11255888", "this is a test")
VBMobileSMS.Send()
But I am always getting an exception . When I run it in the classic emulator I got this
Could not load 'sms.dll'
So after a little search I have downloaded an Example for compact framework and added two classes in my project.
The Marshal class
Imports System
Imports interopserv = System.Runtime.InteropServices
Imports System.ComponentModel
'Namespace NetCF.Runtime.InteropServices
Public NotInheritable Class Marshal
Private Class WinApi
Public Const LMEM_FIXED As Long = 0
Public Const LMEM_MOVEABLE As Long = 2
Public Const LMEM_ZEROINIT As Long = &H40
Public Const LPTR As Long = LMEM_FIXED Or LMEM_ZEROINIT
'private constructor prevents instantiation
Private Sub New()
End Sub
' imported functions
<System.Runtime.InteropServices.DllImport("coredll.dll", SetLastError:=True)> _
Public Shared Function LocalAlloc(ByVal uFlags As System.Int32, ByVal uBytes As System.Int32) As IntPtr
End Function
<System.Runtime.InteropServices.DllImport("coredll.dll", SetLastError:=True)> _
Public Shared Function LocalFree(ByVal hMem As IntPtr) As IntPtr
End Function
<System.Runtime.InteropServices.DllImport("coredll.dll", SetLastError:=True)> _
Public Shared Function LocalReAlloc(ByVal hMem As IntPtr, ByVal uBytes As System.Int64, ByVal fuFlags As System.Int64) As IntPtr
End Function
End Class 'WinApi
'private contructor prevents instantiation
Private Sub New()
End Sub
'memory allocation / deallocation methods
'/ Allocates a block of memory using LocalAlloc.
'/ <param name="cb">The number of bytes in memory required.</param>
'/ <returns>
'/ An IntPtr to the newly allocated memory. This memory must be
'/ released using the Marshal.FreeHLocal method.
'/ </returns>
'/ <exception cref="OutOfMemoryException">
'/ There is insufficient memory to satisfy the request.
'/ </exception>
'/ <remarks>
'/ AllocHlocal exposes the LocalAlloc WinCE API from CoreDll.dll.
'/ For additional information about LocalAlloc, see the MSDN Library.
Public Shared Function AllocHLocal(ByVal cb As Int32) As IntPtr
Try
Return WinApi.LocalAlloc(WinApi.LPTR, cb)
Catch ex As Exception
End Try
End Function
'/ Frees memory previously allocated from the unmanaged memory
'/ of the process with AllocHLocal.
'/ <param name="hlocal">The handle returned by the original matching call to AllocHLocal.</param>
'/ <exception cref="Win32Exception">
'/ Indicates failure. The exception contains the error code obtained from GetLastError.
'/ </exception>
'/ <remarks>
'/ You can use FreeHlocal to free any memory from the heap allocated by AllocHLocal or
'/ ReAllocHLocal, or any equivalent unmanaged API method. If the hlocal parameter is a
'/ null reference (Nothing in Visual Basic), the method does nothing. FreeHlOCAL exposes
'/ the LocalFree function from CoreDll.DLL, which frees all bytes so that you can no longer
'/ use the memory pointed to by <paramref name="hLocal"/>. For additional information about
'/ LocalFree, see the MSDN Library.
Public Shared Sub FreeHLocal(ByVal hlocal As IntPtr)
'If hlocal <> IntPtr.Zero Then
If hlocal.ToInt32 <> 0 Then
'If IntPtr.Zero <> WinApi.LocalFree(hlocal) Then
If WinApi.LocalFree(hlocal).ToInt32 <> 0 Then
Throw New Win32Exception(interopserv.Marshal.GetLastWin32Error())
End If
hlocal = IntPtr.Zero
End If
End Sub
'/ Resizes a block of memory previously allocated with AllocHLocal.
'/ <param name="pv">A pointer to memory allocated with AllocHLocal.</param>
'/ <param name="cb">The new size of the allocated block.</param>
'/ <returns>
'/ An IntPtr to the reallocated memory. This memory must be released
'/ using Marshal.FreeHLocal.
'/ </returns>
'/ <exception cref="OutOfMemoryException">
'/ There is insufficient memory to satisfy the request.
'/ </exception>
'/ <remarks>
'/ ReAllocHLocal exposes the LocalRealloc WinCE API method from CoreDll.dll.
'/ The returned pointer can differ from the original. For additional information
'/ about LocalAlloc, see the MSDN Library.
'/ </remarks>
Public Shared Function ReAllocHLocal(ByVal pv As IntPtr, ByVal cb As Integer) As IntPtr
Dim newMem As IntPtr = WinApi.LocalReAlloc(pv, CType(cb, System.Int64), WinApi.LMEM_MOVEABLE)
'If newMem = IntPtr.Zero Then
If newMem.ToInt32 = 0 Then
Throw New OutOfMemoryException
End If
Return newMem
End Function
'/ Copies the contents of a managed String into unmanaged memory.
'/ <param name="s">A managed string to be copied.</param>
'/ <returns>
'/ The address, in unmanaged memory, to where the s was copied, or 0 if a null reference
'/ (Nothing in Visual Basic) string was supplied.
'/ </returns>
Public Shared Function StringToHLocalUni(ByVal s As String) As IntPtr
If s Is Nothing Then
Return IntPtr.Zero
Else
Dim nc As Integer = s.Length
Dim len As Integer = 2 * (1 + nc)
Dim hLocal As IntPtr = AllocHLocal(len)
'If hLocal = IntPtr.Zero Then
If hLocal.ToInt32 = 0 Then
Throw New OutOfMemoryException
Else
interopserv.Marshal.Copy(s.ToCharArray(), 0, hLocal, s.Length)
Return hLocal
End If
End If
End Function 'StringToHLocalUni
Public Shared Function IntToHLocalUni(ByVal s As Int32) As IntPtr
If s = 0 Then
Return IntPtr.Zero
Else
Dim nc As Integer = interopserv.Marshal.SizeOf(s)
Dim len As Integer = 2 * (1 + nc)
Dim hLocal As IntPtr = AllocHLocal(len)
'If hLocal = IntPtr.Zero Then
If hLocal.ToInt32 = 0 Then
Throw New OutOfMemoryException
Else
'interopserv.Marshal.Copy(s.ToString, 0, hLocal, nc)
Return hLocal
End If
End If
End Function 'StringToHLocalUni
End Class 'Marshal
'End Namespace 'NetCF.Runtime.InteropServices
and the SMS Class from the example
Imports System.Runtime.InteropServices
Imports interopserv = System.Runtime.InteropServices
Public Enum SMS_ADDRESS_TYPE
SMSAT_UNKNOWN = 0
SMSAT_INTERNATIONAL
SMSAT_NATIONAL
SMSAT_NETWORKSPECIFIC
SMSAT_SUBSCRIBER
SMSAT_ALPHANUMERIC
SMSAT_ABBREVIATED
End Enum 'SMS_ADDRESS_TYPE
Public Structure PhoneAddress
'/ <summary>The address type.</summary>
Public AddressType As SMS_ADDRESS_TYPE
'/ <summary>The phone number in string format.</summary>
Public Address() As Char
End Structure 'PhoneAddress
Public Class SMS
Private Shared SMS_MSGTYPE_TEXT As String = "Microsoft Text SMS Protocol"
Private Shared SMS_MODE_SEND As Long = &H2
Private Shared SMS_OPTION_DELIVERY_NONE As Long = &H0
Private Shared SMS_OPTION_DELIVERY_NO_RETRY As Long = &H1
Private Shared PS_MESSAGE_OPTION_NONE As Long = &H0
Private Enum SMS_DATA_ENCODING
SMSDE_OPTIMAL = 0
SMSDE_GSM
SMSDE_UCS2
End Enum 'SMS_DATA_ENCODING
Public Enum PROVIDER_SPECIFIC_MESSAGE_CLASS
PS_MESSAGE_CLASS0 = 0
PS_MESSAGE_CLASS1
PS_MESSAGE_CLASS2
PS_MESSAGE_CLASS3
End Enum 'PROVIDER_SPECIFIC_MESSAGE_CLASS
Private Enum PROVIDER_SPECIFIC_REPLACE_OPTION
PSRO_NONE = 0
PSRO_REPLACE_TYPE1
PSRO_REPLACE_TYPE2
PSRO_REPLACE_TYPE3
PSRO_REPLACE_TYPE4
PSRO_REPLACE_TYPE5
PSRO_REPLACE_TYPE6
PSRO_REPLACE_TYPE7
PSRO_RETURN_CALL
PSRO_DEPERSONALIZATION
End Enum 'PROVIDER_SPECIFIC_REPLACE_OPTION
Private Structure TEXT_PROVIDER_SPECIFIC_DATA
Public dwMessageOptions As Long
Public psMessageClass As PROVIDER_SPECIFIC_MESSAGE_CLASS
Public psReplaceOption As PROVIDER_SPECIFIC_REPLACE_OPTION
End Structure 'TEXT_PROVIDER_SPECIFIC_DATA
<System.Runtime.InteropServices.DllImport("sms.dll")> _
Private Shared Function SmsOpen(ByVal ptsMessageProtocol As [String], _
ByVal dwMessageModes As Int32, _
ByRef psmshHandle As IntPtr, _
ByVal phMessageAvailableEvent As IntPtr) As IntPtr
End Function
<System.Runtime.InteropServices.DllImport("sms.dll")> _
Private Shared Function SmsSendMessage(ByVal smshHandle As IntPtr, _
ByVal psmsaSMSCAddress As Int32, _
ByVal psmsaDestinationAddress As IntPtr, _
ByVal pstValidityPeriod As Int32, _
ByVal pbData As IntPtr, _
ByVal dwDataSize As Int32, _
ByVal pbProviderSpecificData() As Byte, _
ByVal dwProviderSpecificDataSize As Int32, _
ByVal smsdeDataEncoding As Int32, _
ByVal dwOptions As Int32, _
ByVal psmsmidMessageID As Int32) As IntPtr
End Function
<System.Runtime.InteropServices.DllImport("sms.dll")> _
Private Shared Function SmsClose(ByVal smshHandle As IntPtr) As IntPtr
End Function
<StructLayout(LayoutKind.Sequential)> _
Public Structure MsgSize
Public MsgSz As Int32
End Structure
<StructLayout(LayoutKind.Sequential)> _
Public Structure ProviderDataSize
Public ProvDataSize As Int32
End Structure
Public Shared Sub SendMessage(ByVal sPhoneNumber As String, ByVal sMessage As String)
Dim retVal As IntPtr = IntPtr.Zero
Dim smsHandle As IntPtr = IntPtr.Zero
Dim smsProviderData As IntPtr = IntPtr.Zero
Dim smsMessage As IntPtr = IntPtr.Zero
Dim ProvData(12) As Byte
Try
retVal = SmsOpen(SMS_MSGTYPE_TEXT, SMS_MODE_SEND, smsHandle, IntPtr.Zero)
If retVal.ToInt32 <> 0 Then
Throw New Exception("Could not open SMS.")
End If
'Set address structure
Dim smsatAddressType As Byte() = BitConverter.GetBytes(SMS_ADDRESS_TYPE.SMSAT_UNKNOWN)
Dim ptsAddress As Byte() = System.Text.Encoding.Unicode.GetBytes(sPhoneNumber)
Dim smsAddressTag(smsatAddressType.Length + ptsAddress.Length) As Byte
Array.Copy(smsatAddressType, 0, smsAddressTag, 0, smsatAddressType.Length)
Array.Copy(ptsAddress, 0, smsAddressTag, smsatAddressType.Length, ptsAddress.Length)
Dim smsAddress As IntPtr = Marshal.AllocHLocal(smsAddressTag.Length)
System.Runtime.InteropServices.Marshal.Copy(smsAddressTag, 0, smsAddress, smsAddressTag.Length)
'Set message
Dim smsMessageTag As Byte() = System.Text.Encoding.Unicode.GetBytes(sMessage)
smsMessage = Marshal.AllocHLocal(smsMessageTag.Length)
System.Runtime.InteropServices.Marshal.Copy(smsMessageTag, 0, smsMessage, smsMessageTag.Length)
retVal = SmsSendMessage(smsHandle, 0, smsAddress, 0, smsMessage, smsMessageTag.Length, _
ProvData, 12, SMS_DATA_ENCODING.SMSDE_OPTIMAL, SMS_OPTION_DELIVERY_NONE, 0)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
Try
retVal = SmsClose(smsHandle)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
End Class
After that I wrote as the example said the following code.
SMS.SendMessage("12121212", "This is a test")
But When I run it in the windows mobile 6.0 classic emulator I'm getting
Could not find Pinvoke Dll "sms.dll"
I know that I am missing something but I don't know what it is.
Should I deploy something in the emulator ? If yes what should I deploy and also where am I suppose to find it ?
When I want to deploy myApp to the real device should I also include something ?
Any Ideas ? I also try to configure emulator. Emulator's port in my pc is COM3 and also when running the classic emulator I went to the configure option and changed the serial port to COM3.
Any ideas ???
Thank you
解答
Think about it: to actually send SMS message you need cell phone hardware. Emulator has none so it cannot possibly send or receive SMS message for real. Thus it must fake it somehow so you can see this fake SMS in some way. To do so there's a tool called "Cellular Emulator" which fakes it all (normally found in "%ProgramFiles%\Windows Mobile 6 SDK\Tools\Cellular Emulator"). You should use it to simulate all kind of phone activities, see this.
What's wrong with actual device? That I would not know. Make sure it has valid SIM card and whatever plan you're using includes SMS capabilities.
所有回覆
That is expected as WM 6 Classic has no phone capabilities which means no SMS support and thus sms.dll is not present.
You should test your SMS code on something actually capable of SMS, e.g. WM 6 Standard (aka SmartPhone) or WM 6 Professional (AKA Pocket PC Phone Edition).
Hint: cut down your code to the bare minimum as you’re posing it to the forum. Nobody has time to read pages of code, consequentially your chances of getting an answer are greatly reduced.
- Hi ,
I have tested both methods using the WM 6 professional emulator. Using the SMS class I'm not getting any exceptions although I will see in a real enviroment if it is working. Using the Microsoft.WindowsMobile.PocketOutlook I'm getting an error saying 'Error sending sms message'.
Why am I getting this error ?
Thank you zakkar wrote: Hi ,
I have tested both methods using the WM 6 professional emulator. Using the SMS class I'm not getting any exceptions although I will see in a real enviroment if it is working. Using the Microsoft.WindowsMobile.PocketOutlook I'm getting an error saying 'Error sending sms message'.
Why am I getting this error ?
Also I have deployed my app to my windows mobile 6.0 device and tried to send an SMS using both ways but with no succes.
What am I missing ?
Thank youThink about it: to actually send SMS message you need cell phone hardware. Emulator has none so it cannot possibly send or receive SMS message for real. Thus it must fake it somehow so you can see this fake SMS in some way. To do so there's a tool called "Cellular Emulator" which fakes it all (normally found in "%ProgramFiles%\Windows Mobile 6 SDK\Tools\Cellular Emulator"). You should use it to simulate all kind of phone activities, see this.
What's wrong with actual device? That I would not know. Make sure it has valid SIM card and whatever plan you're using includes SMS capabilities.
- hi and thank you for your answer.I wasn't expecting to send an sms from the emulator.But I was expecting to send from my WM device. I have the glofiish X500 + which includes everything. GPS , WM 6.0 and also a valid sim cause I'm using it as a mobile phone.
Is there any additional setting which I need to take care off or with the two lines of code (let's say that I am going to use pocketoutlook class ) I will send it by itsself ?
PocketOutlook class will find the settings ? Or It supports specific types of devices ? Also in my device I can open contacts as Outlook contacts because I'm sychronizing my device with my PC's Outlook.
Is it supposed to be working without doing any additional settings ? Just the code I wrote and that's it ?
Thank you Hi .
It is working.
I have reset the emulator , sent the sms from the emulator (I saw the sms on the emulator's screen ) and installed it on my device.
It is working now.
Thank you

