locked
keep application on storage card running after idle state (WinCE 5.0) RRS feed

  • Question

  • Hi,

    I'm developing an application for a handheld scanner (Symbol MC3090) with windows CE 5.0 (.NET CF 3.5, VS2008). Since the application & the database file (sqlite) are becoming too large for the device's memory, I have to place the database and software onto a storage card. 

    If the user presses the power button, the device goes into an idle state. If the button gets pressed again, the application crashes sometimes (and database access is broken every time. There could be a workaround for this, but what I'm worrying about is the application itself). This is probably because the storage card is unmounted every time the device goes into an idle state. Is there a way to prevent this from happening, or maybe a way to fully load the application in memory at startup?

    Thanks in advance

    Joachim

    Thursday, January 19, 2012 8:18 AM

Answers

  • Solved! (same code but dsk3: in stead of gpd0:):

     

    public const int PPN_UNATTENDEDMODE = 0x0003;
        public const int POWER_NAME = 0x00000001;
        public const int POWER_FORCE = 0x00001000;

        [DllImport("coredll.dll")]
        public static extern bool PowerPolicyNotify(int dwMessage, bool dwData);

        [DllImport("coredll.dll", SetLastError = true)]
        public static extern IntPtr SetPowerRequirement(string pvDevice, CedevicePowerStateState deviceState, uint deviceFlags, string pvSystemState, ulong stateFlags);

        [DllImport("coredll.dll", SetLastError = true)]
        public static extern int ReleasePowerRequirement(IntPtr hPowerReq);

        public enum CedevicePowerStateState : int
        {
            PwrDeviceUnspecified = -1,
            D0 = 0,
            D1,
            D2,
            D3,
            D4,
        }

        //Keep the GPS and device alive:
        PowerPolicyNotify(PPN_UNATTENDEDMODE, true)
        IntPtr gpsPowerHandle = SetPowerRequirement("gpd0:", CedevicePowerStateState.D0, POWER_NAME | POWER_FORCE, null, 0);

    • Marked as answer by joowa Thursday, January 26, 2012 11:50 AM
    Thursday, January 26, 2012 11:50 AM

All replies

  • This sounds like an application defect. Take the kdmp generated when the application crashes and copy it in to the /debug directory of your application's project. Then, use Visual Studio do open the kdmp file and find where it is crashing and why.

    see: Getting Help From the Doctor

    see: Post Mortem Debug of Windows Mobile with Visual Studio 

    Once you've fixed the application crash, you can work on re-establishing connection with the database after the device returns from suspend.

    -PaulH

    • Proposed as answer by Jesse Jiang Monday, January 23, 2012 5:42 AM
    Thursday, January 19, 2012 7:18 PM
  • Those links seem interesting, but I didn't find the registry key to set the path for the kdmp-files. Also, the folder Windows\System\DumpFiles doesn't exist on my device (I turned 'show hidden folders' on). I assume I need to install something onto the device to use Dr. Watson, but didn't find much information for that (yet). Strange enough, I can continue debugging after turning the device off and on again.

    edit;

    Now I see I get this error here, (code below) on c.Invoke (the assembly from type t is not referenced in the form which contains this method, but called earlier with reflection). I don't have this exception if an instance of this type was created earlier, prior to the suspended state of the device.

      Private Shared Function GetInstanceFromParameters(ByVal t As Type, ByVal args As List(Of Object)) As Object
        If args IsNot Nothing AndAlso args.Count > 0 Then
          Dim c = t.GetConstructor(args.Select(Function(p) p.GetType()).ToArray())
          If c IsNot Nothing Then
            Return c.Invoke(args.ToArray)
          Else
            Return Nothing
          End If
        Else
          Return Activator.CreateInstance(t)
        End If
      End Function

     

    Another strange thing here is I can't catch the error with a try/catch block although I'm sure it happens on 'Return c.Invoke(args.ToArray)' ... A breakpoint in the constructor 'c' is never hit.







    • Edited by joowa Monday, January 23, 2012 3:11 PM
    Monday, January 23, 2012 8:54 AM
  • You can't find the folder using WMDC, you have to browse using file explorer on the device itself. Yes, you must have "show all files" turned on. Additionally, you must look for the dump file while the "We're sorry..." dialog is still showing. Once that's closed (i.e. you chose "Send" or "Don't Send") the dump file is deleted.

    What is the exact text of the exception you receive? 

    If you're not catching it using a .net try/catch block, it is probably a native exception. (e.g. access violation)

    -PaulH

    Monday, January 23, 2012 3:16 PM
  • It indeed is an access violation (I get an error form with error code 0xc0000005). I don't use WMDC (I'm debugging wireless), and I looked on the device itself without finding the folder. Maybe the folder also gets deleted when the form is closed, will look into that.

    Thanks for your help, Joachim


    • Edited by joowa Tuesday, January 24, 2012 4:14 PM
    Monday, January 23, 2012 3:41 PM
  • Still no Windows\System folder ..

    I have discovered that every type that is once instantiated before suspend, doesn't cause an exception. Even from the same DLL, the type already instantiated works, while the other (even a simple class) doesn't. The database connection though was easily repairable.


    • Edited by joowa Monday, January 23, 2012 4:15 PM
    Monday, January 23, 2012 4:02 PM
  • If you're running this from the debugger, you don't need the kdmp (and one isn't generated). You're getting more information by doing a live debug session than you would from the kdmp anyway. So, that's probably why you don't see the files.

    Are these types being loaded from a native DLL via P/Invoke (DllImport)? If so, you may need to switch to native debugging and set breakpoints within the DLL's code to determine the source of the Access Violation.

    -PaulH

    Monday, January 23, 2012 5:28 PM
  • My application consists of 'Modules' which are defined in a separate project (dll). Each module has a set of 'contents' (a class with the 'meta data' of a particular screen to show), which are created with reflection when the module is created (all modules are created at startup). A content also has a property 'ContentType', which contains a type in a user control in another project.

    It are those user controls I'm trying to create here. So I'm looking at the 'ContentType' property of the content and create it the moment I need to show the UI for the content (that's what happening in the method above).

    What I'm going to try next is make a shared dummy method in my UserControl base class, and call it when I create the modules & its contents. In that way, there has been a call to each type. I'll see where that brings me.

    Thanks, Joachim

     

    EDIT: didn't work as well..

    I tested by calling the constructor of one user control at application startup hard coded. This particular user control didn't cause an error after turning off and on the device. I could create dummy constructors (without initializecomponent) but that would make an ugly design of course, because I'd have to do that for every class inheriting UserControlBase.

     






    • Edited by joowa Tuesday, January 24, 2012 12:02 PM
    Tuesday, January 24, 2012 8:11 AM
  • Solved! (same code but dsk3: in stead of gpd0:):

     

    public const int PPN_UNATTENDEDMODE = 0x0003;
        public const int POWER_NAME = 0x00000001;
        public const int POWER_FORCE = 0x00001000;

        [DllImport("coredll.dll")]
        public static extern bool PowerPolicyNotify(int dwMessage, bool dwData);

        [DllImport("coredll.dll", SetLastError = true)]
        public static extern IntPtr SetPowerRequirement(string pvDevice, CedevicePowerStateState deviceState, uint deviceFlags, string pvSystemState, ulong stateFlags);

        [DllImport("coredll.dll", SetLastError = true)]
        public static extern int ReleasePowerRequirement(IntPtr hPowerReq);

        public enum CedevicePowerStateState : int
        {
            PwrDeviceUnspecified = -1,
            D0 = 0,
            D1,
            D2,
            D3,
            D4,
        }

        //Keep the GPS and device alive:
        PowerPolicyNotify(PPN_UNATTENDEDMODE, true)
        IntPtr gpsPowerHandle = SetPowerRequirement("gpd0:", CedevicePowerStateState.D0, POWER_NAME | POWER_FORCE, null, 0);

    • Marked as answer by joowa Thursday, January 26, 2012 11:50 AM
    Thursday, January 26, 2012 11:50 AM