0

我一直在维护一个 Windows CE 应用程序一段时间(一年多),并且不时生成它的新版本,将它们复制到手持设备并在那里运行新版本。

不过,今天,我第一次创建了一个新的 Windows CE 应用程序。这是一个非常简单的实用程序。

为了在 VS 2008 中创建它,我选择了一个 C#“智能设备项目”模板,添加了一些控件和一些代码,然后构建了它。

以下是我选择的一些选项:

在此处输入图像描述

我将通过构建项目生成的 .exe 复制到手持设备的 Program Files 文件夹中:

在此处输入图像描述

...但它不会运行。是不是在错误的位置?是否需要复制一些辅助文件?我需要做一些其他的设置才能让它运行吗?要不然是啥?

更新

由于内容不多,我将粘贴下面的所有代码,以防有人认为我的代码可能是问题所在:

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;
        }

    }
}

更新 2

基于,我向应用程序添加了一个全局异常处理程序,因此 Program.cs 现在是:

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));
        }
    }
}

然而,运行新版本并没有显示任何内容——它只是在 Jack Ruby 的友好访问之后短暂地“闪烁”了与 Lee Harvey Oswald 一样多的冗长。

更新 3

问题是否与有关,如果是,如何解决?

我的现有应用程序的更新版本和这个全新的简单应用程序都拒绝运行的情况表明,在编码、构建或部署过程中的某个地方存在根本缺陷。

更新 4

由于这是一个最小的实用程序,它(以及我的遗留,涉及更多)应用程序无法运行的原因可能与项目属性、构建方式、未复制所需文件或...... ???

注意:桌面图标是“通用的”(看起来像一个空白的白色表格);这可能表明存在问题,但它是否表明有问题或者是一个小问题(仅限美学)?

更新 5

在 Project > Properties... 中,Platform 设置为“Active (Any CPU)”和 Platform target 相同(“Active (Any CPU)”)

我读过这是错误的,它应该是“x86”,但没有可用的“x86”选项 - 任何 CPU 都是唯一的......?!?

更新 6

在项目 > 属性... > 设备中,选中“部署最新版本的 .NET Compact Framework(包括服务包) ”。这是应该的吗?

更新 7

好的,这是所有这一切中真正奇怪的部分:

我有两个 CF/CE 应用程序需要在这些 Motorola/Symbol 3090 和 3190 手持设备上运行。

一个是上面讨论的这个简单的实用程序。我发现它确实可以在其中一台设备(3190,FWIW)上运行。所以它在一台设备上运行,但不在另一台设备上运行。

但是,另一个(旧版).exe 则相反 - 它在 3090 上运行(该实用程序甚至不会启动),但不在 3190 上。

因此,3190 满足了实用程序的需求,3090 满足了旧版实用程序的需求。但是,旧版应用程序的新版本不能在任何设备上运行!

我很困惑;在谈到他的三个接球手时,我的感觉就像凯西·斯坦格尔(Casey Stengel)所说的那样:“我有一个会投但不会接球,一个会接球但不会投球,还有一个会击球但两者都不会。 "

更新 8

3190 安装了更新版本的 CF;似乎新旧应用程序都应该在具有较新 CE 的新设备上运行,但它们不会——只有针对/为新框架构建的应用程序才可以......

更新 9

这是 3090 的外观:

在此处输入图像描述

更新 10

所以我有两个 exe,一个在设备上运行(现在都在),另一个在这两个设备上都不运行。这两个exesw似乎几乎相同。我将它们与三个工具进行了比较:Red Gates 的 .NET Reflector;JetBrains 的 dotPeek 和 Dependency Walker。

这是我发现的:

Dependency Walker 两者似乎都有关于缺少依赖项的相同错误(我没有将它们与它们的依赖程序集放在同一个文件夹中,这可能是那里的问题)

.NET Reflector 非工作文件具有工作文件没有的以下条目:

[assembly: Debuggable(0x107)]

这是问题吗?如果是,我该如何改变它?

JetBrains dotPeek exe工作副本中的References都是1.0.50000.0版本

非工作 exe 具有相同的参考列表和相同的版本号。

但是有这个区别:

对于工作的 .exe,dotPeek 说,“ 1.4.0.15,msil,Pocket PC v3.5 ” 对于非工作的 .exe,dotPeek 说,“ 1.4.0.15,msil,.Net Framework v4.5

这是问题吗?如果是,我该如何更改非工作的 .exe 以匹配工作的 .exe?

最后一个令人不安,主要是因为我在项目的非工作(较新)版本中没有看到存在“4.5”字符串的地方。dotPeek 可以从哪里获得这些信息?

更新 11

我现在确实知道问题出在这两个 MessageBox.Show() 之间,因为我看到的第一个,但不是第二个:

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

更新 12

更具体地说,我以某种方式进行了无限循环;通过在手持设备上捣碎“Ent”药丸(这就是按钮的样子——“菱形”)——听起来像是沙鼠踢踏舞(因为在两种方法中调试 MessageBox.Show()s 时弹出并被关闭和无限广告(字面意思)恶心)。

4

2 回答 2

1

您可以尝试在调试器中运行它并检查它失败的地方吗?您可以在 Program.main 的开头放置一个断点并检查它是否已到达?调试输出也可能会给你一些有趣的提示。

于 2014-04-24T06:43:04.130 回答
1

如果一个应用程序没有启动,它主要是缺少一些东西。当您为 WindowsCE 和 CF3.5 编译时,必须在 WindowsCE 设备上安装 Compact Framework 3.5 运行时。通常 Compact Framework 是 Windows CE 映像的一部分,至少是 1.0 版,但谁知道您的测试设备呢?如果至少安装了一个 CF,则需要更新 CF 版本的应用程序将在启动时显示一条消息,说明缺少的版本。所以要么你的设备上没有 CF,要么真的有问题。

您可以运行 \Windows\cgacutil.exe 来检查设备上安装的 CF 版本。该工具将显示已安装 CF 的版本。

您可以使用 TCP/IP 连接或 ActiveSync 连接进行调试。请参阅 stackoverflow 中其他地方的远程调试,我写了一篇关于通过 TCP/IP 进行远程调试的长答案。或者您的设备没有 USB 和 WLAN 或 ENET?

更新:这是通过 tcp/ip 进行远程调试的答案:VS2008 远程连接到 Win Mobile 6.1 设备这也将启用远程部署“在项目 > 属性... > 设备中,”部署最新版本的 .NET紧凑框架(包括服务包)”被选中。这是应该的吗?”

您编写的早期应用程序是否也是使用 .NET 编写的?紧凑框架不关心处理器架构,只有 CF 运行时必须匹配处理器。因此,您不需要 x86 目标,就像编写本机 C/C++ SmartDevice 项目一样。

对您的意见: a) CF1.0 已安装在设备上。b) 在同事计算机上构建的 exe 似乎是为 CF1 构建的,因此运行正常。c) 您的 exe 是为 CF 3.5 构建的,并且由于设备上没有 CF3.5 运行时而无法运行。d) 大多数 CF exe 文件都非常小,只要它们不包含大量资源或...

到目前为止的结论:在设备上安装 CF3.5 运行时:http: //msdn.microsoft.com/en-us/library/bb788171%28v=vs.90%29.aspx。要在两台设备上运行旧版应用程序,还必须安装引用的 Motorola 或其他第 3 方运行时。我强烈建议设置您的环境,以便您可以使用 ActiveSync/WMDC 进行设备的开发、部署和调试。如果您无法寻找一些更有经验的同事。

于 2014-04-25T15:22:42.067 回答