0

I've been maintaining a Windows CE app for some time now (over a year) and have produced new versions of it from time to time, copying them to the handheld device[s] and running the new versions there.

Today, though, I created a new Windows CE app for the first time. It is a very simple utility.

To create it in VS 2008, I selected a C# "Smart Device Project" template, added a few controls and a bit of code, and built it.

Here are some of the options I selected:

enter image description here

I copied the .exe produced via building the project to the handheld device's Program Files folder:

enter image description here

...but it won't run. Is it in the wrong location? Does it need some ancillary files copied over? Is there some other sort of setup I need to do to get it to run? Or what?

UPDATE

Since there's not much of it, I'm pasting ALL the code below in case somebody thinks my code could be the problem:

using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;

namespace PrinterCommanderCE
{
    public partial class PrinterCommanderForm : Form
    {
        public PrinterCommanderForm()
        {
            InitializeComponent();
        }

        private void btnSendCommands_Click(object sender, EventArgs e)
        {
            SendPrinterCommands();
        }

        private void SendPrinterCommands()
        {
            bool successfulSend = false;
            const string quote = "\"";
            string keepPrinterOn = string.Format("! U1 setvar {0}power.dtr_power_off{0} {0}off{0}", quote);
            string shutPrinterOff = string.Format("! U1 setvar {0}power.dtr_power_off{0} {0}on{0}", quote);
            string advanceToBlackBar = string.Format("! U1 setvar {0}media.sense_mode{0} {0}bar{0}", quote);
            string advanceToGap = string.Format("! U1 setvar {0}media.sense_mode{0} {0}gap{0}", quote);

            if (radbtnBar.Checked)
            {
                successfulSend = SendCommandToPrinter(advanceToBlackBar);
            }
            else if (radbtnGap.Checked)
            {
                successfulSend = SendCommandToPrinter(advanceToGap);
            }
            if (successfulSend)
            {
                MessageBox.Show("label type command successfully sent");
            }
            else
            {
                MessageBox.Show("label type command NOT successfully sent");
            }

            if (ckbxPreventShutoff.Checked)
            {
                successfulSend = SendCommandToPrinter(keepPrinterOn);
            }
            else
            {
                successfulSend = SendCommandToPrinter(shutPrinterOff);
            }
            if (successfulSend)
            {
                MessageBox.Show("print shutoff command successfully sent");
            }
            else
            {
                MessageBox.Show("print shutoff command NOT successfully sent");
            }
        }

        private bool SendCommandToPrinter(string cmd)
        {
            bool success = false;
            try
            {
                SerialPort serialPort = new SerialPort();
                serialPort.BaudRate = 19200;
                serialPort.Handshake = Handshake.XOnXOff;
                serialPort.Open();
                serialPort.Write(cmd);
                serialPort.Close();
                success = true;
            }
            catch
            {
                success = false;
            }
            return success;
        }

    }
}

UPDATE 2

Based on this, I added a global exception handler to the app so that Program.cs is now:

namespace PrinterCommanderCE
{
    static class Program
    {
        [MTAThread]
        static void Main()
        {
            AppDomain currentDomain = AppDomain.CurrentDomain;
            currentDomain.UnhandledException += new UnhandledExceptionEventHandler(GlobalExceptionHandler);

            Application.Run(new PrinterCommanderForm());
        }

        static void GlobalExceptionHandler(object sender, UnhandledExceptionEventArgs args)
        {
            Exception e = (Exception)args.ExceptionObject;
            MessageBox.Show(string.Format("GlobalExceptionHandler caught : {0}", e.Message));
        }
    }
}

Yet running the new build shows nothing - it just "flashes" momentarily with about as much verbosity as Lee Harvey Oswald after Jack Ruby's friendly visit.

UPDATE 3

Could the problem be related to this, and if so, how to solve it?

The circumstance that both my updated version of an existing app AND this brand new and simple app refuse to run indicate there is something fundamentally flawed somewhere in the coding, building, or deployment process.

UPDATE 4

As this is a minimal utility, the reason it (and my legacy, much more involved) app are not working may have something to do with the project properties, how it's being built, a needed file not being copied over, or...???

NOTE: The desktop icon is "generic" (looks like a blank white form); this perhaps indicates a problem, but is it indicative of something awry or is it a minor (aesthetics-only) problem?

UPDATE 5

In Project > Properties..., Platform is set to "Active (Any CPU)" and Platform target the same ("Active (Any CPU)")

I have read that this is wrong, that it should be "x86", but there is no "x86" option available - Any CPU is the only one...?!?

UPDATE 6

In Project > Properties... > Devices, the "Deploy the latest version of the .NET Compact Framework (including Service Packs)" is checked. Is this as it should be?

UPDATE 7

Okay, here's the really strange part of all this:

I have two CF/CE apps that I need to run on these Motorola/Symbol 3090 and 3190 handheld devices.

One is this simple utility discussed above. I find that it actually does run on one of the devices (the 3190, FWIW). So it runs on one device, but not on the other.

HOWEVER, the other (legacy) .exe is the opposite - it runs on the 3090 (where the utility will not even start up), but not on the 3190.

So the utility's needs are met by the 3190, and the legacy util's needs are met by the 3090. However, the NEW version of the legacy app does not run on either device!

I am baffled; I feel as Casey Stengel must have when speaking once of his three catchers: "I got one that can throw but can't catch, one that can catch but can't throw, and one who can hit but can't do either."

UPDATE 8

The 3190 has a newer version of the CF installed; it seems that both the new and the old apps should run on the new device with the newer CE, but they don't - only the one built against/for the new framework does...

UPDATE 9

Here is what the 3090 looks like:

enter image description here

UPDATE 10

So I have two exes, one that runs on the devices (both of them now), and the other that will run on neither of the devices. The two exesw seem almost identical. I compared them with three tools: Red Gates' .NET Reflector; JetBrains' dotPeek, and Dependency Walker.

Here is what I found:

Dependency Walker Both seem to have the same errors about missing dependencies (I didn't have them in the same folder with their dependent assemblies is probably the problem there)

.NET Reflector The nonworking file has this entry that the working file does not:

[assembly: Debuggable(0x107)]

Is this the problem and, if so, how can I change it?

JetBrains dotPeek The References in the working copy of the exe are all version 1.0.50000.0

The non-working exe has an identical list of References, and the same version number.

There is this difference, though:

For the working .exe, dotPeek says, "1.4.0.15, msil, Pocket PC v3.5" For the non-working .exe, dotPeek says, "1.4.0.15, msil, .Net Framework v4.5"

Is this the problem and, if so, how can I change the non-working .exe to match the working one?

This last is disconcerting, primarily because I see no place in the non-working (newer) version of the project where a "4.5" string exists. Where could dotPeek be getting that information?

UPDATE 11

I do know now that the problem is somewhere between these two MessageBox.Show()s, because the first one I see, but not the second:

public static int Main(string [] args)
{
    try
    {
        // A home-brewed exception handler (named ExceptionHandler()) is already defined, but I'm adding a global one
        // for UNHANDLED exceptions (ExceptionHandler() is explicitly called throughout the code in catch blocks).
        MessageBox.Show("made it into Main method"); // TODO: Remove after testing <= this one is seen
        AppDomain currentDomain = AppDomain.CurrentDomain;
        currentDomain.UnhandledException += new UnhandledExceptionEventHandler(GlobalExceptionHandler);

        string name = Assembly.GetExecutingAssembly().GetName().Name;
        IntPtr mutexHandle = CreateMutex(IntPtr.Zero, true, name);
        long error = GetLastError();

        if (error == ERROR_ALREADY_EXISTS)
        {
            ReleaseMutex(mutexHandle);

            IntPtr hWnd = FindWindow("#NETCF_AGL_BASE_",null);
            if ((int) hWnd > 0)
            {
                SetForegroundWindow(hWnd);  
            }
            return 0;
        }

        ReleaseMutex(mutexHandle);

        DeviceInfo devIn = DeviceInfo.GetInstance();

        Wifi.DisableWifi();

        // Instantiate a new instance of Form1.
        frmCentral f1 = new frmCentral();
        f1.Height = devIn.GetScreenHeight(); 
        f1.Text = DPRU.GetFormTitle("DPRU HHS", "", "");

        MessageBox.Show("made it before Application.Run() in Main method"); // TODO: Remove after testing <= this one is NOT seen
        Application.Run(f1);

        devIn.Close();

        Application.Exit();
        return 0;
    }
    catch(Exception ex)
    {
        DPRU.ExceptionHandler(ex, "Main");
        return 0;
    }
} // Main() method

UPDATE 12

More specifically, I've got infinite looping going on somehow; By mashing the "Ent" pill on the handheld device (that's what the button looks like - a "lozenge") - it sounds like gerbils tap-dancing (as debugging MessageBox.Show()s in two methods pop up and are dismissed over and over ad infinitum ad (literally) nauseum).

Community
  • 1
  • 1
B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862
  • It turned out that the real problem was due to some code the installer had done which caused the device to always try to auto-start the app; so it was already running (trying to) when I attempted to replace the .exe – B. Clay Shannon-B. Crow Raven May 01 '14 at 22:27

2 Answers2

1

Can you try to run it inside the debugger and check where it fails? Can you place a breakpoint right at the beginning of Program.main and check if it's reached? Debug output may also give you some interesting hints.

Valter Minute
  • 2,177
  • 1
  • 11
  • 13
  • No, I can't debug it that way; it's not, and I don't think can, be set up for that (believe me, I've tried, and jumped through many hoops, getting my tailfeathers burned to a crisp in the process). We build on the PC, copy the exe to the handheld, and run it. "Debugging" is by way of MessageBox.Show(), etc. – B. Clay Shannon-B. Crow Raven Apr 24 '14 at 15:21
  • Did you try to build an empty .NET CF app and run it on the target. Just to check if it's a project-specific issue or if there is something wrong on the target device or on your dev PC. – Valter Minute Apr 25 '14 at 15:37
  • This app is about as simple as can be, so I'd say there's either something wrong on the handheld device or the PC. -- or a localized E.M.P. has struck in my cube. – B. Clay Shannon-B. Crow Raven Apr 25 '14 at 15:54
  • It's simple, but it's more complicated than the "hello world" generated by the wizard. Checking if the hello world works is useful to understand if there is something wrong in the app or in the .NET runtime on the target, IMHO. – Valter Minute Apr 28 '14 at 08:29
1

If an application does not start it is mostly missing something. As you compiled for WindowsCE and CF3.5, the Compact Framework 3.5 runimes have to be installed on the WindowsCE device. Normally Compact Framework is part of Windows CE images, at least version 1.0, but who knows for your test device? If at least one CF is installed, an app requiring a newer CF version will show that on start by a message stating about the missed version. So either no CF is on your device, or something is goind real wrong.

You can run \Windows\cgacutil.exe to check the CF version installed on the device. The tool will show the version of installed CF.

You can debug using a TCP/IP connection or ActiveSync connection. See remote debuggung elsewhere in stackoverflow, I wrote a long aanswer about remote debug via TCP/IP. Or does your device neither have USB and WLAN or ENET?

Update: Here is the answer for remote debug via tcp/ip: VS2008 remotely connect to Win Mobile 6.1 Device This will also enable the remote deployment "In Project > Properties... > Devices, the "Deploy the latest version of the .NET Compact Framework (including Service Packs)" is checked. Is this as it should be?"

Are the earlier apps you wrote also written .NET? Compact framework does not care about the processor architecture, only the CF runtimes have to match the processor. So you do not need an x86 target as if you write a native C/C++ SmartDevice project.

To your comments: a) CF1.0 is installed on the device. b) the exe built on the colleagues computer seems to be built for CF1 and therefor runs OK. c) your exe is built for CF 3.5 and does not run as there is no CF3.5 runtime on the device. d) most CF exe files are very small as long as they do not include large resources or ...

Conclusion so far: Install the CF3.5 runtime onto the device: http://msdn.microsoft.com/en-us/library/bb788171%28v=vs.90%29.aspx. To run the legacy app on both devices, the referenced Motorola or other 3rd party runtimes must also be installed. I stringly recommand to setup your environment so you can use ActiveSync/WMDC for development, deployment and debugging of the device. If you are unable look for some more experienced colleague.

Community
  • 1
  • 1
josef
  • 5,951
  • 1
  • 13
  • 24
  • There is a \Program Files\.NET Compact Framework folder on the device, but it is empty, or at least appears to be (who put it there? why? why is it empty?) I would think that is the problem (it's empty), but one singular .exe of the app (built on a former colleague's machine) runs just fine on the device - so THAT version of the .exe has everything it needs. It's not a large .exe, so it does not appear as if he embedded all that stuff in the .exe (if that's even possible). So...still stumped. – B. Clay Shannon-B. Crow Raven Apr 25 '14 at 15:28
  • "So either no CF is on your device, or something is goind real wrong." I must have CF, or the "legacy" .exe would not run, right? "...real wrong"? It is quite likely that that is, indeed, the case. – B. Clay Shannon-B. Crow Raven Apr 25 '14 at 15:30
  • "You can run \Windows\cgacutil.exe to check the CF version installed on the device. The tool will show the version of installed CF." It says, "MS .NET CF 1.0.3316.00" I'm guessing that's an old version. If my guess is sagacious, do I need to update the CF version, or downdate how I'm targeting the app as I build it? – B. Clay Shannon-B. Crow Raven Apr 25 '14 at 15:36
  • "Are the earlier apps you wrote also written .NET?" I've only written one (which does not run) and have updated/maintained another which, until recently, ran fine on multiple devices we have here. – B. Clay Shannon-B. Crow Raven Apr 25 '14 at 15:48
  • 1. The exe built on colleagues machine seems to be built for CF1 (Visual Studio 2003 or 2005?); 2./3. From your comments it seems that CF1 is installed on your device. 4. You need to install CF3.5 onto the device: http://msdn.microsoft.com/en-us/library/bb788171%28v=vs.90%29.aspx – josef Apr 26 '14 at 05:13
  • The erstwhile/absquatulated dev who architected the main project said the devices could not host CF 3.5 (not enough space or some such). So I need to "downgrade" the device which I upgraded to 3.5 to the lesser version. – B. Clay Shannon-B. Crow Raven Apr 28 '14 at 15:58
  • "VS2008 remotely connect to Win Mobile 6.1 Device" Are Motorola/Symbol 3090 and 3190 devices Win Mobile 6.1 devices? – B. Clay Shannon-B. Crow Raven Apr 28 '14 at 16:01
  • 1
    The 3090 and 3190 can come from Motorola/Symbol with different OS selections. Are you able to recognize visually if a device is running CE or Mobile? A Mbile device has a task and info bar at the top and a home or today screen. A Windows CE device can look like the OEM wants. Mostly a WinCE device has a task bar at bottom of screen. AND, you cannot downgrade a WM device which comes with NetCF 3.5. – josef Apr 29 '14 at 08:19
  • The 3190 looks like a "basic", "regular" Windows desktop. It has a "wallpaper" that says, "Windows Embedded CE 6.0" I have pasted above (Update 9) a scream shot of the 3090, as seen on "Remote Display Control for Windows CE" – B. Clay Shannon-B. Crow Raven Apr 29 '14 at 15:38
  • 1
    So the 3190 is running Windows Embedded CE 6. There should be a Board Support Package by Motorola for that OEM Windows CE6 image. I assume the 3190 is using an Arm XScale processor as it is also available with Windows Mobile 6.1. You should contact Motorola support. – josef May 01 '14 at 08:50
  • I have no idea what a board support package is or what it would it do for me/how I would use it. How does one determine which processor the device has? I can look at the settings and see the CE version and the CF version, but I don't see where processor type is displayed. Can these be seen via the command line somehow? – B. Clay Shannon-B. Crow Raven May 01 '14 at 15:45