2010-07-23 4 views
3

내 C# 응용 프로그램에서 직렬 포트를 통해 가능한 많은 제어 기능을 사용할 수있는 방법을 찾고 있습니다. 문제는 제어 할 수 있도록 작성된 오래된 C++ 프로그램을 제외하고는 문서가없는 장치와 통신해야한다는 것입니다. SerialPort 클래스를 사용하여 장치와 통신하려고 시도했지만 그 동작이 매우 이상합니다 (일부 명령을 반복해야하고 일부 다른 명령은 전혀 작동하지 않습니다). 저 관리되지 않는 프로그램의 동작을 복사하고 싶습니다만, 예를 들어 DCB와 같은 저수준 함수와 구조에 대한 액세스를 제공하지 않으므로 serialport 클래스에서는 불가능한 것처럼 보입니다.직렬 포트 WIN32 통신 API에 대한 C#/.NET 래퍼

.net에서 사용할 수있는 직렬 통신을위한 저수준 래퍼가 있습니까? 어쩌면 내가 런타임에 serialport innacessible 회원 조작 리플렉션을 사용할 수 있습니까?

+1

'SerialPort' 클래스의 모든 속성을 확인 했습니까? 매핑되지 않은 것은 거의 없습니다. –

답변

3

SerialPort 클래스의는 Win32에서 시리얼 포트 API 주위에 매우 얇은 래퍼가 다른 래퍼가 당신의 인생을 개선 할 수있는 방법을보고, 어려운 : 여기

내가 RTS_CONTROL_TOGGLE에 액세스 할 반사를 사용하는 예입니다. .NET 1.x에서 사용할 수있는 래퍼가 있으며 직렬 포트를 지원하지 않습니다. 다음은 MSDN magazine입니다.

하지만 같은 문제가 발생할 가능성이 있습니다. 서면 명령을 잃어 버릴 수있는 한 가지 방법은 RTS 신호가 꺼져있을 때 장치가받은 바이트를 버리거나 잃어 버리는 것입니다. Handshake 속성을 RequestToSend로 설정하여이를 수정합니다.

명령을 읽는 것이 잘못 될 수있는 한 가지 방법은 Read() 호출을 잘못 처리하는 것입니다. 수신 버퍼에서 사용할 수있는 바이트 수만큼의 임의의 바이트를 반환합니다. 반환 값에주의를 기울여 실제로 읽은 바이트 수를 알려줍니다. 단 하나의 보증은 적어도 1 일 것이며 카운트 이상이어야합니다.

SysInternals의 PortMon utility은 통신 문제를 해결하는 데 도움이 될 수 있으며 장치 드라이버가 보는 내용을 그대로 볼 수 있습니다. 하이퍼 터미널 또는 다른 잘 알려진 프로그램과 비교하십시오.

+0

PortMon 참조는 매우 유용했습니다. 감사합니다. – Kris

+3

전혀 * 얇지는 않습니다. 'SerialStream' 레이어를 도입했으며,이 레이어는 오버랩 된 (fail-asynchronous) winapi 메소드를 사용합니다. 'SerialPort'에는 너무 많은 문제가 있습니다. 실제 쓰레기 래퍼를 찾으려고합니다.'DataReceived' 이벤트는 포트 클로즈 (port closing)의 예외이며, USB- 시리얼 어댑터가 'ObjectDisposedException' (허)입니다. 연결이 끊어진 상태 등이 있습니다. – Sinatr

+0

흠, ODE가 마음에 들지 않으면 포트가 열려있는 동안 커넥터를 잠그지 마십시오. 그렇게 할 필요가 전혀 없습니다. USB 에뮬레이터를 사용할 때 "안전 제거 하드웨어"트레이 아이콘을 사용하면 ** 옵션이 아닙니다 ** 직렬 포트는 재생 및 재생 장치가 아닙니다. –

0

이전 C++ 코드를 관리되는 C++ 클래스로 복사 할 수 있습니다. 그러면이 코드를 C# 코드의 일반 .NET 클래스처럼 사용할 수 있습니다. 이것은 귀하의 목표를 달성하는 가장 빠른 방법 일 수 있습니다.

5

.NET SerialPort 클래스를 제안하는 사람들에게; 시리얼 관련 문제에 자주 스택 오버플로 대답 공급자, 벤 보이트는 WinAPI를 래퍼 결국 프레임 워크를 제공하여 SerialPort를 사용하는 것보다 훨씬 더 좋은 생각으로 판명 이유에서 눈부신 통찰력을 제공합니다

Ben Voigt on .NET SerialPort

읽어야합니다.

그는 또한 향후 블로그 게시물에서 밝힐 수있는 WinAPI 래퍼를 말합니다. 그렇게되면 원래의 질문에 답을 얻을 수 있습니다.

또한 요청한 기능을 제공하는 상업용 솔루션이 하나 이상있는 것 같습니다. here.

또 다른 편집 :

일부는 더 .NET에서 더하여 SerialPort 클래스는 없었다 시점에서 분명히 this blog post 나왔고 온라인 검색 ... 소스 코드는 목적으로는 Win32 API를 래핑하는 방법을 보여주는 제공됩니다.

편집은

일부 사용자는 위에서 언급 한 MSDN 블로그 게시물 링크가 죽었다는 것을 지적했다. 링크 된 문서의

제목이었다 :

"Use P/Invoke to Develop a .NET Base Class Library for Serial Device Communications", 그것을 참조하는 다른 MSDN 문서에서 존 하인드 andpublished 2002년 10월 내가 말할 수있는 쓴 :

enter image description here

불행하게도, Microsoft는 2003 년까지 잡지 버전을 제공하는 것 같습니다 :

https://msdn.microsoft.com/en-us/magazine/msdn-magazine-issues.aspx

FWIW, 다른 곳에서 half working online version을 찾았습니다 ...

+0

나는 이상한 투표를하지 않겠지 만 의견을 보내주십시오. – Kris

+1

MSDN 블로그 게시물에 대한 링크가 깨졌습니다. 가능하다면 링크가 다시 끊어지기 때문에 기사 제목도 포함하십시오. – AaA

+1

내가 찾아 볼게! – Kris

2

PInvoke를 통한 직렬 포트 작업이 정상적으로 작동합니다. 우리는 Silverlight 응용 프로그램에서이 작업을 수행하지만 일반 .NET 응용 프로그램에서도 동일하게 작동합니다. Serial Communication with Silverlight 5 (COM port)에 대한 답은 사용자의 요구에 쉽게 적용될 수있는 기본 래퍼를 제공합니다. 일반적인 WinAPI 방법을 사용하므로 C++ 응용 프로그램과 마찬가지로 모든 직렬 포트 기능에 대한 완전한 액세스 권한을 얻을 수 있습니다.

P. 아직 수행하지 않은 경우 PortMon을 사용하여 회선의 상황을 모니터링하십시오.

+0

다른 답변에 감사드립니다.게시 된 코드는 매우 유용합니다. 부분은 참으로 32 비트 Win7에서 좋은 도구입니다. 내 경험은 x64에서 작동하지 않는다는 것입니다 (http://stackoverflow.com/questions/1356470/sysinternals-portmon-error-2). 관리자로 실행하고 WinXP SP2/3 호환성을 설정해도 도움이되지 않았습니다. 동정, 그 좋은 도구 때문입니다. – Kris

+0

당신이 참조한 솔루션을 사용하여 결국 그들은 내 목적에 잘 어울립니다. 감사. – Kris