첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

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
    }
}

 

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
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요