[C#/WINFORM] 멀티 원격 데스크톱 프로토콜 클라이언트(Remote Desktop Protocol Client) 사용하기
C#/WinForm 2020. 2. 10. 21:14728x90
반응형
728x170
▶ RDPInformation.cs
using AxMSTSCLib;
namespace TestProject
{
/// <summary>
/// RDP 정보
/// </summary>
public class RDPInformation
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 클라이언트 - Client
/// <summary>
/// 클라이언트
/// </summary>
public AxMsRdpClient9NotSafeForScripting Client { get; set; }
#endregion
}
}
728x90
▶ MainForm.cs
using System;
using System.Windows.Forms;
using AxMSTSCLib;
using MSTSCLib;
namespace TestProject
{
/// <summary>
/// 메인 폼
/// </summary>
public partial class MainForm : Form
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainForm()
/// <summary>
/// 생성자
/// </summary>
public MainForm()
{
InitializeComponent();
#region 이벤트를 설정한다.
FormClosing += Form_FormClosing;
this.connectButton.Click += connectButton_Click;
this.disconnectButton.Click += disconnectButton_Click;
this.tabControl.SizeChanged += tabControl_SizeChanged;
#endregion
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
//////////////////////////////////////////////////////////////////////////////// Event
#region 폼을 닫을 경우 처리하기 - Form_FormClosing(sender, e)
/// <summary>
/// 폼을 닫을 경우 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void Form_FormClosing(object sender, FormClosingEventArgs e)
{
if(this.tabControl.TabPages.Count > 0)
{
for(int i = this.tabControl.TabPages.Count - 1; i > -1; i--)
{
TabPage tabPage = this.tabControl.TabPages[i];
RDPInformation information = tabPage.Tag as RDPInformation;
information.Client.Disconnect();
}
}
}
#endregion
#region 탭 컨트롤 크기 변경시 처리하기 - tabControl_SizeChanged(sender, e)
/// <summary>
/// 탭 컨트롤 크기 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void tabControl_SizeChanged(object sender, EventArgs e)
{
if(this.tabControl.TabPages.Count > 0)
{
for(int i = this.tabControl.TabPages.Count - 1; i > -1; i--)
{
TabPage tabPage = this.tabControl.TabPages[i];
RDPInformation information = tabPage.Tag as RDPInformation;
AxMsRdpClient9NotSafeForScripting client = information.Client;
client.UpdateSessionDisplaySettings
(
(uint)client.Width,
(uint)client.Height,
(uint)client.Width,
(uint)client.Height,
0,
96,
96
);
}
}
}
#endregion
#region 클라이언트 연결중인 경우 처리하기 - client_OnConnecting(sender, e)
/// <summary>
/// 클라이언트 연결중인 경우 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void client_OnConnecting(object sender, EventArgs e)
{
AxMsRdpClient9NotSafeForScripting client = sender as AxMsRdpClient9NotSafeForScripting;
AddListBoxMessage("{0}/{1} : 연결중입니다...", client.Server, client.UserName);
}
#endregion
#region 클라이언트 연결시 처리하기 - client_OnConnected(sender, e)
/// <summary>
/// 클라이언트 연결시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void client_OnConnected(object sender, EventArgs e)
{
AxMsRdpClient9NotSafeForScripting client = sender as AxMsRdpClient9NotSafeForScripting;
AddListBoxMessage("{0}/{1} : 연결되었습니다.", client.Server, client.UserName);
}
#endregion
#region 클라이언트 로그온 에러시 처리하기 - client_OnLogonError(sender, e)
/// <summary>
/// 클라이언트 로그온 에러시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void client_OnLogonError(object sender, IMsTscAxEvents_OnLogonErrorEvent e)
{
AxMsRdpClient9NotSafeForScripting client = sender as AxMsRdpClient9NotSafeForScripting;
if(e.lError == 0)
{
AddListBoxMessage("{0}/{1} : 로그온시 인증 에러가 발생했습니다.", client.Server, client.UserName);
}
else
{
AddListBoxMessage("{0}/{1} : 로그온시 에러가 발생했습니다.", client.Server, client.UserName);
}
RemoveClient(client);
}
#endregion
#region 클라이언트 로그인 완료시 처리하기 - client_OnLoginComplete(sender, e)
/// <summary>
/// 클라이언트 로그인 완료시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void client_OnLoginComplete(object sender, EventArgs e)
{
AxMsRdpClient9NotSafeForScripting client = sender as AxMsRdpClient9NotSafeForScripting;
AddListBoxMessage("{0}/{1} : 로그온을 성공했습니다.", client.Server, client.UserName);
}
#endregion
#region 클라이언트 연결 중단시 처리하기 - client_OnDisconnected(sender, e)
/// <summary>
/// 클라이언트 연결 중단시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void client_OnDisconnected(object sender, IMsTscAxEvents_OnDisconnectedEvent e)
{
AxMsRdpClient9NotSafeForScripting client = sender as AxMsRdpClient9NotSafeForScripting;
AddListBoxMessage("{0}/{1} : 연결이 중단되었습니다.", client.Server, client.UserName);
RemoveClient(client);
}
#endregion
#region 클라이언트 치명적 에러 발생시 처리하기 - client_OnFatalError(sender, e)
/// <summary>
/// 클라이언트 치명적 에러 발생시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void client_OnFatalError(object sender, IMsTscAxEvents_OnFatalErrorEvent e)
{
AxMsRdpClient9NotSafeForScripting client = sender as AxMsRdpClient9NotSafeForScripting;
AddListBoxMessage("{0}/{1} : 치명적 에러가 발생했습니다.", client.Server, client.UserName);
RemoveClient(client);
}
#endregion
#region 연결 버튼 클릭시 처리하기 - connectButton_Click(sender, e)
/// <summary>
/// 연결 버튼 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void connectButton_Click(object sender, EventArgs e)
{
#region 서버를 설정한다.
string server = this.serverTextBox.Text.Trim();
if(string.IsNullOrEmpty(server))
{
MessageBox.Show("서버 항목을 입력해 주시기 바랍니다.");
return;
}
#endregion
#region 포트를 설정한다.
string portString = this.portTextBox.Text.Trim();
int port;
if(!int.TryParse(portString, out port))
{
MessageBox.Show("포트 항목을 입력해 주시기 바랍니다.");
return;
}
#endregion
#region 도메인을 설정한다.
string domain = this.domainTextBox.Text.Trim();
#endregion
#region 사용자 ID를 설정한다.
string userID = this.userIDTextBox.Text.Trim();
if(string.IsNullOrEmpty(userID))
{
MessageBox.Show("사용자 ID 항목을 입력해 주시기 바랍니다.");
return;
}
#endregion
#region 패스워드를 설정한다.
string password = this.passwordTextBox.Text.Trim();
if(string.IsNullOrEmpty(password))
{
MessageBox.Show("패스워드 항목을 입력해 주시기 바랍니다.");
return;
}
#endregion
#region 클라이언트를 설정한다.
AxMsRdpClient9NotSafeForScripting client = new AxMsRdpClient9NotSafeForScripting();
client.Dock = DockStyle.Fill;
#endregion
#region RDP 정보를 설정한다.
RDPInformation information = new RDPInformation();
information.Client = client;
#endregion
#region 탭 페이지를 설정한다.
TabPage tabPage = new TabPage();
tabPage.Padding = new Padding(5, 5, 5, 5);
tabPage.Text = $"{server}:{userID}";
tabPage.Tag = information;
tabPage.Controls.Add(client);
#endregion
this.tabControl.TabPages.Add(tabPage);
this.tabControl.SelectedTab = tabPage;
client.OnConnecting += client_OnConnecting;
client.OnConnected += client_OnConnected;
client.OnLogonError += client_OnLogonError;
client.OnLoginComplete += client_OnLoginComplete;
client.OnDisconnected += client_OnDisconnected;
client.OnFatalError += client_OnFatalError;
client.Server = server;
client.AdvancedSettings9.RDPPort = port;
client.Domain = domain;
client.UserName = userID;
client.AdvancedSettings9.ClearTextPassword = password;
client.AdvancedSettings9.EnableCredSspSupport = true;
client.AdvancedSettings2.SmartSizing = true;
IMsRdpClientNonScriptable4 ocx = client.GetOcx() as IMsRdpClientNonScriptable4;
ocx.AllowCredentialSaving = false;
ocx.PromptForCredentials = false;
ocx.PromptForCredsOnClient = false;
client.DesktopWidth = 0;
client.DesktopHeight = 0;
client.Connect();
}
#endregion
#region 연결 중단 버튼 클릭시 처리하기 - disconnectButton_Click(sender, e)
/// <summary>
/// 연결 중단 버튼 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void disconnectButton_Click(object sender, EventArgs e)
{
if(this.tabControl.TabPages.Count == 0)
{
return;
}
TabPage tabPage = this.tabControl.SelectedTab;
RDPInformation information = tabPage.Tag as RDPInformation;
if(information.Client.Connected == 1)
{
information.Client.Disconnect();
RemoveClient(information.Client);
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Function
#region 리스트 박스 메시지 추가하기 - AddListBoxMessage(format, parameterArray)
/// <summary>
/// 리스트 박스 메시지 추가하기
/// </summary>
/// <param name="format">포맷 문자열</param>
/// <param name="parameterArray">매개 변수 배열</param>
private void AddListBoxMessage(string format, params object[] parameterArray)
{
string temporaryMessage;
if(parameterArray.Length == 0)
{
temporaryMessage = format;
}
else
{
temporaryMessage = string.Format(format, parameterArray);
}
string message = string.Format("[{0}] {1}", DateTime.Now.ToString("HH:mm:ss"), temporaryMessage);
this.messageListBox.Items.Insert(0, message);
}
#endregion
#region 탭 페이지 구하기 - GetTabPage(client)
/// <summary>
/// 탭 페이지 구하기
/// </summary>
/// <param name="client">클라이언트</param>
/// <returns>탭 페이지</returns>
private TabPage GetTabPage(AxMsRdpClient9NotSafeForScripting client)
{
foreach(TabPage tabPage in this.tabControl.TabPages)
{
RDPInformation information = tabPage.Tag as RDPInformation;
if(client == information.Client)
{
return tabPage;
}
}
return null;
}
#endregion
#region 클라이언트 제거하기 - RemoveClient(client)
/// <summary>
/// 클라이언트 제거하기
/// </summary>
/// <param name="client">클라이언트</param>
private void RemoveClient(AxMsRdpClient9NotSafeForScripting client)
{
client.OnConnecting -= client_OnConnecting;
client.OnConnected -= client_OnConnected;
client.OnLogonError -= client_OnLogonError;
client.OnLoginComplete -= client_OnLoginComplete;
client.OnDisconnected -= client_OnDisconnected;
client.OnFatalError -= client_OnFatalError;
TabPage tabPage = GetTabPage(client);
client.Dispose();
if(tabPage != null)
{
this.tabControl.TabPages.Remove(tabPage);
}
}
#endregion
}
}
※ Microsoft Windows 10 Version 1903에서 테스트했다.
300x250
※ COM 참조 설정법
1. [도구 상자 항목 선택] 대화 상자에서 [Microsoft RDP Client Control - version 10] 항목을 아래와 같이 선택한다.
2. [도구 상자]에서 [Microsoft RDP Client Control - version 10] 항목을 폼에 드래하면 아래와 같은 COM 참조가 추가된다.
- AxMSTSCLib
- MSTSCLib
728x90
반응형
그리드형(광고전용)
'C# > WinForm' 카테고리의 다른 글
[C#/WINFORM] PrinterSettings 클래스 : InstalledPrinters 정적 속성을 사용해 프린터 존재 여부 구하기 (0) | 2020.02.29 |
---|---|
[C#/WINFORM] Application 클래스 : OpenForms 정적 속성을 사용해 폼 오픈 여부 구하기 (0) | 2020.02.29 |
[C#/WINFORM] ColorTranslator 클래스 : FromHtml 정적 메소드를 사용해 16진수 색상 코드에서 색상 구하기 (0) | 2020.02.28 |
[C#/WINFORM] 크로미엄 브라우저 사용하기 (0) | 2020.02.28 |
[C#/WINFORM] Form 클래스 : CreateParams 속성을 사용해 포커스 설정 방지하기 (0) | 2020.02.12 |
[C#/WINFORM] GIF 에디터 사용하기 (0) | 2020.01.28 |
[C#/WINFORM] Control 클래스 : MousePosition 정적 속성을 사용해 마우스 위치 색상 구하기 (0) | 2020.01.26 |
[C#/WINFORM] Cursor 클래스 : Clip 정적 속성을 사용해 마우스 이동 영역 제한하기 (0) | 2020.01.13 |
[C#/WINFORM] GroupBox 클래스 : 익스팬더(Expander) 그룹 박스 사용하기 (0) | 2020.01.10 |
[C#/WINFORM] ScrollableControl 클래스 : 접을 수 있는 패널 사용하기 (0) | 2020.01.05 |
댓글을 달아 주세요