첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
유용한 소스 코드가 있으면 icodebroker@naver.com으로 보내주시면 감사합니다.
블로그 자료는 자유롭게 사용하세요.

■ 멀티 원격 데스크톱 프로토콜 클라이언트(Remote Desktop Protocol Client) 사용하기

------------------------------------------------------------------------------------------------------------------------


TestProject.zip


RDPInformation.cs

 

 

using AxMSTSCLib;

 

namespace TestProject

{

    /// <summary>

    /// RDP 정보

    /// </summary>

    public class RDPInformation

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 클라이언트 - Client

 

        /// <summary>

        /// 클라이언트

        /// </summary>

        public AxMsRdpClient9NotSafeForScripting Client { get; set; }

 

        #endregion

    }

}

 

 

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에서 테스트했다.

 

COM 참조 설정법

 

1. [도구 상자 항목 선택] 대화 상자에서 [Microsoft RDP Client Control - version 10] 항목을 아래와 같이 선택한다.

 

 

2. [도구 상자]에서 [Microsoft RDP Client Control - version 10] 항목을 폼에 드래하면 아래와 같은 COM 참조가 추가된다.

 

  • AxMSTSCLib
  • MSTSCLib

 

Posted by 사용자 icodebroker

댓글을 달아 주세요