Почему мое приложение CE отказывается работать?
Я поддерживаю приложение Windows CE уже некоторое время (более года) и время от времени выпускаю его новые версии, копируя их на портативные устройства и запуская там новые версии.
Однако сегодня я впервые создал новое приложение Windows CE. Это очень простая утилита.
Чтобы создать его в VS 2008, я выбрал шаблон "Smart Device Project" на 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));
}
}
}
Тем не менее, запуск новой сборки ничего не показывает - она на мгновение "вспыхивает" примерно с такой же многословностью, как Ли Харви Освальд после дружеского визита Джека Руби.
ОБНОВЛЕНИЕ 3
Может ли проблема быть связана с этим, и если да, то как ее решить?
Обстоятельства того, что моя обновленная версия существующего приложения И это совершенно новое и простое приложение отказываются работать, указывают на то, что в процессе кодирования, построения или развертывания есть что-то принципиально ошибочное.
ОБНОВЛЕНИЕ 4
Поскольку это минимальная утилита, причина того, что приложение (и мое устаревшее, гораздо более сложное) приложение не работают, может иметь какое-то отношение к свойствам проекта, способу его сборки, необходимому файлу, который не копируется, или...???
ПРИМЕЧАНИЕ. Значок на рабочем столе "универсальный" (выглядит как пустая белая форма); возможно, это указывает на проблему, но указывает ли это на что-то не так или это небольшая (только для эстетики) проблема?
ОБНОВЛЕНИЕ 5
В Project > Properties... для платформы установлено значение "Active (любой процессор)", а целевой объект платформы ("активный (любой процессор)")
Я читал, что это неправильно, что это должно быть "x86", но нет опции "x86" - любой ЦП является единственным...?!?
ОБНОВЛЕНИЕ 6
В Project> Свойства... > Устройства установлен флажок "Развернуть последнюю версию.NET Compact Framework (включая пакеты обновления)". Это так и должно быть?
ОБНОВЛЕНИЕ 7
Хорошо, вот действительно странная часть всего этого:
У меня есть два приложения CF/CE, которые мне нужно запустить на этих портативных устройствах Motorola/Symbol 3090 и 3190.
Одним из них является эта простая утилита, рассмотренная выше. Я обнаружил, что он действительно работает на одном из устройств (3190, FWIW). Таким образом, он работает на одном устройстве, но не на другом.
ОДНАКО другой (устаревший) .exe противоположен - он работает на 3090 (где утилита даже не запускается), но не на 3190.
Таким образом, потребности утилиты удовлетворяются 3190, а потребности устаревшей утилиты - 3090. Однако НОВАЯ версия устаревшего приложения не работаетни на одном устройстве!
Я сбит с толку; Я чувствую, что Кейси Стенгел, должно быть, когда-то говорил о своих трех ловцах: "Уменя есть тот, кто может бросить, но не может поймать, тот, который может поймать, но не может бросить, и тот, кто может ударить, но не может ни того, ни другого."
ОБНОВЛЕНИЕ 8
На 3190 установлена более новая версия CF; кажется, что и новое, и старое приложения должны запускаться на новом устройстве с новым CE, но они этого не делают - делает только одно, созданное для / для нового фреймворка...
ОБНОВЛЕНИЕ 9
Вот как выглядит 3090:
ОБНОВЛЕНИЕ 10
Итак, у меня есть два exe, один, который работает на устройствах (оба сейчас), а другой, который не будет работать ни на одном из устройств. Два exesw кажутся почти идентичными. Я сравнил их с тремя инструментами:.NET Reflector от Red Gates; JetBrains' dotPeek и Dependency Walker.
Вот что я нашел:
Обходчик зависимостей Оба, похоже, имеют одинаковые ошибки в отношении отсутствующих зависимостей (у меня их не было в одной папке с их зависимыми сборками, вероятно, проблема там)
Отражатель.NET В нерабочем файле есть эта запись, которой нет в рабочем файле:
[assembly: Debuggable(0x107)]
Это проблема, и если да, то как я могу ее изменить?
JetBrains dotPeek Все ссылки в рабочей копии exe версии 1.0.50000.0
Нерабочий исполняемый файл имеет идентичный список ссылок и тот же номер версии.
Есть разница, однако:
Для рабочего.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() в двух методах всплывает и сбрасывается и над бесконечностью до (буквально) тошноты).
2 ответа
Если приложение не запускается, оно в основном чего-то не хватает. После компиляции для 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. Посмотрите удаленную отладку в другом месте в stackru, я написал длинный ответ об удаленной отладке через TCP/IP. Или ваше устройство не имеет USB и WLAN или ENET?
Обновление: вот ответ для удаленной отладки через tcp / ip: VS2008 удаленно подключается к устройству Win Mobile 6.1. Это также включает удаленное развертывание "В Project > Свойства... > Устройства" Развертывание последней версии.NET Compact Framework (включая Service Packs)"проверено. Это так и должно быть?"
Написанные ранее приложения также написаны на.NET? Компактная структура не заботится о архитектуре процессора, только время выполнения CF должно соответствовать процессору. Таким образом, вам не нужна цель x86, как если бы вы писали собственный проект SmartDevice для C/C++.
К вашим комментариям: а) CF1.0 установлен на устройстве. б) исполняемый файл, созданный на компьютере коллег, кажется, построен для CF1 и поэтому работает нормально. c) ваш exe-файл создан для CF 3.5 и не работает, так как на устройстве нет среды выполнения CF3.5. d) большинство exe-файлов CF очень малы, если они не содержат больших ресурсов или...
Заключение на данный момент: установите среду выполнения CF3.5 на устройство: http://msdn.microsoft.com/en-us/library/bb788171%28v=vs.90%29.aspx. Чтобы запустить устаревшее приложение на обоих устройствах, необходимо также установить указанную среду выполнения Motorola или других сторонних производителей. Я настоятельно рекомендую настроить вашу среду, чтобы вы могли использовать ActiveSync/WMDC для разработки, развертывания и отладки устройства. Если вы не можете найти более опытного коллегу.
Можете ли вы попробовать запустить его внутри отладчика и проверить, где он выходит из строя? Можете ли вы установить точку останова в начале Program.main и проверить, достигнута ли она? Отладочный вывод также может дать вам несколько интересных советов.