Send mail to the author(s)

April 20, 2009

HOWTO: Determine whether or not a library exports a function

Back in May 2008, I wrote a blog post about checking for Win32 methods. I was recently reminded of this when a customer emailed us about a scenario that exactly matched the intended use case.

The customer was using the Smart Device Framework with a Windows CE 5.0 device and was receiving a MissingMethodException "Can't find an Entry Point 'xxx' in a PInvoke DLL 'yyy'". The exception message is detailed enough to explain the situation -- since Windows CE is modular, whoever created the OS image had not added a required component, resulting in the native functions to be missing from coredll.dll. This is not an uncommon scenario in the Windows CE world.

Below is an example of how you can gracefully handle calling the PlaySound function from coredll.dll even on devices that don't support the function. The important part is the call to Device.Win32Library("coredll").HasMethod("PlaySound"). This is return false if coredll.dll does not exist or if coredll.dll does not export the PlaySound function. Of course, you could raise a PlatformNotSupportedException or try another mechanism for playing the sound file instead of just returning without calling the native PlaySound function. The important point is that you should code in a way that can handle scenarios where the native function is not available and adapt accordingly.

Imports System.Runtime.InteropServices
Imports OpenNETCF.Reflection

Partial Public Class MainForm
  Friend Class NativeMethods
    Private Const SND_ASYNC As Integer = &H1
    Private Const SND_FILENAME As Integer = &H20000

    Public Shared Sub SafelyPlaySound(ByVal soundFile As String)
      If Not Device.Win32Library("coredll").HasMethod("PlaySound") Then
        Exit Sub ' Function is not exported so we silently return
      End If

      ' Coredll exists and the PlaySound function has been exported
      ' so we can safely make the P/Invoke call
      PlaySound(soundFile, IntPtr.Zero, SND_ASYNC And SND_FILENAME)
    End Sub

     _
    Private Shared Function PlaySound(ByVal szSound As String, _
                                      ByVal hMod As IntPtr, _
                                      ByVal flags As Integer) As Integer
    End Function

  End Class
End Class

April 20, 2009

Get Padarn for free!

Last week we quietly launched a fantastic new promotion for our Padarn Web Server product:

Padarn is a lightweight, single-purpose web server that supports a growing subset of ASP.NET. It is written entirely in C# and can be used as stand-alone web server, or embedded into an existing application. Padarn can be used to create elegant, data-driven web sites using SQL Server Compact Edition, or interface with a whole myriad of hardware peripherals, such as web cams, sensors, controllers, etc.

If you would like more information on Padarn, please send an email to padarn@opennetcf.com.

March 6, 2009

HOWTO: Build the Smart Device Framework source code

Note: This blog post only applies to Smart Device Framework Standard or Professional Edition customers.

If you open the SDF Public Source solution that ships with Smart Device Framework 2.3 and then build the source, you'll come across the following error:

Friend access was granted to 'OpenNETCF,PublicKey=...', but the output assembly is 
named 'OpenNETCF, Version=2.3.0.21, Culture=neutral, PublicKeyToken=null'. Try 
adding a reference to 'OpenNETCF,PublicKey=...' or changing the output assembly name 
to match.

(Note that I've replaced the actual public key with ellipses in the above. You will see an extraordinarily long hexadecimal number in your errors list in Visual Studio.)

The easiest way to remedy this is through a quick search & replace. Hit Ctrl-H to bring up the Find & Replace window. In the Find what text box, enter the following:

,PublicKey=00240000048000009400000006020000002400005253413100040000010001002beeba3
bfe7c548e085cffb8c2b6fd61ddd02b06d70864bb7de8bb22473edf5ab4b2196ff98e232c3e87f11fd
7986b743d5d3fdd6ecaf624bacfed116e1cefa50cd652365371d0ebd2702eb1084fed46df79ac0f59f4
d66c547918613d56dcf106843f3458516d3cd26f057a346d9f645fc24a7410a095c754835916e13cdbe

Make sure the Replace with text box is empty and the Look in combobox is showing Entire Solution. Click the Replace All button. When the search & replace has completed, build the solution again and it will succeed.

If you wish to do this manually (you may only want to use 1 or 2 of the 16 projects), you will need to modify the AssemblyInfo.cs file for the following projects:

  • OpenNETCF
  • OpenNETCF.Configuration
  • OpenNETCF.Net
  • OpenNETCF.Windows.Forms

November 26, 2008

ANN: Smart Device Framework 2.3

Today, we released Smart Device Framework 2.3. This is the long awaited release of the Smart Device Framework for Visual Studio 2008.

It's been a painful path to get to this point, what with contending with frustrating bugs in Visual Studio 2008 forms designer and all, but we finally got there. Thanks for you patience and understanding.

Along with the new version is a new naming convention. We've dropped the name Smart Device Framework Extensions for Visual Studio with its Standard and Premium editions. Instead, say hello to Smart Device Framework Standard Edition and Professional Edition. Be sure to check out the new feature matrix to find out how each edition differs.

We've got some pretty cool stuff features in the libraries, notably OpenNETCF.Core which contains a dozen or so extension methods for common scenarios, as well as OpenNETCF.Net.Mail, for sending mail via SMTP directly from the device -- this eliminates the need to configure a mail account on the device.

August 12, 2008

HOWTO: Prevent ResolveAssemblyReferences warnings in Visual Studio 2008

When you reference an assembly compiled against .NET Compact Framework 2.0 in a project targeting .NET Compact Framework, it's quite likely you will receive a number of ResolveAssemblyReferences warnings, similar to this:

ResolveAssemblyReferences:
  Consider app.config remapping of assembly "System.Windows.Forms, Culture=neutral, 
  PublicKeyToken=969db8053d3322ac, Retargetable=Yes" from Version "2.0.0.0" [] to 
  Version "3.5.0.0" [C:\Program Files\Microsoft.NET\SDK\CompactFramework\v3.5\
  WindowsCE\System.Windows.Forms.dll] to solve conflict and get rid of warning.

This warning occurs when the compiler has loaded the .NET Compact Framework 3.5 base class libraries (BCLs) and the referenced assembly, but the metadata contained in the referenced assembly references the .NET Compact Framework 2.0 BCLs.

To remove the warnings you can add an App.Config to your project and redirect the assembly bindings from the 2.0 versions to the 3.5 equivalents. Below is an example of the XML required in the App.Config to redirect the 2.0 version of System.dll to the 3.5 version.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <runtime>
    <assemblybinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentassembly>
        <assemblyidentity name="System" culture="neutral" publickeytoken="969db8053d3322ac" />
        <bindingredirect  newVersion="3.5.0.0" oldVersion="2.0.0.0" />
      </dependentassembly>
    </assemblybinding>
  </runtime>
</configuration>

You will need to add a dependentassembly element for each of the ResolveAssemblyReferences warnings that you receive.

Make sure the Build Action property of the App.Config is set to Content and the Copy To Output Directory property is set to Only if newer. Then, rebuild your solution and the warnings should not appear.

July 23, 2008

Lambda expressions in .NET Compact Framework 2.0

There's been a lot of internal discussion today on how to leverage C# 3.0 features without requiring .NET Compact Framework 3.5. Mark has the low down on using extension methods with a little compiler misdirection hack.

The discussions kicked off because I discovered that you can use lambda expressions with .NET Compact Framework 2.0 projects in Visual Studio 2008. I even twittered about it yesterday. (Note: it didn't take me too long to realize it's not a bug, but due to Visual Studio 2008 using the C# 3.0 compiler.) Code like the following just works -- no hacks required:

delegate double PowerOf(double x, double y);

static void Main() 
{
    PowerOf pwr = (x, y) => Math.Pow(x, y);
    double result = pwr(2, 3);
}

If you are using Visual Studio 2008 and still need to target .NET Compact Framework 2.0, the little things like this go a long way to creating and maintaining reusable code.