C# 如何从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

我使用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;
}
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
not
SerialPort
的类。它也没有
Read()
Write
方法。根据您发布的代码,您使用的是来自SDF 1x的
SerialPort
,这是一个完全独立的代码库,具有完全不同的对象模型,上面的伪代码就是为其设计的(尽管它通常适用于任何实现,因为它是伪代码);我以为我在使用OpenNETCF,我支持该单元中的某些内容,因为它的使用没有变灰…请参阅更新8。严格地说,两者都是“OpenNETCF”,因为我们都编写并发布了它们,并且都有自己的名称空间。他们只是不同而已。就像FTP一样,我们有两个完全独立的库,它们具有不同的对象模型,但它们都是我们的。因为您更改了库,所以您以前的所有代码都变得毫无意义。设置只有您知道,但它看起来像19200,没有奇偶校验,1个停止位,等等。要发送数据,请将其放在输出属性中。要读取数据,请读取输入属性。好的,我来试一试。如何将奇偶校验设置为“无”或“否”?这些值不被接受。它是枚举吗?另外,波特率不接受整数…?好的,我得到了这个部分:bps.BaudRate=BaudRates.CBR_19200;要将
字节
数组来回转换为
字符串
,请使用
System.Text.Encoding
类。所以使用
setting=Encoding.ASCII.GetString(inputBytes)