我使用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()方法接受一个字节数组(“buffer”),后跟一个int(“offset”)和另一个int(“count”),并返回一个int。我不知道使用什么作为args或者如何处理结果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(字符串值)处......”
我补充说:
serialPort.ReadTimeout = 500;// made no difference
基于this,我尝试以这种方式工作:
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);
如果我做给它parens:
Thread readThread = new Thread(ReadSetting());
...它告诉我,“ Argument'1':无法从'void'转换为System.Threading.ThreadStart'”
- 和
“ System.Threading.Thread.Thread(System.Threading.ThreadStart)的最佳重载方法匹配'有一些无效的参数”
使用此代码:
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。
这次尝试:
serialPort.WriteLine(cmd);
setting = serialPort.ReadExisting();
...结束与第一次更新非常相似(“System.NotSupportedException:尚未在OpenNETCF.IP.Ports.SerialPort.ReadExisting()at ...”)
好的,我在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循环中似乎存在无限循环。
我在“ReadByte”之后添加了这个:
MessageBox.Show(c.ToString());
...所有它都显示我什么都没有(没有“内部文本”的MessageBox);在我热启动设备之前,我让它弹出32次。
好的,那么,我的立场得到纠正 - 我不使用OpenNETCF SerialPort,因为没有这样的事情。基于提供的伪代码ctacke,我正在尝试并拥有它。我现在正在尝试使用:
Port serialPort = new Port();
serialPort.Settings = whateverPortSettingsYouNeed;
serialPort.Open();
serialPort.Send(cmd);
...但我不知道“whateverPortSettingsYouNeed”应该是什么,没有“Send”方法,我不知道用什么来代替ReadByte()
我现在有这个设置:
BasicPortSettings bps = new BasicPortSettings();
bps.BaudRate = 19200;
//bps.ByteSize = ?;
//bps.Parity = None;
//bps.StopBits = 1;
Port serialPort = new Port();
serialPort.Settings = bps;
...但是,正如您所看到的,我不知道大多数值应该是什么。
编译:
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;
}
}
......现在我会看看它是否真的有用......
我发现(艰难的)我必须在设置Output val之前打开端口;它现在是:
serialPort.Open();
byte[] outputBytes = Encoding.ASCII.GetBytes(cmd);
serialPort.Output = outputBytes;
byte[] inputBytes = serialPort.Input;
setting = inputBytes.ToString();
...但是读入设置的是“System.Byte []”
我需要实际获取inputBytes中的值,而不只是查看其类型的表示形式?
答案 0 :(得分:2)
正在读取字节。缓冲区是读入字节的位置(由偏移量和计数修改),而返回值是读取的字节数。典型的流式东西。
docos在这里:http://msdn.microsoft.com/en-us/library/ms143549(v=vs.90).aspx
答案 1 :(得分:1)
我注意到的第一件事是您正在使用名为SerialPort
的类,这意味着您正在使用SDF 1.x中的代码,该代码可以追溯到最近的大约2005年。不确定我是否过于热衷于此。我在该代码之后创建了一个open source library that contains just a Port
class,但它的工作方式不同 - 它是在VB6串行端口对象模型之后建模的。老实说,我甚至不记得是谁在SDF 1.x中编写代码 - 可能是我,可能没有。我认为不仅仅是根据我看到的代码风格来判断。
我打算质疑你为什么不使用内置的CF连续剧,但如果你使用的是SDF 1.x,你很可能会使用预装的CF版本-dates包含串行端口API。
对于你现在正在使用的那个,我认为它在某种程度上取决于预期的数据回归方式,但伪代码看起来像这样:
var port = new SerialPort;
port.Settings = whateverPortSettingsYouNeed;
port.Open();
....
// send the command
port.Send(myCommand);
// get a synchronous, newline-delimited response
var response = new StringBuilder();
char c;
do
{
c = (char)port.ReadByte();
// see if it actually read anything
if(c == '\0')
{
// wait a little bit, then try again - you will want to put in a timeout here
Thread.Sleep(10);
continue;
}
response.Append(c);
// you may want to check for response "reasonableness" here
} while(c != \n');
DoSomethingWithResponse(response);