【发布时间】: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