Oct 9 2009

Samsung adds support for Compass, Proximity Sensor to SDK

Samsung released an updated version of their Windows Mobile SDK today.  The updated SDK contains new APIs that will let you access the proximity sensor and the compass in devices such as the Omnia II. You can get more information on the updated SDK from the Samsung Mobile Innovator site.

Tags:

Oct 5 2009

Windows Marketplace for Mobile now Live!

The Windows Marketplace for Mobile is now Live. If you fire up your 6.5 Emulator and click on the Marketplace icon you'll be able to log in look around.  Right now only a few applications are available.  Edward from MSMobiles.com has uploaded a video to youtube (http://www.youtube.com/watch?v=i6Py1ZYyy1s) and written a review on it (http://msmobiles.com/news.php/8641.html ). Windows Mobile 6.5 devices will start to roll out into the hands of consumers in another 2 days though both newly released devices and ROM updates for existing devices.  Most Windows Mobile devices will have the Marketplace preinstalled (though a few months ago it was reported that Verizon Wireless has decided that the Marketplace would not be included on their devices).

Tags:

Oct 2 2009

Windows Mobile 7 Supports Vector Graphics

Category: Mobile | Windows | Windows CEJoel Ivory Johnson @ 20:38

Windows Mobile 7 has support for vector graphics.  That will address a lot of the concerns that many developers had about targetting multiple resolutions and creating graphical resources for each one. Where did I hear this? At the Windows Mobile Developer camp in Mountain View, California, USA. The event is still going on now, but when the videos are posted I will post a link to them.

Tags:

Nov 7 2008

Detecting Storage Cards

Category: Windows CE | Programming | WindowsJoel Ivory Johnson @ 17:37

Some time ago in the MSDN forms I responded to a few questions on how to detect the storage cards in the file system and how does one get the storage card's capacity. I wrote the following could are a response to those questions and thought it would be helpful to share.  Storage cards show up in the file system as temporary directories.  This program examines the objects in the root of the device and any folders that have temp attribute are considered to be a positive match

using System;
using System.IO;
using System.Runtime.InteropServices;

namespace StorageCardInfo
{
  class Program
  {
    const ulong Megabyte = 1048576;
    const ulong Gigabyte = 1073741824;

 

    [DllImport("CoreDLL")]
    static extern int GetDiskFreeSpaceEx(
       string DirectoryName,
       out ulong lpFreeBytesAvailableToCaller,
       out ulong lpTotalNumberOfBytes,
       out ulong lpTotalNumberOfFreeBytes 
    );

    static void Main(string[] args)
    {
      DirectoryInfo root = new DirectoryInfo(@"\");
      DirectoryInfo[] directoryList = root.GetDirectories();
      ulong FreeBytesAvailable;
      ulong TotalCapacity;
      ulong TotalFreeBytes;

      for (int i = 0; i < directoryList.Length; ++i)
      {
        if ((directoryList[i].Attributes & FileAttributes.Temporary) != 0)
        {
          GetDiskFreeSpaceEx(directoryList[i].FullName, out FreeBytesAvailable, out TotalCapacity, out TotalFreeBytes);
          Console.Out.WriteLine("Storage card name: {0}", directoryList[i].FullName);
          Console.Out.WriteLine("Available Bytes : {0}", FreeBytesAvailable);
          Console.Out.WriteLine("Total Capacity : {0}", TotalCapacity);
          Console.Out.WriteLine("Total Free Bytes : {0}", TotalFreeBytes);
        }
      }
    }
  }
}

 

 

 

Tags:

Oct 31 2008

.Net Micro Framework 3.0 Released

The .Net Micro Framework version 3.0 is now availble.

  • Compatibility with Visual Studio 2008 and C# Express
  • Touch Screen and Gesture Support
  • Ability to Act as USB Accessory for PC
  • WiFi and SSL Support
  • Emulator included with Kit

For me the most significant feature of this release is the support for Visual Studio 2008.  When I checked the hardware page I saw that the .Net Micro Framework kit that I have is compatible, so I can uninstall VS 2005 and free up some hard drive space. For those curious there is a video in the "Getting Started" section of the

Download the SDK Today!

.Net Micro Framework Resources

Tags:

Oct 29 2008

Spark Your Imagination

The third Windows CE related contest to come up in the past several weeks is titled "Spark Your Imagination."  The grand price is $15,000 and a trip to TechEd 2009. The contest is divided into three rounds.  In the first round you must submit a 1 to 3 page paper describing a home automation project.  If you are one of the 50 chosen finalist you will receive a Via Artigo Pico-ITX hardware kit to construct your idea, write a 4-5 page paper on it, and make a three minute video about it.  The three top finalist receive $1,000 and a flight to Silicon Valley to demonstrate their idea at a Microsoft Keynote.

Tags:

Sep 9 2008

What Tools do I Need to Develop for Windows Mobile?

Several times in the past two weeks I've seen users on the MSDN forum ask what software tools are needed to develop for Windows Mobile.   It's possible to develop for Windows Mobile devices using the .Net Compact Framework SDK and the command line compiler.  I would never suggest that some one do that; IDEs provide a much better debugging and development experience. The chart collowing this paragraph will let you know what versions of Visual Studio that you can use for each Windows Mobile and .Net version.  Note that no Visual Studio express version is lited here.  

Visual Studio VersionSupported Windows Mobile Versions
Visual Studio .Net 2003 Supports .Net Compact Framework 1.0 for Pocket PC 2002 and Windows Mobile 2003
Visual Studio 2005 Standard Edition or Better .Net 1.0 and .Net 2.0 from Windows Mobile 2003 to Windows Mobile 6
Visual Studio 2008 Professional .Net 2.0 and 3.5 from Windows Mobile 5 to Windows Mobile 6

Programs that you cannot presently use for Windows Mobile development include the express editions of Visual Studio and Visual Studio 2008 Standard.

Tags:

Sep 7 2008

Windows Mobile Current Directory

Another area when programming on Windows CE/Mobile devices is "How do I find the current directory?"  CE devices don't have a concept of a current directory.  This means that relative paths don't have meaning on a CE device (all paths are absolute).  Because of the lack or relative paths  some files (such as help files) are loaded to the Windows directory (personally I absolutly hate copying anything specific to an application to the Windows Directory).

It follows that since there is no concept of a current directory on a Windows Mobile device how would one locate a resource for which only a relative path is known?  A .Net program always has access to the modules of which it is composed (usually a .Net component is composed of one module packaged in a DLL or EXE file). The following line will return the absolute path to the currently executing assembly.

 string modulePath = this.GetType().Assembly.GetModules()[0].FullyQualifiedName;

 To get the absolute path to the folder that contains the assembly simple string manipulation is required.  The assembly name appears after the last directory seperator. While the directory seperator is usually the backslash (\) character, for better compatibility across other operating systems that may run .Net (ex: Mono[^] on Linux, OS X, or Solaris) use System.IO.Path.DirectorySeparator to represent the directory separator charactor.

string solutionFolder = modulePath.Substring(0, modulePath.LastIndexOf(Path.DirectorySeparatorChar) );

Once the folder to your program is known use Path.Combine to build the fully qualified file name for files in your folder.  Path.Combine takes into account the directory separator for the operating system on which your program is run.  So if you had data in a file named MyFile.txt you would use

string myFilePath = Path.Combine(solutionFolder,"MyFile.txt");

Update 1 : I received a simpler way to accomplish the same thing from John Spraul in the comment section.  Thanks. John!

Update 2: If you are developing using the native APIS use the following:
GetModuleFileName(GetModuleHandle(NULL),    pszFullPath, MAX_PATH);

Path.GetDirectoryName(this.GetType().Assembly.GetModules()[0].FullyQualifiedName)

or

Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName)

if you do not want to load the type.

Tags:

Aug 28 2008

My CE Devices

Category: Windows CE | Off Topic | WindowsJoel Ivory Johnson @ 17:17

I had to pull out one of my older Pocket PCs for testing something and while I was at it I decided to round up my Windows CE devices and take a picture of them together.  I seem to have quite a bit.  Missing from the history of devices that I've owned are an i-mate Jam and the ViewSonic V37.  Regretably I sold one and gave the other to some one that wanted a PocketPC.  I hope to get a Windows Mobile 6 standard device and a Windows CE development kit in the coming months.

 

My Windows CD Devices

Tags:

Aug 13 2008

Get Certified for Windows CE

For a limited time you can download a free preperation kit for certification in Windows CE development.  The kit contains all the information you need to pass certification 70-571.

For more details visit http://msdn.microsoft.com/en-us/embedded/cc294468.aspx

 

 

Tags:

Aug 13 2008

Autolaunching an Application on Windows Mobile

I submitted an article to codeproject.com a little over a month ago about automatically starting an application base on an event or a schedule. I posted the content of the article here.  To get the source code visit http://www.codeproject.com/script/Articles/Article.aspx?aid=27917

Introduction

Figuring out how to make an application automatically start up had long been a mystery to me. The information was scattered and a bit of research was needed to collect all of. During my research I placed all of my notes in a various documents and have decided to organize them into a single document and share with all. The information presented here was tested on Windows Mobile 5 and Windows Mobile 6 devices but can also be applied to several versions of Windows CE (The OS from which Windows Mobile is derived).

It's possible to achieve similar functionality by making your own executable that watches system changes through the SystemState class and responding accordingly, but that would cause your program to have a larger footprint.

About the Code

The first methods of automatically starting a program are centered in what I will call configuration tasks; making shortcuts, registry entries, or placing files in specific locations. For these methods I do not provide code examples. Later within this article I discuss methods of automatically launching applications that are setup through code. For these methods I include example code within the article and full source attached to the article.

The code examples rely on some Win32 functions that are called through P/Invoke. Both code examples refer to a project named Win32 which contains the references to these functions. Additionally Win32 also contain a structure and an enumeration needed to properly pass information to the WinAPI functions. To run the code examples you will need a Windows Mobile device (or emulator) and Visual Studio 2008.

Remember that on Windows Mobile devices you should prevent more than one instance of your program from existing in memory (if a second instance is started it should notify the first instance and then immediatly terminate).

What is meant be “auto-start?”

When I use the phrase auto-start I use it to refer to the launching of any program based on an event (other than the user clicking on the program’s icon). A program can be automatically started in one of four ways.

  • A program on a memory card runs as soon as the card is inserted
  • A program is scheduled to start at a predetermined time
  • A program is launched in response to a system change
  • A program launches at device power up

AutoRun from a Memory Card

The user inserting a memory card can cause an application to launch in one of two ways. The memory card could have a program on it that launches upon insertion of the Windows Mobile device could start a program that is already present in its main storage in response to the memory card being inserted. The later would be implemented by registering an application to start on a system change (discussed later).

When a memory card is inserted into a Windows Mobile / Windows CE device the OS automatically looks in a certain folder for a program named Autorun.exe. If that program is found then it is immediately run. The folder in which the OS looks is going to depend on what type of processor that the device has. For an overwhelming majority of Windows Mobile devices that folder will be “/2577”. Here is a table of the possible folder names for other Windows CE devices.

ProcessorFolder Name
ARM 720 1824
Arm 820 2080
ARM 920 2336
ARM 7TDMI 70001
Hitachi SH3 10003
Hitachi SH3E 10004
Hitachi SH4 10005
Motorola 821 821
SH3 103
SH4 104
Strongarm 2577

f you already have an application on a memory card that you wanted to autorun.exe but you did not want to rename the executable or place it in this folder then you can always make a second executable whose purpose is to launch your first executable.

Startup Shortcut

A shortcut can be made to an application that you wish to startup automatically and placed in \Windows\StartUp. Use this method if you have a single executable that needs to be started that has no dependencies on other executables. The format of shortcuts on windows mobile devices is simple. It will always be in the form of 00#”<\program Files\path>” where 00 is replaced with the number of characters that appear after the ‘#’ sign, the ‘#’ is a delimiter, and then the complete path to the executable. The following is an example of a shortcut to Windows Media Player.

23#“\windows\wmplayer.exe”

You don't have to manually create the shortcut though. There is a native API call SHCreateShortcut that will create a shortcut for you. The first argument is the full path to the shortcut to be created and the second arguement is the full path to the file to which the shortcut points.

Starting an Application at Bootup

For Windows Mobile devices the location for autostart entries is HKEY_LOCAL_MACHINE\Init. Unlike the startup entries on a desktop machine (which only require the path to the executable to start) the entries for Windows Mobile devices are a little more structured. There are two keys associated with an application that needs to start up automatically, a LaunchXX key and an optional DependXX key. The XX would be replaced with a number. This number is also called the sequence number The value of LaunchXX is a string value (REG_SZ) that contains the path to the executable to be started. The DependXX key is used to specify on what applications that the current application has dependencies (and thus in what order the applications must be launched). The DependXX key contains a list of word (2 bytes) values that contain the sequence number values of the required applications.

The following screenshot is of the registry on my Windows Mobile 5 phone. Launch21 refers to an application named “coldinit.” If we look at Depend21 we see that “coldinit.exe” has a dependency on an application identified by 0x14 (20 decimal). So “coldinit.exe” must be launched after the app identified in Launch20, “Device.exe.”

Screen shot of Windows Mobile Registry

Applications launched using this method must notify the application of successful startup by calling the SignalStarted(DWORD) function. This function is a native call. For C programs the header to this function is defined in Winbase.h and in the library Coredll.lib. Developers using managed code will need to P/Invoke this method. The functions only argument is the sequence number of the executable. The sequence number is passed to the application as its only command argument. Note that the sequence number is the only argument that the application will be able to receive through the command line arguments. Any other information that must be passed to the application should be passed through configuration files or registry keys.

Starting a Program at a Specified Time

The Windows CE / Windows Mobile OS contains functionality for automatically starting a program at a specified time. The functionality is available through a call to CeRunApAtTime from the CoreDLL library. As mentioned by Jim Wilson in many of his “How Do I” video post on MSDN, this function expects the start time to be specified in the WinAPI SystemTime structure instead of the DateTime structure (CeRunAppAtTime is an unmanaged function called using the platform invoke functionality). Converting a time from a DateTime to a SystemTime is not difficult; there are already WinAPI functions that do this for you. To make calling this function easier I have placed the following code in my Win32Helper class. I’ve also provided an overloaded function to allow the time to be passed as an offset from the current time with a TimeSpan object.

public static void RunAppAtTime(string applicationEvent, DateTime startTime)
{
    long fileTimeUTC = startTime.ToFileTime();
    long fileTimeLocal = 0 ;
    SystemTime systemStartTime = new SystemTime();
    CoreDLL.FileTimeToLocalFileTime(ref fileTimeUTC, ref fileTimeLocal);
    CoreDLL.FileTimeToSystemTime(ref fileTimeLocal, systemStartTime);
    CoreDLL.CeRunAppAtTime(applicationEvent, systemStartTime);
}
public static void RunAppAtTime(
     string applicationEvent, 
     TimeSpan timeDisplacement
)
{
    DateTime targetTime = DateTime.Now + timeDisplacement;
    RunAppAtTime(applicationEvent, targetTime);
}

Where applicationEvent is the full path to the application to start and startTime is the time at which the application should be executed. There’s also an overloaded version of the method that accepts a TimeSpan object instead of a DateTime if you wanted to specify the start time relative to the current time.

If an application were attempting to schedule itself to be restarted at a later time it will need to be able to pass it’s complete path. I used reflection to find that path.

Module[] m = this.GetType().Assembly.GetModules();
target = m[0].FullyQualifiedName;

Screenshot of timed start program

Running the Program because of a System Change

There are a number of system changes that can be used to trigger the execution of a program. The WinAPI function CeRunAppAtEvent is used to associate a program with an event. Once associated that program will be launched every single time that the event occurs! So you must also remember to disassociate the program with the event when you no longer want it to automatically start.

I have created the enumeration in the Win32 class named WhichEvent that contains the ID numbers for the events that can be used to trigger program execution.

When a program is started because of a change in system state a single argument is passed to the program to indicate the state change that triggered the programs execution. (I don't discuss the details of how to do that here). For a complete list of the possible arguments see the example cod in AutoStartArgumentString.cs.

Enumeration ElementDescription

NOTIFICATION_EVENT_NONE

Used to clear all events associated with a program

NOTIFICATION_EVENT_TIME_CHANGE

NOTIFICATION_EVENT_SYNC_END

ActiveSync synchronization has completed on the device

NOTIFICATION_EVENT_ON_AC_POWER

The unit’s charger is connected

NOTIFICATION_EVENT_OFF_AC_POWER

The unit’s charger is disconnected

NOTIFICATION_EVENT_NET_CONNECT

The device is connected to a network

NOTIFICATION_EVENT_NET_DISCONNECT

The device is disconnected from a network

NOTIFICATION_EVENT_DEVICE_CHANGE

A memory card or other device was inserted or removed

NOTIFICATION_EVENT_IR_DISCOVERED

The device has detected another infrared device

NOTIFICATION_EVENT_RS232_DETECTED

The device has been connected to an RS232 device

NOTIFICATION_EVENT_RESTORE_END

A full restore of the device has completed

NOTIFICATION_EVENT_WAKEUP

The device has come out of a suspended state

NOTIFICATION_EVENT_TZ_CHANGE

The time zone of the device has changed

NOTIFICATION_EVENT_MACHINE_NAME_CHANGE

The name of the device has changed

I have created a class simple named Core for declaring platform invoked methods from the CoreDLL.dll library and declared the CeRunApAtEvent function within it. The following schedules the the windows calculator to start when the device comes out of the suspended state.

CoreDLL.CeRunAppAtEvent(@"\Windows\Calc.exe", (int)WhichEvent.NOTIFICATION_EVENT_DEVICE_CHANGE);

After that call the windows calculator will start every single time that the device is woken up. To prevent the calculator from starting up a second call is necessary.

CoreDLL.CeRunAppAtEvent(@"\Windows\Calc.exe", (int)WhichEvent.NOTIFICATION_EVENT_NONE);

Included with this article is an example application that can be used to cause an application to launch for various events. Originally this program would only register a program to start upon wakeup. But I've extended the program so that it can also start programs in response to other events. Note that by changing the value in the call to CERunAppAtEvent that you can use the program cause an executable to launch for bcause of some other event (such as a memory card being inserted or ActiveSync completing its synchronization).

WakeupStart.png

When a program is autostarted a string is passed to it through the command line indicating the event that started it. I've included a program named ShowCommandLine with the source code that does nothing more than display the command line arguments that it received. From the screen shot below you can see the command line argument that was received when the program was started upon connecting to a network connection.

ShowCommandLine.png

Preventing Multiple Instances

Normally the .Net framework will take care of ensuring that multiple instances of your program are not running. This doesn't always work for programs that are started because of a system event. Several system events can be fired in rapid succession or the same event can be fired twice (for some odd reason the wakeup event is usually fired twice). The first time I tried scheduling the ShowCommandLine program to start on wakeup and another event I ended up with several instances of it running.

MultiInstance.png

To get around this I create an event object (using P/Invoke) before loading the form. If several instances of the program are started in rapid succession then the creation of the event will fail, and we can use this failure to know that the this is not the first instance of the program and immediatly unload it.

static void Main()
{
    IntPtr eventHandle = IntPtr.Zero;
    const string ApplicationEventName = "ShowCommandLineEvent";  //We will use this as our handle to 
                                                                 //to ensure only one instance of the
                                                                 //program is started            
    try
    {
        //Try to create the event.  If the creation fails then it is 
        //because another instance of this application is already 
        //running. If another instance exists then this instance
        //should immediatly terminate.
        eventHandle = CoreDLL.CreateEvent(IntPtr.Zero, true, false, ApplicationEventName);
        int lastError = Marshal.GetLastWin32Error();
        //MessageBox.Show(String.Format("event handle {0}",eventHandle));
        
        if (0 == lastError)
        {
            Application.Run(new Form1());
        }
    }
    finally
    {
        //When the application is no longer running it should release the event
        if (eventHandle != IntPtr.Zero)
            CoreDLL.CloseHandle(eventHandle);
    }
}

When multiple instances of a program are created in this manner you may want to send a notification to the first instance of the program so that it can respond to the event.

 

 

What's Next?

This article is largly the result of research I am doing in preperation for software solution that I plan to design. In the next part of my research I will develop a solution for making the phone respond to other events not exposed directly through the the CeRunAppAtEvent function.

History

  • 19 July 2008 - Initial Publication
  • 31 July 2008 - Added reference to SHCreateShortcut (Thanks Zoomesh!)

Tags: