【问题标题】:Why is my CE app refusing to run?为什么我的 CE 应用程序拒绝运行?
【发布时间】:2014-04-23 18:05:22
【问题描述】:

我已经维护 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

基于this,我向应用程序添加了一个全局异常处理程序,因此 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

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

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

更新 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。

这是我发现的:

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

.NET 反射器 非工作文件有这个工作文件没有的条目:

[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 以匹配工作的?

最后一个令人不安,主要是因为我在项目的非工作(较新)版本中没有看到“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 弹出并被关闭和无限广告(字面意思)恶心)。

【问题讨论】:

  • 事实证明,真正的问题是由于安装程序执行的某些代码导致设备始终尝试自动启动应用程序;所以当我尝试替换 .exe 时它已经在运行(尝试)

标签: deployment compact-framework windows-ce smart-device handhelddevice


【解决方案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 remotely connect to Win Mobile 6.1 Device 这也将启用远程部署“在项目 > 属性... > 设备中,”部署最新.NET Compact Framework 的版本(包括服务包)”被选中。这是应该的吗?”

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

致您的 cmets: 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 进行设备的开发、部署和调试。如果您无法寻找更有经验的同事。

【讨论】:

  • 设备上有一个\Program Files\.NET Compact Framework 文件夹,但它是空的,或者至少看起来是空的(谁把它放在那里的?为什么?为什么它是空的?)我会认为这是问题所在(它是空的),但是应用程序的一个单一的 .exe(建立在前同事的机器上)在设备上运行得很好 - 所以那个版本的 .exe 拥有它需要的一切。它不是一个大的 .exe,因此看起来好像他将所有这些东西都嵌入到了 .exe 中(如果可能的话)。所以……还是难住了。
  • “所以要么你的设备上没有 CF,要么真的出了问题。”我必须有 CF,否则“旧版”.exe 将无法运行,对吗? “……真的错了”?很可能确实是这样。
  • "您可以运行 \Windows\cgacutil.exe 来检查设备上安装的 CF 版本。该工具将显示已安装 CF 的版本。"它说,“MS .NET CF 1.0.3316.00”我猜这是一个旧版本。如果我的猜测是明智的,我是否需要更新 CF 版本,或者在构建应用程序时更新我定位应用程序的方式?
  • 3090 和 3190 可以来自 Motorola/Symbol,具有不同的操作系统选择。如果设备运行 CE 或 Mobile,您是否能够直观地识别? Mbile 设备顶部有一个任务和信息栏,还有一个主屏幕或今日屏幕。 Windows CE 设备可以看起来像 OEM 想要的那样。大多数情况下,WinCE 设备在屏幕底部都有一个任务栏。而且,您不能降级 NetCF 3.5 附带的 WM 设备。
  • 所以 3190 正在运行 Windows Embedded CE 6。摩托罗拉应该为该 OEM Windows CE6 映像提供板级支持包。我假设 3190 使用的是 Arm XScale 处理器,因为它也可用于 Windows Mobile 6.1。您应该联系摩托罗拉支持。
【解决方案2】:

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

【讨论】:

  • 不,我不能那样调试它;它不是,而且我认为不能为此设置(相信我,我已经尝试过,并且跳过了很多圈,在这个过程中让我的尾羽被烧焦了)。我们在 PC 上构建,将 exe 复制到掌上电脑,然后运行它。 “调试”是通过MessageBox.Show()等方式
  • 您是否尝试构建一个空的 .NET CF 应用程序并在目标上运行它。只是为了检查这是否是特定于项目的问题,或者目标设备或您的开发 PC 上是否有问题。
  • 这个应用程序尽可能简单,所以我会说手持设备或 PC 有问题。 -- 或本地化的 E.M.P.击中了我的立方体。
  • 很简单,但是比向导生成的“hello world”复杂多了。检查 hello world 是否有效有助于了解应用程序或目标上的 .NET 运行时是否有问题,恕我直言。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-21
  • 2023-03-15
  • 2021-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-16
相关资源
最近更新 更多