Я поддерживаю приложение Windows CE в течение некоторого времени (более года) и время от времени выпускаю его новые версии, копируя их на портативные устройства и запуская там новые версии.
Однако сегодня я впервые создал новое приложение для Windows CE. Это очень простая утилита.
Чтобы создать его в VS 2008, я выбрал шаблон C# «Smart Device Project», добавил несколько элементов управления и немного кода и построил его.
Вот некоторые из вариантов, которые я выбрал:
Я скопировал .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
В «Проект» > «Свойства...» для платформы установлено значение «Активен (любой ЦП)», а цель платформы — та же («Активная (любой ЦП)»)
Я читал, что это неправильно, что это должно быть «x86», но нет доступной опции «x86» - любой процессор является единственным ...?!?
ОБНОВЛЕНИЕ 6
В разделе «Проект» > «Свойства...» > «Устройства» установлен флажок «Развернуть последнюю версию .NET Compact Framework (включая пакеты обновлений)». Это так и должно быть?
ОБНОВЛЕНИЕ 7
Хорошо, вот действительно странная часть всего этого:
У меня есть два приложения CF/CE, которые мне нужно запустить на этих портативных устройствах Motorola/Symbol 3090 и 3190.
Одним из них является эта простая утилита, описанная выше. Я обнаружил, что на самом деле он работает на одном из устройств (3190, FWIW). То есть на одном устройстве работает, а на другом нет.
ОДНАКО, у другого (устаревшего) .exe все наоборот - он запускается на 3090 (где утилита даже не запустится), а на 3190 - нет.
Таким образом, потребности утилиты удовлетворяются 3190, а потребности устаревшей утилиты удовлетворяются 3090. Однако НОВАЯ версия устаревшего приложения не работает на ни одном устройстве!
я сбит с толку; Я чувствую себя так же, как Кейси Стенгель, говоря об одном из трех своих кетчеров: "Я есть тот, который может бросить, но не может поймать, тот, кто может поймать, но не может бросить, и тот, кто может ударить, но не может ни того, ни другого."
ОБНОВЛЕНИЕ 8
На модели 3190 установлена более новая версия CF; кажется, что и новое, и старое приложения должны работать на новом устройстве с более новым CE, но это не так - работает только то, которое создано против/для новой платформы...
ОБНОВЛЕНИЕ 9
Вот как выглядит 3090:
ОБНОВЛЕНИЕ 10
Итак, у меня есть два исполняемых файла, один из которых работает на устройствах (сейчас оба), а другой не работает ни на одном из устройств. Два EXEW кажутся почти идентичными. Я сравнил их с тремя инструментами: .NET Reflector от Red Gates; dotPeek от JetBrains и Dependency Walker.
Вот что я нашел:
Dependency Walker Кажется, у обоих одинаковые ошибки об отсутствующих зависимостях (у меня их не было в одной папке с их зависимыми сборками, вероятно, проблема в этом)
.NET Reflector В нерабочем файле есть запись, которой нет в рабочем файле:
[assembly: Debuggable(0x107)]
Является ли это проблемой, и если да, то как я могу это изменить?
JetBrains dotPeek Все ссылки в рабочей копии исполняемого файла относятся к версии 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() в двух методах всплывает и закрывается через и до бесконечности (буквально) тошнота).