我试图在Windows通用应用程序中使用串行端口.我一直在使用Microsoft的Serial Sample应用程序作为模板,但是我遇到了一个相当奇怪的问题.
var dis = await DeviceInformation.FindAllAsync(SerialDevice.GetDeviceSelectorFromUsbVidPid(0x04D8, 0x000A)); var sp = await SerialDevice.FromIdAsync(dis[0].Id);
这是一个失败的片段.它与原始样本略有不同,因为它连接到具有特定供应商的第一个设备.现在,如果我把这个片段放在Microsoft生成的示例应用程序中,串口就打开了,一切都很好.但是,当我将此代码移动到我自己的项目中时,它总是null
从方法返回.
以下是MainPage.xaml.cs
Microsoft示例中的完整版本:我的
工作!
// Copyright (c) Microsoft. All rights reserved. using System; using System.Collections.ObjectModel; using System.Diagnostics; using System.Linq; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.Devices.Enumeration; using Windows.Devices.SerialCommunication; using Windows.Storage.Streams; using System.Threading; using System.Threading.Tasks; namespace SerialSample { public sealed partial class MainPage : Page { ////// Private variables /// private SerialDevice serialPort = null; DataWriter dataWriteObject = null; DataReader dataReaderObject = null; private ObservableCollectionlistOfDevices; private CancellationTokenSource ReadCancellationTokenSource; public MainPage() { this.InitializeComponent(); comPortInput.IsEnabled = false; sendTextButton.IsEnabled = false; listOfDevices = new ObservableCollection (); ListAvailablePorts(); } /// /// ListAvailablePorts /// - Use SerialDevice.GetDeviceSelector to enumerate all serial devices /// - Attaches the DeviceInformation to the ListBox source so that DeviceIds are displayed /// private async void ListAvailablePorts() { try { string aqs = SerialDevice.GetDeviceSelector(); var dis = await DeviceInformation.FindAllAsync(SerialDevice.GetDeviceSelectorFromUsbVidPid(0x04D8, 0x000A)); serialPort = await SerialDevice.FromIdAsync(dis[0].Id); status.Text = "Select a device and connect"; for (int i = 0; i < dis.Count; i++) { listOfDevices.Add(dis[i]); } DeviceListSource.Source = listOfDevices; comPortInput.IsEnabled = true; ConnectDevices.SelectedIndex = -1; try { // Disable the 'Connect' button comPortInput.IsEnabled = false; // Configure serial settings serialPort.WriteTimeout = TimeSpan.FromMilliseconds(1000); serialPort.ReadTimeout = TimeSpan.FromMilliseconds(1000); serialPort.BaudRate = 9600; serialPort.Parity = SerialParity.None; serialPort.StopBits = SerialStopBitCount.One; serialPort.DataBits = 8; serialPort.Handshake = SerialHandshake.None; // Display configured settings status.Text = "Serial port configured successfully: "; status.Text += serialPort.BaudRate + "-"; status.Text += serialPort.DataBits + "-"; status.Text += serialPort.Parity.ToString() + "-"; status.Text += serialPort.StopBits; // Set the RcvdText field to invoke the TextChanged callback // The callback launches an async Read task to wait for data rcvdText.Text = "Waiting for data..."; // Create cancellation token object to close I/O operations when closing the device ReadCancellationTokenSource = new CancellationTokenSource(); // Enable 'WRITE' button to allow sending data sendTextButton.IsEnabled = true; Listen(); } catch (Exception ex) { status.Text = ex.Message; comPortInput.IsEnabled = true; sendTextButton.IsEnabled = false; } } catch (Exception ex) { status.Text = ex.Message; } } ////// comPortInput_Click: Action to take when 'Connect' button is clicked /// - Get the selected device index and use Id to create the SerialDevice object /// - Configure default settings for the serial port /// - Create the ReadCancellationTokenSource token /// - Start listening on the serial port input /// /// /// private async void comPortInput_Click(object sender, RoutedEventArgs e) { var selection = ConnectDevices.SelectedItems; if (selection.Count <= 0) { status.Text = "Select a device and connect"; return; } DeviceInformation entry = (DeviceInformation)selection[0]; try { serialPort = await SerialDevice.FromIdAsync(entry.Id); // Disable the 'Connect' button comPortInput.IsEnabled = false; // Configure serial settings serialPort.WriteTimeout = TimeSpan.FromMilliseconds(1000); serialPort.ReadTimeout = TimeSpan.FromMilliseconds(1000); serialPort.BaudRate = 9600; serialPort.Parity = SerialParity.None; serialPort.StopBits = SerialStopBitCount.One; serialPort.DataBits = 8; serialPort.Handshake = SerialHandshake.None; // Display configured settings status.Text = "Serial port configured successfully: "; status.Text += serialPort.BaudRate + "-"; status.Text += serialPort.DataBits + "-"; status.Text += serialPort.Parity.ToString() + "-"; status.Text += serialPort.StopBits; // Set the RcvdText field to invoke the TextChanged callback // The callback launches an async Read task to wait for data rcvdText.Text = "Waiting for data..."; // Create cancellation token object to close I/O operations when closing the device ReadCancellationTokenSource = new CancellationTokenSource(); // Enable 'WRITE' button to allow sending data sendTextButton.IsEnabled = true; Listen(); } catch (Exception ex) { status.Text = ex.Message; comPortInput.IsEnabled = true; sendTextButton.IsEnabled = false; } } ////// sendTextButton_Click: Action to take when 'WRITE' button is clicked /// - Create a DataWriter object with the OutputStream of the SerialDevice /// - Create an async task that performs the write operation /// /// /// private async void sendTextButton_Click(object sender, RoutedEventArgs e) { try { if (serialPort != null) { // Create the DataWriter object and attach to OutputStream dataWriteObject = new DataWriter(serialPort.OutputStream); //Launch the WriteAsync task to perform the write await WriteAsync(); } else { status.Text = "Select a device and connect"; } } catch (Exception ex) { status.Text = "sendTextButton_Click: " + ex.Message; } finally { // Cleanup once complete if (dataWriteObject != null) { dataWriteObject.DetachStream(); dataWriteObject = null; } } } ////// WriteAsync: Task that asynchronously writes data from the input text box 'sendText' to the OutputStream /// ///private async Task WriteAsync() { Task storeAsyncTask; if (sendText.Text.Length != 0) { // Load the text from the sendText input text box to the dataWriter object dataWriteObject.WriteString(sendText.Text); // Launch an async task to complete the write operation storeAsyncTask = dataWriteObject.StoreAsync().AsTask(); UInt32 bytesWritten = await storeAsyncTask; if (bytesWritten > 0) { status.Text = sendText.Text + ", "; status.Text += "bytes written successfully!"; } sendText.Text = ""; } else { status.Text = "Enter the text you want to write and then click on 'WRITE'"; } } /// /// - Create a DataReader object /// - Create an async task to read from the SerialDevice InputStream /// /// /// private async void Listen() { try { if (serialPort != null) { dataReaderObject = new DataReader(serialPort.InputStream); // keep reading the serial input while (true) { await ReadAsync(ReadCancellationTokenSource.Token); } } } catch (Exception ex) { if (ex.GetType().Name == "TaskCanceledException") { status.Text = "Reading task was cancelled, closing device and cleaning up"; CloseDevice(); } else { status.Text = ex.Message; } } finally { // Cleanup once complete if (dataReaderObject != null) { dataReaderObject.DetachStream(); dataReaderObject = null; } } } ////// ReadAsync: Task that waits on data and reads asynchronously from the serial device InputStream /// /// ///private async Task ReadAsync(CancellationToken cancellationToken) { Task loadAsyncTask; uint ReadBufferLength = 1024; // If task cancellation was requested, comply cancellationToken.ThrowIfCancellationRequested(); // Set InputStreamOptions to complete the asynchronous read operation when one or more bytes is available dataReaderObject.InputStreamOptions = InputStreamOptions.Partial; // Create a task object to wait for data on the serialPort.InputStream loadAsyncTask = dataReaderObject.LoadAsync(ReadBufferLength).AsTask(cancellationToken); // Launch the task and wait UInt32 bytesRead = await loadAsyncTask; if (bytesRead > 0) { rcvdText.Text = dataReaderObject.ReadString(bytesRead); status.Text = "bytes read successfully!"; } } /// /// CancelReadTask: /// - Uses the ReadCancellationTokenSource to cancel read operations /// private void CancelReadTask() { if (ReadCancellationTokenSource != null) { if (!ReadCancellationTokenSource.IsCancellationRequested) { ReadCancellationTokenSource.Cancel(); } } } ////// CloseDevice: /// - Disposes SerialDevice object /// - Clears the enumerated device Id list /// private void CloseDevice() { if (serialPort != null) { serialPort.Dispose(); } serialPort = null; comPortInput.IsEnabled = true; sendTextButton.IsEnabled = false; rcvdText.Text = ""; listOfDevices.Clear(); } ////// closeDevice_Click: Action to take when 'Disconnect and Refresh List' is clicked on /// - Cancel all read operations /// - Close and dispose the SerialDevice object /// - Enumerate connected devices /// /// /// private void closeDevice_Click(object sender, RoutedEventArgs e) { try { status.Text = ""; CancelReadTask(); CloseDevice(); ListAvailablePorts(); } catch (Exception ex) { status.Text = ex.Message; } } } }
从我的代码中获取下一个块.前两行ConnectToSerialPort()
与测试前相同,但SerialDevice.FromIdAsync(dis[0].id);
总是为空.这不行!!
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using Windows.Devices.Enumeration; using Windows.Devices.SerialCommunication; using Windows.Storage.Streams; using Windows.UI.Xaml.Controls; namespace OpenLab.Kitchen.Receiver { public sealed partial class MainPage : Page { private ListBytes { get; set; } public MainPage() { this.InitializeComponent(); Bytes = new List (); ConnectToSerialPort(); } private async void ConnectToSerialPort() { var dis = await DeviceInformation.FindAllAsync(SerialDevice.GetDeviceSelectorFromUsbVidPid(0x04D8, 0x000A)); var sp = await SerialDevice.FromIdAsync(dis[0].Id); Debug.WriteLine(sp.UsbVendorId); DeviceInformationCollection serialDevices; while ((serialDevices = await DeviceInformation.FindAllAsync(SerialDevice.GetDeviceSelectorFromUsbVidPid(0x04D8, 0x000A))).Count < 1) { Debug.WriteLine("Unable to locate..."); } SerialDevice serialPort; while ((serialPort = await SerialDevice.FromIdAsync(serialDevices[0].Id)) == null) { Debug.WriteLine("Failed to open serial port..."); } serialPort.WriteTimeout = TimeSpan.FromMilliseconds(1000); serialPort.ReadTimeout = TimeSpan.FromMilliseconds(1000); serialPort.BaudRate = 9600; serialPort.Parity = SerialParity.None; serialPort.StopBits = SerialStopBitCount.One; serialPort.DataBits = 8; serialPort.Handshake = SerialHandshake.None; var dataReader = new DataReader(serialPort.InputStream); var buffer = new byte[1024]; while (true) { var bytesRead = await dataReader.LoadAsync((uint)buffer.Length); dataReader.ReadBytes(buffer); Bytes.AddRange(buffer.Take((int)bytesRead)); byte[] slipPacket; while ((slipPacket = Slip.ExtractSlipPacket(Bytes)) != null) { var waxPacket = WaxPacketConverter.FromBinary(slipPacket, DateTime.Now); if (waxPacket != null) { Debug.WriteLine(waxPacket); } } } } } }
我已经检查了所有的清单权限以匹配它们并检查引用的DLL版本之类的东西,所有内容看起来都一样.还检查了运行VS作为管理员的事情,我没有同时打开这两个应用程序所以它不是那个应该保持端口打开或任何...
有没有人有任何想法?
所以Microsoft没有提到您需要在应用程序清单中添加一些内容以进行串行通信,也不会在应用程序清单GUI中添加用于串行通信的复选框.
需要将以下内容添加到您的应用清单中(
如果该部分不存在,则创建该部分):
更新10/2016
Microsoft已更新其文档以反映此要求.
https://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.serialcommunication.aspx