如何在 C# 中制作串口挂钩






3.20/5 (6投票s)
一篇关于在 C# 中创建串口挂钩的文章

引言
这个 C# 控制台程序演示了如何在 C# 中使用串口钩子,某种程度上是这样。这是因为与 Windows 消息、键盘和鼠标等不同,实际上没有现成的 API 提供串口钩子,您可以使用 SetWindowsHookEx
API 来实现这些功能。
背景
所以你打开了你最喜欢的互联网浏览器,打开了你最喜欢的搜索引擎,并输入“如何在 C# 中创建串口钩子?”。
然后你的搜索引擎开始搜索浩瀚的 WWW。瞧!
除非我错了,或者我没有在互联网上搜索足够长的时间来挖掘一个,否则你的搜索结果可能不是你所期望的。
所以这里有一个 C# 控制台程序,至少说明了这个概念,在一个非常简单的示例中。首先,我们创建一个 WIN32 串口库(请参阅文档 WIN32 Serial Module.chm ),它提供串口钩子接口。该串口库利用重叠选项提供异步 I/O,从而使钩子成为可能。然后我们在 C# 中导入串口库方法。就完成了。
使用代码
如果您有兴趣使用硬件流控制,那么这篇文章不适合您,因为串口库在此示例中不提供此功能。但是,只要您有耐心并进行一些小的修改,就可以扩展现有的库来完成这项工作。
所以这是一个提供从终端到应用程序层的透明数据传输的示例,反之亦然。但这并不会阻止您实现自己的消息传递协议(例如,最简单的 STX + <Data> + STX + LRC)。
就像任何其他非静态类一样,您只需要创建类 CommsSerial
的一个实例,就可以在您的程序中使用它,如下所示
请注意,此控制台程序需要将串口号作为程序参数传递。
namespace UsingWIN32SerialHooksInCSharp
{
class SerialProgram
{
private CommsSerial comSerial;
private void SerialSimulation(ushort port)
{
try
{
comSerial = new CommsSerial();
comSerial.SerialReceptionEvent +=
delegate(object obj, ComEventArgs comEventArgs)
{
Console.WriteLine("\n---Data available notification----");
Console.WriteLine("{0} byte(s) successfully read.",
comEventArgs.Length);
Console.WriteLine("Data: {0}", comEventArgs.ToString());
//
// Write data to serial.
// In real applications, this could be the response after analyzing
// the received data.
//
byte[] dataToWrite = new byte[] { 0x02, (byte)'T',
(byte)'E', (byte)'S', (byte)'T', 0x03 };
Console.WriteLine("\nWriting {0} byte(s) of data. \nData: {1}",
dataToWrite.Length,
Conversion.BytesToAsciiHex
(dataToWrite,dataToWrite.Length)
);
//write data
comSerial.Write(dataToWrite, (uint)dataToWrite.Length );
};
comSerial.SerialTransmitEvent +=
delegate(object obj, ComEventArgs comEventArgs)
{
Console.WriteLine("\n---Write finished notification----");
Console.WriteLine("{0} byte(s) successfully written.",
comEventArgs.Length);
};
try
{
Console.Write("\nOpening serial COM port...");
//Open the serial port
comSerial.Open(port,
CommsSerial.DataSize.EIGHT_BITS,
CommsSerial.ParityBit.NOPARITY,
CommsSerial.StopBit.ONESTOPBIT,
CommsSerial.BaudRate.CBR_115200
);
Console.WriteLine("OK!");
Console.Write("\nInstalling hooks...");
//Install the hooks
comSerial.InstallHooks();
Console.WriteLine("OK!");
do
{
Console.WriteLine("\nSerial monitor listening...\n");
//
// Do something
//
// i.e. maybe until stop button is pressed.
//
//Simulate active to inactivated state
//Active until 25 seconds timeout expires.
Thread.Sleep(20000);
Console.WriteLine("Closing serial monitor...");
} while (false);
//Uninstall hooks
comSerial.UninstallHooks();
//
comSerial.Close();
Console.WriteLine("Monitor closed.");
}
catch (SerialManagedException)
{
//Re-throw exceptions
throw;
}
catch (Exception)
{
//Re-throw exceptions
throw;
}
}
catch (SerialManagedException ex)
{
Console.WriteLine("A serial exception occurred.");
Console.WriteLine(ex.Message);
}
catch (ArgumentException ex)
{
Console.WriteLine("An argument exception occurred.");
Console.WriteLine(ex.Message);
}
catch(Exception ex)
{
Console.WriteLine("Unknown exception occurred.");
Console.WriteLine(ex.Message);
}
}
static void Main(string[] args)
{
ushort port;
if (args.Length==0)
{
Console.WriteLine("\nError: No program argument provided!");
Console.WriteLine("\nUsage: {0} [serial port]",
Path.GetFileName
(Process.GetCurrentProcess().MainModule.FileName)
);
Console.WriteLine("\n");
Console.ReadKey();
return;
}
port = Convert.ToUInt16(args[0]);
if ( port == 0 || port > 15)
{
//Default port
port = 1;
}
SerialProgram serialProgram = new SerialProgram();
//Perform serial simulation
serialProgram.SerialSimulation(port);
//Simulation has ended.
Console.WriteLine("\nSimulation finished.");
Console.WriteLine("<press>");
Console.ReadKey();
}
}
}
历史
- 初始代码版本 1.0