我一直在维护一个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;
}
}
}
基于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));
}
}
}
然而,运行新版本并没有显示任何内容 - 它只是"闪烁"在杰克·鲁比的友好访问之后,与李·哈维·奥斯瓦尔德一样多的冗长。
问题可能与this有关,如果有,请问如何解决?
我更新版本的an existing app和这个全新且简单的应用程序拒绝运行的情况表明在编码,构建或部署过程中存在某些根本性缺陷。
由于这是一个最小的实用程序,它(以及我的遗产,更多涉及)应用程序无法正常工作的原因可能与项目属性,它是如何构建,所需文件无关复制过,或...... ???
注意:桌面图标是"泛型" (看起来像一个空白的白色形式);这或许表明存在问题,但它是否表明存在问题或是否是一个次要的(仅限美学)问题?
在项目>属性...,平台设置为"活动(任何CPU)"和平台目标相同("活动(任何CPU)")
我读过这是错的,它应该是" x86",但是没有" x86"选项可用 - 任何CPU是唯一的......?!?
在项目>属性...>设备," 部署最新版本的.NET Compact Framework(包括Service Pack)"检查。这是应该的吗?
好的,这是所有这一切中非常奇怪的部分:
我需要在这些Motorola / Symbol 3090和3190手持设备上运行两个CF / CE应用程序。
一个是上面讨论的这个简单的实用程序。我发现它实际上 在其中一个设备(3190,FWIW)上运行。所以它在一台设备上运行,但在另一台设备上运行。
然而,其他(遗留).exe则相反 - 它在3090上运行(实用程序甚至不启动),但不在3190上。
3190满足了实用程序的需求,3090满足了遗留用户的需求。然而,遗留应用程序的新版本无法在上运行< / em>设备!
我很困惑;我觉得Casey Stengel在他的三个捕手中说过一次时必须要有:&#34; 我有一个可以扔但却无法捕捉的,一个可以抓住但不能扔的,一个可以击中但无法做到的人。&#34;
3190安装了较新版本的CF;似乎新旧应用程序都应该在新设备上使用较新的CE运行,但它们不是 - 只有针对新框架构建的应用程序才会运行...
以下是3090的样子:
所以我有两个exes,一个在设备上运行(现在都是两个),另一个将在两个设备上运行。这两个exesw看起来几乎相同。我将它们与三种工具进行了比较:Red Gates&#39; .NET Reflector; JetBrains公司&#39; dotPeek和Dependency Walker。
这是我发现的:
Dependency Walker 两者似乎都有关于缺少依赖关系的相同错误(我没有将它们放在同一文件夹中,其依赖程序集可能存在问题)
.NET Reflector 非工作文件具有此工作文件不包含的条目:
[assembly: Debuggable(0x107)]
这是问题,如果是,我该如何更改?
JetBrains dotPeek exe的工作副本中的引用都是版本1.0.50000.0
非工作exe具有相同的引用列表和相同的版本号。
但是存在这种差异:
对于工作.exe,dotPeek说,&#34; 1.4.0.15,msil, Pocket PC v3.5 &#34; 对于非工作的.exe,dotPeek说,&#34; 1.4.0.15,msil, .Net Framework v4.5 &#34;
这是问题,如果是,我该如何更改非工作.exe以匹配工作?
这最后令人不安,主要是因为我认为项目的非工作(较新)版本中没有地方可以使用&#34; 4.5&#34;字符串存在。 dotPeek哪里可以获得这些信息?
我做现在知道这个问题介于这两个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
更具体地说,我以某种方式进行了无限循环;通过捣碎&#34; Ent&#34;手持设备上的药丸(这是按钮的样子 - &#34;菱形&#34;) - 听起来像沙鼠一样跳舞(因为调试MessageBox.Show()s弹出两个方法被无休止地广告(字面意思)恶心被解雇。
答案 0 :(得分:1)
您可以尝试在调试器中运行它并检查它失败的位置吗? 你可以在Program.main的开头放置一个断点并检查它是否到达了吗? 调试输出也可能会给你一些有趣的提示。
答案 1 :(得分:1)
如果应用程序无法启动,则大多数情况下都会丢失。在为WindowsCE和CF3.5编译时,必须在WindowsCE设备上安装Compact Framework 3.5 runimes。 通常,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 这也将启用远程部署“在项目&gt;属性...&gt;设备中, “检查部署最新版本的.NET Compact Framework(包括Service Pack)”。是否应该如此?“
您编写的早期应用程序是否也编写了.NET?紧凑的框架不关心处理器架构,只有CF运行时必须匹配处理器。因此,您不需要像编写本机C / C ++ SmartDevice项目那样的x86目标。
对你的评论: 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或其他第三方运行时。我强烈建议您设置环境,以便可以使用ActiveSync / WMDC进行设备的开发,部署和调试。如果你找不到更有经验的同事。