Я пишу команды на ленточный принтер с помощью OpenNETCF.IO.Ports.SerialPort следующим образом:
public static bool SendCommandToPrinter(string cmd)
{
bool success; // init'd to false by default
try
{
SerialPort serialPort = new SerialPort();
serialPort.BaudRate = 19200;
serialPort.Handshake = Handshake.XOnXOff;
serialPort.Open();
serialPort.Write(cmd);
serialPort.Close();
success = true;
}
catch // may not need a try/catch block, as success defaults to false
{
success = false;
}
return success;
}
... теперь мне нужно прочитать значение, возвращаемое вызовом "get val", но я не знаю, как это сделать, и я не смог найти, как это сделать. У меня есть следующее начало, но я не знаю, как «заполнить пробел»:
string getDeviceLang = string.Format("! U1 getvar {0}device.languages{0}", quote);
public static string GetSettingFromPrinter(string cmd)
{
string settingVal = string.Empty;
SerialPort serialPort = new SerialPort();
serialPort.BaudRate = 19200;
serialPort.Handshake = Handshake.XOnXOff;
serialPort.Open();
serialPort.Write(cmd); // do I even need this call to write?
settingVal = serialPort.Read() // ???
serialPort.Close();
return settingVal;
}
Метод OpenNETCF.IO.Ports.SerialPort Read() принимает массив байтов («буфер»), за которым следует целое число («смещение») и еще одно целое число («количество»), и возвращает целое число. Я не знаю, что использовать в качестве аргументов или что делать с результатом int.
ОБНОВИТЬ
Я пробовал это:
public static string GetSettingFromPrinter(string cmd)
{
string settingVal = string.Empty;
try
{
SerialPort serialPort = new SerialPort();
serialPort.BaudRate = 19200;
serialPort.Handshake = Handshake.XOnXOff;
serialPort.Open();
serialPort.Write(cmd);
// testing...
settingVal = serialPort.ReadLine();
serialPort.Close();
return settingVal;
}
catch (Exception x)
{
MessageBox.Show(x.ToString());
return settingVal;
}
}
... но это вознаграждает меня неудовлетворительным "System.NotSupportedException: еще не в OpenNETCF.IP.Ports.SerialPort.ReadTo(строковое значение) в..."
ОБНОВЛЕНИЕ 2
Я добавил это:
serialPort.ReadTimeout = 500;// made no difference
ОБНОВЛЕНИЕ 3
На основании этого я попытался заставить его работать следующим образом:
public class PrintUtils
{
static SerialPort _serialPort;
static bool keepReading = true;
static string settingVal = string.Empty;
. . .
public static string GetSettingFromPrinter(string cmd)
{
Thread readThread = new Thread(ReadSetting());
try
{
_serialPort = new SerialPort();
_serialPort.BaudRate = 19200;
_serialPort.Handshake = Handshake.XOnXOff;
_serialPort.Open();
while (keepReading)
{
_serialPort.WriteLine(cmd);
}
_serialPort.Close();
return settingVal;
}
catch (Exception x)
{
MessageBox.Show(x.ToString());
return settingVal;
}
}
public static void ReadSetting()
{
while (keepReading)
{
try
{
settingVal = _serialPort.ReadLine();
keepReading = settingVal.Equals(string.Empty);
}
catch (Exception ex) { MessageBox.Show(ex.ToString());}
}
}
... но я получаю в этой строке "Метод 'PDAClient.PrintUtils.Read()' без круглых скобок":
Thread readThread = new Thread(Read);
Если я делаю ставлю скобки:
Thread readThread = new Thread(ReadSetting());
... он говорит мне: "Аргумент '1': невозможно преобразовать 'void' в System.Threading.ThreadStart'"
-а также:
"Наилучшее совпадение перегруженного метода для System.Threading.Thread.Thread(System.Threading.ThreadStart)' содержит недопустимые аргументы"
ОБНОВЛЕНИЕ 4
И с этим кодом:
public static string GetSettingFromPrinter(string cmd)
{
string setting = string.Empty;
byte[] buffer = null;
try
{
SerialPort serialPort = new SerialPort();
serialPort = new SerialPort();
serialPort.BaudRate = 19200;
serialPort.Handshake = Handshake.XOnXOff;
serialPort.ReadTimeout = 500;
serialPort.Open();
serialPort.Write(cmd);
setting = Convert.ToString(serialPort.Read(buffer, 0, buffer.Length));
serialPort.Close();
return setting;
}
catch (Exception x)
{
MessageBox.Show(x.ToString());
return setting;
}
}
Я получаю NRE.
ОБНОВЛЕНИЕ 5
Эта попытка:
serialPort.WriteLine(cmd);
setting = serialPort.ReadExisting();
... заканчивается очень похоже на первое обновление ("System.NotSupportedException: еще не в OpenNETCF.IP.Ports.SerialPort.ReadExisting() в...")
ОБНОВЛЕНИЕ 6
Хорошо, я включил псевдокод в комментарий ctacke, и теперь у меня есть это:
const string quote = "\"";
. . .
string getDeviceLang = string.Format("! U1 getvar {0}device.languages{0}", quote);
. . .
String deviceLanguage = PrintUtils.GetSettingFromPrinter(getDeviceLang);
public static string GetSettingFromPrinter(string cmd)
{
string setting = string.Empty;
try
{
SerialPort serialPort = new SerialPort();
serialPort = new SerialPort();
serialPort.BaudRate = 19200;
serialPort.Handshake = Handshake.XOnXOff;
serialPort.ReadTimeout = 500;
serialPort.Open();
serialPort.WriteLine(cmd); // or Write()
// get a synchronous, newline-delimited response
StringBuilder response = new StringBuilder();
char c;
do
{
c = (char)serialPort.ReadByte();
response.Append(c);
} while(c != '\n');
serialPort.Close();
return setting;
}
catch (Exception x)
{
MessageBox.Show(x.ToString());
return setting;
}
... но он "зависает" - кажется, что в цикле do...while есть бесконечный цикл.
ОБНОВЛЕНИЕ 7
Я добавил это после "ReadByte":
MessageBox.Show(c.ToString());
... и все, что он мне показывает, это ничего (MessageBox без «внутреннего текста»); Я позволил ему появиться 32 раза, прежде чем я загрузил устройство.
ОБНОВЛЕНИЕ 8
Хорошо, тогда я исправлен - я не использовал последовательный порт OpenNETCF, так как его не существует. Итак, я пытаюсь получить это, основываясь на предоставленном псевдокоде. Я сейчас пытаюсь использовать:
Port serialPort = new Port();
serialPort.Settings = whateverPortSettingsYouNeed;
serialPort.Open();
serialPort.Send(cmd);
... но я не знаю, каким должен быть "whateverPortSettingsYouNeed", метода "Send" нет, и я не знаю, что использовать вместо ReadByte()
ОБНОВЛЕНИЕ 9
У меня это сейчас для настроек:
BasicPortSettings bps = new BasicPortSettings();
bps.BaudRate = 19200;
//bps.ByteSize = ?;
//bps.Parity = None;
//bps.StopBits = 1;
Port serialPort = new Port();
serialPort.Settings = bps;
... но, как видите, я не знаю, какими должны быть большинство значений.
ОБНОВЛЕНИЕ 10
Это компилирует:
public static string GetSettingFromPrinter(string cmd)
{
string setting = string.Empty;
try
{
BasicPortSettings bps = new BasicPortSettings();
bps.BaudRate = BaudRates.CBR_19200;
bps.Parity = OpenNETCF.IO.Serial.Parity.none;
bps.StopBits = OpenNETCF.IO.Serial.StopBits.one; //bps.StopBits.one;
Port serialPort = new Port("COM1:", bps);
byte[] outputBytes = System.Text.Encoding.ASCII.GetBytes(cmd);
serialPort.Output = outputBytes;
serialPort.Open();
byte[] bites = serialPort.Input;
setting = bites.ToString();
serialPort.Close();
return setting;
}
catch (Exception x)
{
MessageBox.Show(x.ToString());
return setting;
}
}
...Теперь я посмотрю, действительно ли это работает...
ОБНОВЛЕНИЕ 11
Я узнал (трудным путем), что мне нужно было открыть порт перед установкой выходного значения; это снег:
serialPort.Open();
byte[] outputBytes = Encoding.ASCII.GetBytes(cmd);
serialPort.Output = outputBytes;
byte[] inputBytes = serialPort.Input;
setting = inputBytes.ToString();
... но в настройках читается "System.Byte[]"
Что мне нужно, чтобы на самом деле получить значение в inputBytes, а не просто увидеть представление его типа?
byte
в массивString
и обратно, используйте классSystem.Text.Encoding
. Так что используйтеsetting = Encoding.ASCII.GetString(inputBytes);
- person tcarvin   schedule 12.06.2014