Ask a questionAsk a question
 

AnswerCould Not load sms.dll

  • Thursday, June 12, 2008 12:10 PMzakkar Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    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



















Answers

  • Saturday, June 14, 2008 6:12 PMIlya TumanovMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    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.

     

All Replies

  • Thursday, June 12, 2008 4:05 PMIlya TumanovMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    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.

  • Friday, June 13, 2008 6:26 AMzakkar Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    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



  • Friday, June 13, 2008 8:12 AMzakkar Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
     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 you



  • Saturday, June 14, 2008 6:12 PMIlya TumanovMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    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.

     

  • Tuesday, June 17, 2008 5:54 AMzakkar Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    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
  • Tuesday, June 17, 2008 9:10 AMzakkar Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    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