C# 如何从OpenNETCF.IO.Ports.SerialPort读取字符串?
我使用OpenNETCF.IO.Ports.SerialPort将命令写入皮带打印机,方法如下:C# 如何从OpenNETCF.IO.Ports.SerialPort读取字符串?,c#,serial-port,compact-framework,windows-ce,opennetcf,C#,Serial Port,Compact Framework,Windows Ce,Opennetcf,我使用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
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;
}
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());}
}
}
…现在我需要读取从“get val”调用返回的值,但我不知道如何读取,也不知道如何读取。我有以下开始,但不知道如何“填空”:
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(字符串值)在…”
更新2
我补充说:
serialPort.ReadTimeout = 500;// made no difference
更新3
基于此,我尝试通过以下方式使其工作:
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;
}
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”之后添加了以下内容:
…它给我的只是一无所获(一个没有“内部文本”的消息框);在热启动设备之前,我让它弹出32次
更新8
好的,那么,我站在更正-我没有使用OpenNETCF串行端口,因为没有这样的东西。因此,我正试图根据提供的伪代码ctacke来实现这一点。我现在尝试使用:
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中获取实际值,而不是仅仅查看其类型的表示吗?它正在读取字节。缓冲区是读取字节的位置(由偏移量和计数修改),而返回值是读取的字节数。典型的流类型的东西
文档在这里:我注意到的第一件事是,您正在使用一个名为
SerialPort
的类,这意味着您正在使用SDF 1.x中的代码,该类的最新版本可以追溯到2005年左右。我不确定我会不会对这件事过于热心。我在那之后创建了一个代码,但它的工作方式不同——它是按照VB6串行端口对象模型建模的。老实说,我甚至不记得是谁在SDF1.x中编写了代码——可能是我,也可能不是。我认为不仅仅是从我看到的代码风格来判断
我想问的是,为什么您不只是使用内置的CF串行内容,但如果您使用的是SDF 1.x,那么您可能使用的CF版本早于包含串行端口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);
这些文档不适用于OpenNETCF的SerialPort,因为它似乎没有任何文档。它可以用同样的方式,但它没有示例代码,只有“理论”。啊,我明白了。没有发现你正在使用Opennet CF。我很确定它们遵循相同的API约定。正确,它遵循标准流约定。我使用的是OpenNETCF库-这就是我使用的串行端口。我不同意。Codeplex串行库有一个名为
Port
notSerialPort
的类。它也没有Read()
或Write
方法。根据您发布的代码,您使用的是来自SDF 1x的SerialPort
,这是一个完全独立的代码库,具有完全不同的对象模型,上面的伪代码就是为其设计的(尽管它通常适用于任何实现,因为它是伪代码);我以为我在使用OpenNETCF,我支持该单元中的某些内容,因为它的使用没有变灰…请参阅更新8。严格地说,两者都是“OpenNETCF”,因为我们都编写并发布了它们,并且都有自己的名称空间。他们只是不同而已。就像FTP一样,我们有两个完全独立的库,它们具有不同的对象模型,但它们都是我们的。因为您更改了库,所以您以前的所有代码都变得毫无意义。设置只有您知道,但它看起来像19200,没有奇偶校验,1个停止位,等等。要发送数据,请将其放在输出属性中。要读取数据,请读取输入属性。好的,我来试一试。如何将奇偶校验设置为“无”或“否”?这些值不被接受。它是枚举吗?另外,波特率不接受整数…?好的,我得到了这个部分:bps.BaudRate=BaudRates.CBR_19200;要将字节
数组来回转换为字符串
,请使用System.Text.Encoding
类。所以使用setting=Encoding.ASCII.GetString(inputBytes)代码>