반응형

안녕하세요

 

코딩하는남자 코딩연습생입니다

 

이번에 할려고 하는것은 Winform에서 폼내의 모든 컨트롤의 이름을 가져올려고 합니다

 

보통 컨트롤 이름 가져오기 할께 사용하는 코드로는

 

Control GetControlByName(string Name)
{
    foreach (Control c in this.Controls)
        if (c.Name == Name)
            return c;

    return null;
}

이런식으로 구현을 하는데 이렇게 하게 되면

 

컨테이너컨트롤에 한해서 한 컨터이너컨트롤 내부의 컨트롤들만 불러오게 되더라구요

 

여기서 컨테이너컨트롤이라는건 Panle, groupbox, TableLayoutPanel, 등을 말하는것으로써

 

컨트롤을 감싸는 컨트롤을 칭하는것입니다

 

컨테이너 컨트롤을 포함한 모든 컨트롤을 불러오는 방법을 설명할 것입니다

 

클래스 파일을 생성합니다

 

 

[Source Code]

         public static Control[] GetAllControlsUsingRecursive(Control containerControl)
        {
            List<Control> allControls = new List<Control>();

            foreach (Control control in containerControl.Controls)
            {
                allControls.Add(control);

                if (control.Controls.Count > 0)
                {
                    allControls.AddRange(GetAllControlsUsingRecursive(control));
                }
            }

            return allControls.ToArray();
        }

 

이렇게 클래스 구문을 작성해주고

 

본문에서 다음과 같이 호출하여 리턴 받을 수 있습니다

 

[Source Code]

            Control[] controls = MyApp.GetAllControlsUsingRecursive(this);

            foreach (Control control in controls)
            {
                if (control.Name != "")
                {
                    if (control.Name.Substring(0, 3) == "lbl" || control.Name.Substring(0, 3) == "cmd")
                    {
                        control.Text = appResourceMgr.GetString(control.Name);
                    }
                }
            }

 

저의 경우네는 레이블과 버튼의 정보만 가져오고 싶어서

 

레이블의 명칭의 시작을 lbl로 구성하고 버튼의 시작 명칭을 cmd로 구성하였기에

 

IF문을 통해 해달 컨트롤을 걸러냈습니다

 

이렇게 하면 본문의 호출할려는 폼의 모든 컨트롤을 GetAllControlsUsingRecursive로 리턴해주고

 

GetAllControlsUsingRecursive에서는 재귀호출을 사용하여 컨테이너컨트롤 내부의 컨트롤 까지 검색하여

 

리턴해주게 됩니다

 

컨트롤 검색이나 명칭변경 또는 컨트롤 제어를 위해 고민중이시라면

 

다음과 같은 구문을 사용하여 검색하게 되면 좋을거 같습니다

 

감사합니다

반응형
반응형

안녕하세요

 

코딩하는 남자 "코딩연습생"입니다

 

저번 시간에 윈도우 핸들러를 통해 카카오톡PC 버전에서 메세지 보내기를 게시했는데요

 

이번에는 텔레그램 API를 통해 C#에서 메세지를 보내는 방법을 구현해 볼려고 합니다

 

요즘은 모둔 매신져들이 PC와 연계를 많이 하고 있는 추세이고 코딩에 대한 API도 많이 제공되고 있어서

 

무한한 가능성이 생겨나고 있는거 같습니다

 

다시 본론으로 돌아와서 텔레그램을 C#으로 불러오기 위해서는 몇가지 설정이 입니다

 

[사전 준비 사항]

 

1. 텔레그램 가입하기

2. Bot을 통한 나만의 Bot을 생성한다

3. API Key를 부여 받는다

 

이렇게 3가지를 사전 준비해야 합니다 방법은 아주 간단합니다

 

텔레그램을 가입하기 위해 텔레그램 싸이트 접속

: https://web.telegram.org

 

Telegram Web

Welcome to the Web application of Telegram messenger. See https://github.com/zhukov/webogram for more info.

web.telegram.org

 

위 링크로 접속하셔서 가입 or 로그인을 해줍니다

 

 

로그인 뒤에 옆 친구리시트 중에 다음과 같은 BotFather를 클릭해 줍니다

 

번역하면 봇아버지ㅋㅋ

 

그다음 봇 아버지에게 다음과 같이 말을 겁니다

 

 

/start 텔레그램을 시작하겠다는 말을 봇아버지에게 하는거죠

 

 

그다음 봇아버지에게 /newBot이라고 말은 걸면 아버지가 물어볼꺼에요 봇이름은 무엇으로 할거니?

 

라고..

 

거기에 Bot 이름을 입력해주시면 되는데

 

이름_Bot 이름 뒤에 꼭 _Bot이라고 붙여 주셔야 합니다

 

그렇게 Bot이 생성이 되면 HTTP API 라는 키를 알려줍니다

 

여기까지 되셧으면 사전 준비는 완료

 

다음은 비쥬얼 스튜디오로 가서 프로젝트를 하나 생성해 줍니다

 

그 다음 Nuget을 통해 TelegramBot을 참조 추가 해줍니다

 

 

저는 이미 설치가 되어 있으서 업데이트라고 나오는데

 

여러분은 아마 설치라고 나오실겁니다

 

 

설치하게 되면 Telegram.Bot이라는 참조가 생성이 됩니다

 

그다음 텔레그램을 제어하기 위한 Class를 생성할겁니다

 

저는 src라는 폴더 아래 TelegramBot.cs라는 파일을 생성했습니다

 

[SourceCode]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Cache;
using System.IO;

 

프로젝트 using 선언문을 선언해주고

 

    public class TelegramBot
    {
        private static readonly string _baseUrl = "https://api.telegram.org/bot";
        private static readonly string _token = "879350682:AAEgVohD-XAq6g_Fq4vEHecuiiqLCnZ6CEU";
        public static string _chatId = string.Empty;

        /// <summary>
        /// 텔레그램봇에게 메시지를 보냅니다.
        /// </summary>
        /// <param name="text">보낼 메시지</param>
        /// <param name="errorMessage">오류 메시지</param>
        /// <returns>결과</returns>
        public static bool SendMessage(string text, out string errorMessage)
        {
            return SendMessage(_chatId, text, out errorMessage);
        }

        /// <summary>
        /// 텔레그램봇에게 메시지를 보냅니다.
        /// </summary>
        /// <param name="chatId">chat id</param>
        /// <param name="text">보낼 메시지</param>
        /// <param name="errorMessage">오류 메시지</param>
        /// <returns>결과</returns>
        public static bool SendMessage(string chatId, string text, out string errorMessage)
        {
            string url = string.Format("{0}{1}/sendMessage", _baseUrl, _token);

            HttpWebRequest req = WebRequest.Create(new Uri(url)) as HttpWebRequest;
            req.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
            req.Timeout = 30 * 1000;
            req.Method = "POST";
            req.ContentType = "application/json";

            string json = String.Format("{{\"chat_id\":\"{0}\", \"text\":\"{1}\"}}", chatId, EncodeJsonChars(text));
            byte[] data = UTF8Encoding.UTF8.GetBytes(json);
            req.ContentLength = data.Length;
            using (Stream stream = req.GetRequestStream())
            {
                stream.Write(data, 0, data.Length);
                stream.Flush();
            }

            HttpWebResponse httpResponse = null;
            try
            {
                httpResponse = req.GetResponse() as HttpWebResponse;
                if (httpResponse.StatusCode == HttpStatusCode.OK)
                {
                    string responseData = null;
                    using (Stream responseStream = httpResponse.GetResponseStream())
                    {
                        using (StreamReader reader = new StreamReader(responseStream, UTF8Encoding.UTF8))
                        {
                            responseData = reader.ReadToEnd();
                        }
                    }

                    if (0 < responseData.IndexOf("\"ok\":true"))
                    {
                        errorMessage = String.Empty;
                        return true;
                    }
                    else
                    {
                        errorMessage = String.Format("결과 json 파싱 오류 ({0})", responseData);
                        return false;
                    }
                }
                else
                {
                    errorMessage = String.Format("Http status: {0}", httpResponse.StatusCode);
                    return false;
                }
            }
            catch (Exception ex)
            {
                errorMessage = ex.Message;
                return false;
            }
            finally
            {
                if (httpResponse != null)
                    httpResponse.Close();
            }
        }

        private static string EncodeJsonChars(string text)
        {
            return text.Replace("\b", "\\\b")
                .Replace("\f", "\\\f")
                .Replace("\n", "\\\n")
                .Replace("\r", "\\\r")
                .Replace("\t", "\\\t")
                .Replace("\"", "\\\"")
                .Replace("\\", "\\\\");
        }
    }

이렇게 Class 파일을 하나생성해 줍니다

 

그 다음 메인폼으로 이동한뒤에

 

using Telegram.Bot;
using Telegram.Bot.Types;
using Telegram.Bot.Types.Enums;
using Telegram.Bot.Types.ReplyMarkups;

 

Telegram.Bot을 화면에 삽입 시켜 줍니다

 

private void Telegram_Send()
        {
            string text = Messge;
            string errorMessage = null;
            bool ret = TelegramBot.SendMessage(text, out errorMessage);


            switch (TelegramBot._chatId)
            {
                case "chatId1":
                    Who = "사용자1";
                    break;
                case "chatId2":
                    Who = "사용자2";
                    break;
                case "chatId3":
                    Who = "사용자3";
                    break;
                case "chatId4":
                    Who = "사용자4";
                    break;
                case "chatId5":
                    Who = "사용자5";
                    break;
            }

            //Log 기록.
            TelegramBot._chatId = "chatId_Bot";
            text = "[" + Who + "] 전송시간 : " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            bool ret2 = TelegramBot.SendMessage(text, out errorMessage);

        }

 

이렇게 하면 전송하게 됩니다

 

여기서 chatId라는게 나오는데요

 

상대방의 고유 계정 ID라고 보시면 될거 같은데요 나의 ID를 보는 방법은 다음과 같습니다

 

친구 검색하기에서 "get id"라고 검색을 하면 아래 그림과 같은 Bot이 나오는데 추가해줍니다

 

 

추가하게 되면 친구 리스트에 다음과 같이 나오게 되겟죠?

 

대화창으로 이동한뒤 /start라고 쳐주면 

 

Your Chat ID = "xxxxxxxxx"라고 알려줍니다

 

저 코드가 chatId가 되는겁니다

 

그리고 단체그룹방에 메세지를 보고 싶을 경우에는

 

해당 그룹방에 나의 Bot을 추가한뒤에 

 

인터넷 주소창에

 

https://api.telegram.org/bot"API 토큰값"/getUpdates

 

이렇게 입력을 하게 되면

 

빨간색 테두리안에 해당 대화방의 Chatid가 나오게 됩니다

 

반응형
반응형

안녕하세요

 

코딩하는남자 코딩 연습생입니다!

 

이번에 게시할 주제는 카카오PC 버전을 이용해서

 

현재 활성화된 대화창을 찾아 자동으로 메세지를 보내는 방법을 구현해 봤습니다

 

응용 부분은 사내 알림, 시스템 관리자 알림, 등 카카오톡을 활용해서 시스템 알림 기능을 만들기 위해 시도해 봤는데요

 

결론은 실패 입니다ㅎㅎ

 

카카오 챗봇에서 연속 메세지가 다중 발생하면 계정에 Block을 걸어 계정을 사용하지 못하게 정책이 잡혀 있더라구요

 

아마 악성 이용을 방지 하지 위함인거 같습니다

 

그래도 응용하면 나중에 다른 다른 어플리케이션을 제어할수도 있기에

 

방법을 공유해볼께요

 

 

 

 

[Source Code]

using System.Runtime.InteropServices;

 

윈도우에 실행 중인 창에 대한 핸들러를 사용하기 위한 DllImport 함수를 사용하기 위한 선언문

 

        [DllImport("user32.dll")]
        public static extern int FindWindow(string lpClassName, string lpWindowName);
        //FindWindow (최상위 창 핸들값 가져오는 API)

        [DllImport("user32.dll")]
        public static extern int FindWindowEx(int hWnd1, int hWnd2, string lpsz1, string lpsz2);
        //FindWindowEX (인자로 받아온 핸들의 자식의 핸들값 가져오는 API)

        [DllImport("user32.dll")]
        public static extern int SendMessage(int hwnd, int wMsg, int wParam, string lParam);
        //SendMessage

        [DllImport("user32.dll")]
        public static extern uint PostMessage(int hwnd, int wMsg, int wParam, int lParam);
        
        //윈도우를 포커스를 지정하여 최상위로 오도록 한다
        [DllImport("user32.dll")]
        private static extern bool SetForegroundWindow(int hWnd);

        //최소화된 윈도우를 활성화 시킴
        [DllImport("user32.dll")]
        private static extern bool ShowWindowAsync(int hWnd, int nCmdShow);

 

DllImport를 사용해 다음과 같이 핸들러 추가

 

        // user create.
        string Title = string.Empty;
        string massage = string.Empty;

        const int WM_KEYDOWN = 0x100;
        const int WM_KEYUP = 0x101;
        const Int32 VK_RETURN = 0x0D;
        const int VK_ENTER = 0x0D;

 

제목과 보낼 메세지를 담을 변수와 키보드 코드를 이미 지정합니다

 

        public void sendKatalk(string title, string msg)
        {
            int hd01 = FindWindow(null, title);
            int hd03 = FindWindowEx(hd01, 0, "RichEdit20W", "");

            //ShowWindowAsync(hd01, 1);
            SetForegroundWindow(hd01);

            //maessage send.
            SendMessage(hd03, 0x000c, 0, msg);

            //sleep Time 3sec.
            Thread.Sleep(3000);

            PostMessage(hd03, 0x0100, 0xD, 0x1C001);

            //sleep Time 3sec.
            Thread.Sleep(3000);
        }

 

FindWindow를 통해 title의 이름을 가진 활성화 창을 찾습니다

 

그 다음 SetForegroundWindow를 통해 title이름을 가진 창을 최상위로 활성화 시킵니다

 

그 뒤에 SendMessage를 이용해서 hd03에서 RichEdit20W 부분 위치에 msg라는 값을 넣어줍니다

 

마지막으로 PostMessage를 통해 RichEdit20W에 엔터 명령어를 보내주면 메세지 보내기 성공!!

 

저는 Theread를 사용해서 사용자이름을 불러와 자동으로 대화창을 활성화 시키고 그 활성화 된

 

대화창에 메세지를 생성하여 보내도록 구현햇습니다

 

궁금하신 내용은 댓글을 통해 문의 주시면 아는 범위에서 답변 드리도록 하겠습니다

 

감사합니다

반응형
반응형

안녕하세요

 

코딩하는남자 코딩연습생입니다

 

저번 PPT 슬라이드 실행과 연계해서 네트워크 공유 폴더의 파일을 C#에서 Soket으로 접속하여 실행되도록

 

구현하는 방법을 이번에 설명을 해볼까 합니다

 

C#으로 PPT슬라이드로 파일 실행하기는 아래 링크로 확인하시면 됩니다

 

https://codingman.tistory.com/37

 

[C#]파워포인트 슬라이드 구현하기

안녕하세요 코딩하는남자 코딩연습생입니다 오늘 벌써 4번째 글을 쓰고 있는거 같습니다ㅎㅎㅎ 요즘 회사 일이 많아 1일1포스팅을 지킬려고 힘들게 노력하다가 1일 1포스팅은 무조껀 지키고 시간이 있을때 많이 포..

codingman.tistory.com

그럼 다시 본론으로 돌아와서 당연히 네트워크 공유 폴더에 접근 할려면 Soket부터 구현을 해야 겠죠?

 

 

[Source Code]

using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;

 

다음 3개의 using문을 선언해 줍니다.

 

다음은 네트워크 접속시 인증과 윈도우 인증을 위한 구문 입니다

 

   [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct NETRESOURCE
        {
            public uint dwScope;
            public uint dwType;
            public uint dwDisplayType;
            public uint dwUsage;
            public string lpLocalName;
            public string lpRemoteName;
            public string lpComment;
            public string lpProvider;
        }

        // API 함수 선언
        [DllImport("mpr.dll", CharSet = CharSet.Auto)]
        public static extern int WNetUseConnection(
                    IntPtr hwndOwner,
                    [MarshalAs(UnmanagedType.Struct)] ref NETRESOURCE lpNetResource,
                    string lpPassword,
                    string lpUserID,
                    uint dwFlags,
                    StringBuilder lpAccessName,
                    ref int lpBufferSize,
                    out uint lpResult);

        // API 함수 선언 (공유해제)
        [DllImport("mpr.dll", EntryPoint = "WNetCancelConnection2", CharSet = CharSet.Auto)]
        public static extern int WNetCancelConnection2A(string lpName, int dwFlags, int fForce);

        //PPT 함수 선언
        [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
        static extern IntPtr FindWindow(IntPtr ZeroOnly, string lpWindowName);
        //PPT 함수 선언
        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
        //PPT 함수 선언
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern bool SetWindowText(IntPtr hwnd, String lpString);

        [DllImport("user32")]
        private static extern bool SetForegroundWindow(IntPtr handle);

        [DllImport("User32")]
        private static extern int ShowWindow(IntPtr hwnd, int nCmdShow);

        private string FileName = "";

 

이렇게 구조체와 Dll파일을 Import 시켜줍니다

 

이제 준비가 되었으면 공유 폴더에 접속을 해야겠죠?

 

public int ConnectRemoteServer(string server)
        {
            int capacity = 64;
            uint resultFlags = 0;
            uint flags = 0;
            System.Text.StringBuilder sb = new System.Text.StringBuilder(capacity);
            NETRESOURCE ns = new NETRESOURCE();
            ns.dwType = 1;              // 공유 디스크
            ns.lpLocalName = null;   // 로컬 드라이브 지정하지 않음
            ns.lpRemoteName = server;
            ns.lpProvider = null;
            int result = 0;
            if (server == @"\\아이피주소\폴더명$")
            {
                result = WNetUseConnection(IntPtr.Zero, ref ns, "공유폴더접속암호", "폴더이름", flags,
                                            sb, ref capacity, out resultFlags);
            }
            else
            {
                result = WNetUseConnection(IntPtr.Zero, ref ns, "공유폴더접속암호", "폴더이름", flags, sb, ref capacity, out resultFlags);
            }
            return result;
        }

 

이제는 반대로 접속을 했다면 반대로 해제도 해야겠죠?

 

public void CencelRemoteServer(string server)
        {
            WNetCancelConnection2A(server, 1, 0);
        }

 

이제 버튼을 통해 공유 폴더에 접근하는 구문입니다

 

ConnectRemoteServer(@"\\아이피주소\폴더이름");

 

그 다음 저의 경우 공유폴더에 있는 ppt파일을 실행 시키도록 구현했는데요

 

위의 ppt만들기 링크와 이어져 있습니다

 

FileName = @"\\아이피번호\폴더이름\파일이름.PPT";
PowerPoint.Application pptapp = new PowerPoint.Application();
pptapp.Visible = MsoTriState.msoCTrue;
PowerPoint.Presentation pptPres = pptapp.Presentations.Open(FileName, MsoTriState.msoCTrue, MsoTriState.msoCTrue, MsoTriState.msoCTrue);
PowerPoint.SlideShowWindow slideWindow = pptPres.SlideShowSettings.Run();

 

이렇게 하시면 공유폴더에 있는 특정 파일을 바로 파워포인트 슬라이드 모드로 실행이 됩니다

 

전에 글쓴 C#으로 파워포인트 슬라이드 실행하기와 이어서 같이 사용하시면

 

공유폴더에 있는 파일을 바로 파워포인트 슬라이드로 실행하는게 완성됩니다

반응형
반응형

안녕하세요

 

코딩하는남자 코딩연습생입니다

 

오늘 벌써 4번째 글을 쓰고 있는거 같습니다ㅎㅎㅎ

 

요즘 회사 일이 많아 1일1포스팅을 지킬려고 힘들게 노력하다가

 

1일 1포스팅은 무조껀 지키고 시간이 있을때 많이 포스팅 하자 맘 먹고 하루 벌써 4개의 포스팅을 하고 있습니다ㅎㅎㅎ

 

제가 블로그를 운영해서 미비한 수준의 실력이지만 그래도 같은 개발자분들에게 조금이나마 서로 도와주고

 

정보 공유 할 수 있는 계기가 되길 원합니다ㅎㅎ

 

이번 주제는 C#으로 파워포인트 슬라이드를 구현해볼려고 합니다

 

이걸 만들게 된 계기는 공유폴더에 파워포인트 문서를 특정 조건에 의해 자동 슬라이드를 보여 주는 방식의 

 

프로그램을 만들기 위해서 입니다

 

예를 들면 제조회사에서 공정에 작업표준을 띄운다든지 아니면 손님별 가이드 내용을 보여준다던지

 

이러한 특수 조건에 의해 파워포인트 문서를 자동으로 슬라이드로 실행시키는거죠

 

어떻게 보면 간단한 프로그램이지만 어디에 어떻게 사용하는냐에 따라 많이 응용 될수 있을거 같습니다

 

다시 본론으로 돌아와서 기본 빈 C# 프로젝트를 하나 생성합니다

 

저는 Project라는 이름으로 프로젝트를 생성했습니다

 

그다음 비쥬얼베이직에 오피스 프로그램을 불러올수 있다록 참조 설정을 진행 합니다

 

 

 

참조 관리자에서 COM탭에서 형식 라이브러리 항목중에 다음 리스트들을 참조 추가 해줍니다

 

이렇게 추가 해준뒤 이제 소스 코드를 작성해 볼께요

 

[Source Code]

using PowerPoint = Microsoft.Office.Interop.PowerPoint;

파워 포인트 슬라이드 옵션을 사용하기 위해 using문을 통해 파워포인트를 프로젝트에 삽입 시킵니다

 

 

다름 코드분을 통해 해당 위치의 PPT파일을 슬라이드옵션을 부여하여 실행시킵니다

 

 PowerPoint.Application pptapp = new PowerPoint.Application();
 pptapp.Visible = MsoTriState.msoCTrue;
 PowerPoint.Presentation pptPres = pptapp.Presentations.Open(FileName, MsoTriState.msoCTrue, MsoTriState.msoCTrue, MsoTriState.msoCTrue);
 PowerPoint.SlideShowWindow slideWindow = pptPres.SlideShowSettings.Run();

 

이렇게 실행 하게 되면 PPT파일이 실행되고 자동으로 슬라이드 옵션이 시작되면서

 

바로 슬라이드 표현이 가능해 집니다

 

이렇게 간단한 코드 몇줄로 C#으로 파워포인트 슬라이드를 제어 할 수 있습니다

 

해당 Source Code 중에

 

pptapp.Presentations.Open(FileName, MsoTriState.msoCTrue, MsoTriState.msoCTrue, MsoTriState.msoCTrue);

 

해당 구문에서 FileName의 경우 네트워크 공유 폴더의 파일 명을 가져와 자동 입력되도록 구현 했습니다

 

C#으로 네트워크 공유 폴더 접속 하는 방법은 다음번 블로그에 기재 하도록 하겠습니다

 

해당 구문을 복사하여 FileName를 Fix 고정으로 구현하면 바로 테스트가 가능합니다

 

한번 적용해 보시고 궁금한 사항이나 문제점은 댓글로 남겨 주시면 답변 드리도록 하겠습니다

 

감사합니다~

반응형
반응형

안녕하세요

 

코딩하는남자 코딩연습생입니다

 

이번 블로그글은 C#이나 C++등 비쥬얼 스튜디오를 이용하여 프로젝트 개발을 진행하고

 

배포하는 방법 중 하나인 ClickOnce 사용 방법을 다루어 볼까 합니다

 

많은 분들이 사용하고 계시는 방법인데 프로젝트 Source 관리도 편하고 배포 버전도 자동 관리를 해주니

 

정말 단점이 별로 없을 정도로 유용한 기능 중 하나 입니다

 

ClickOnce를 사용하기 위해서는 서버 IIS 기능과 FTP 기능을 사용해야 합니다

 

IIS서버가 존재한다는 가정에 설명을 하도록 하겠습니다

 

IIS서버 구축 방법은 서버 버전에 따라 많이 다르고 IIS 버전에 따라서도 많이 다르기 때문에

 

이번 시간에 IIS 서버 구축 방법까지 설명하기가 힘들거 같습니다

 

차후에 IIS 서버를 구축하게 될 일이 생기면 그때 자료를 모아서 포스팅 하도록 하겠습니다

 

 

[서버 설정]

1. IIS 서버에 배포를 위한 웹사이트 등록하기

  - 사이트 항목에서 마우스 오른쪽 버튼을 클릭하여 웹 사이트 추가를 클릭

 

2. 웹사이트 추가 정보 입력

   - 사이트 이름, 실제 경로 입력하고 확인

 

3. IIS 웹서버 상세 설정 진행

   - IIS 웹서버 상세 설정에서 "디렉터리 검색" 부분을 사용안함에서 적용으로 상태 변경

 

4. IIS서버 접속시 운영될 기본 문서 설정

   - IIS서버 상세 속성 설정에서 기본문서부분에 publish.htm 항목 추가

 

5. IIS서버 접속 인증

    - 익명 인증 사용

 

6. 생성한 IIS서버에 FTP게시 추가

    - 생성한 웹사이트 항목에서 마우스 오른쪽 버튼을 클릭하여 FTP 게시 추가 클릭

 

7. FTP 서버 상세 설정에서 FTP 권한 부여 규칙 설정

   - 모든 사용자 읽기,쓰기 권한 부여

 

8. FTP 서버 상세 설정에서 FTP 인증 규칙 설정

   - 기본인증 및 익명 인증 허용

 

9. 서버 내 게시될 위치의 폴더 권한 수정

    - 웹사이트 등록시 실제 경로의 위치의 폴더에서 마우스 오른쪽 버튼 클릭하여 속성 클릭

 

10. 폴더 속성에서 보안탭 클릭

11. 폴더 속성의 보안탭에서 편집 클릭

12. 폴더 사용권한에서 추가 버튼 클릭

13. 사용자 또는 그룹 선택 화면에서 고급 항목 클릭

14. 사용자 또는 그룹선택 고급 화면에서 지금찾기 버튼 클릭

15. 검색된 사용자중에 다음 사용자를 추가

    - IIS_IUSRS, Users

16. 비쥬얼스튜디오로 돌아와서 해당 프로젝트의 속성 보기

     - 솔루션 탐색기에서 프로젝트 항목에서 마우스 오른쪽 버튼을 클릭하여 속성 클릭

 

17. 프로젝트 속성에서 서명 탭을 클릭하여 ClickOnce 매니페스트 서명 체크

 

18. 프로젝트 속성에서 보안탭에서 ClickOnce 보안 설정 사용 체크 설정

19. 프로젝트 속성 탭에서 게시 탭을 선택

    - 게시 위치 상단에 IIS서버에서 구축한 FTP 주소 입력

    - 게시 위치 하단에 IIS서버 주소 입력

    - 설치 모드 및 설정 상세 속성 설정

 

20. 응용 프로그램 파일

     - 기본 빌드 구성의 배포 파일을 생성시켜 주므로 별도 설정은 하지 않음

 

21. 필수 구성 요소

     - 개발 환경에서 닷넷 환경에 필요한 필수 S/W를 배포시 같이 배포 되도록 설정 할 수 있음

       (저는 배포 환경에 맞지 않아 추가 구성 요소를 설정하지 않았습니다)

22. 옵션 설정

     - 게시 옵션 화면에서 프로젝트 설명

       (해당 부분의 정보는 배포시 웹사이트나 응용 프로그램 항목 명칭이 자동 생성되어 집니다

     - 게시 옵션의 배포 탭 설정

 

    - 게시 옵션 항목중 매니페스트 설정

      (바탕화면 아이콘을 자동으로 설정할 수 있음)

 

23. 마무리 단계 최종 배포 완료 이후 이렇게 웹사이트 화면으로 배포가 가능 합니다

 

다음과 같은 화면이 보이신다면 ClickOnce를 사용하여 배포에 성공하신 겁니다~

 

웹사이트에 보이는 설치 버튼 클릭 한번으로 제가 만든 응용프로그램이 자동 배포 됩니다ㅎㅎ

 

여기까지 보시는라 고생하셨습니다

 

앞으로 비쥬얼스튜디오를 사용하여 개발하였을 경우 Debug 폴더 뒤져서 배포 하지 마시고 ClickOnce를 사용해 보세요~

 

감사합니다

반응형
반응형

안녕하세요

 

코딩하는남자 코딩연습생입니다

 

이번 블로그 내용은 저번 시간에 작성했던 비동기 Soket 통신을 이용해서

 

[OMRON] RFID Reader V680S 모델과 실질적인 통신 구현 방법과

 

V680S 통신 명령어에 대해 작성해 보도록 하겠습니다

 

참고로 저도 C# 언어로 회사일을 하고 있지만 코딩이라는게 손 놓으면 금방 까먹고

 

실력이 늘지 않아서 자기 개발을 위해 연습하고 기록하고 있습니다

 

제가 올린 게시글을 보고 연습하시다 혹시 잘 안되시거나 문제가 있을 경우 댓글 남겨주시면

 

제가 아는 범위 내에서 같이 공부 하는것도 나쁘지 않을거 같습니다

 

그럼 다시 이어서 저번 시간 게시 했던 비동기 Soket 구현 방법으로 구현한 프로젝트에

 

이어서 설명을 할거라서 혹시 이전글을 못 보신분들은 이건글을 확인 한뒤에 이어 가시면 될거 같습니다

 

https://codingman.tistory.com/24

 

[C#] Soket 통신으로 RFID 연결하기 #1

안녕하세요. 코딩하는남자의 코딩연습생입니다 이번 블로그 주제는 C#의 Soket 통신을 이용해서 OMRON RFID V680S 모델과 통신을 해서 단거리 무선 통신을 구현해볼려고 해요 이걸 시도하게 된 계기는 회사에서 진..

codingman.tistory.com

 

아 참고로 게시글을 읽다 보면 SourceCode 부분에 자꾸 자동 광고가 삽입되어서

 

난감하던 찰라에 "코드블럭"이란 기능이 있다는걸 이제야 알게 되었습니다ㅎㅎ

 

앞으로 좀 더 편하게 보실 수 있도록 글쓰기 연습을 많이 하겠습니다

 

C#으로 비동기식 Soket을 구현하셨다면 이번에는 [OMRON] RFID V680S에 대해 알아야 하는데요

 

이더넷 통신이 가능한 RFID Reader로 명령어를 Send해서 Resceive받아 내는 형식으로 동작 합니다

 

좀 더 자세한 이해를 위해서는 V680S 모델의 매뉴얼을 보시는게 좋은데요

 

이것 또한 제 블로그에 기재 했으니 검색 or 링크를 통해 한번 읽어 주시면 되겠습니다

 

http://htps://codingman.tistory.com/23

불러오는 중입니다...

매뉴얼까지 읽어 보셨다면 지금 부터 설명 드리는것에 대한 이해가 빠르실겁니다

 

비동기식 Soket 통신의 시작으로 BeginConnect()를 실행시키고 나면

 

Callback이 실행 되면서 Send() 명령어를 처음에 타게 됩니다

 

이런 구조의 이유는 V680S의 교신 방식 때문인데요 매뉴얼을 읽어 보시면 V680S의 교신 방법이

 

3가지가 있습니다

 

첫번째는 1회성 교신

두번째는 자동 교신

세번째는 FIFO. 트리거 교신

 

 

교신 방법별 특징은 매뉴얼에 상세히 나와 있으니 참고 하시면 될거 같구요

 

 

이런식으로 V680S는 교신 이후 교신처리 단계를 거치게 됩니다

 

즉, 명령어로 "너 읽어라"라는 신호를 주기 전까지는 대기를 한다는 뜻입니다

 

그래서 V680S에게 "너 읽어라"라는 명령어를 주기 위해 처음 Send를 보내게 됩니다

 

Send부분에서는 Byte형식의 Buffer 배열을 V680S로 명령어를 전송 줍니다

 

byte[] sndBuf = new byte[12];
sndBuf[0] = 0x00;   // 트랜잭션 식별자 상위
sndBuf[1] = 0x00;   // 트랜잭션 식별자 하위
sndBuf[2] = 0x00;   // 프로토콜 식별자 상위
sndBuf[3] = 0x00;   // 프로토콜 식별자 하위
sndBuf[4] = 0x00;   // 필드길이 상위
sndBuf[5] = 0x06;   // 필드길이 하위
sndBuf[6] = 0xFF;   // 유니트 식별자 (고정)
sndBuf[7] = 0x03;   // 펑션코드
sndBuf[8] = 0x00;   // (byte)((nAdr & 0xFF00) >> 8);       // 레지스터번호 상위
sndBuf[9] = 0x00;   // (byte)(nAdr & 0x00FF);              // 레지스터번호 하위
sndBuf[10] = (byte)((pWordSize & 0xFF00) >> 8); // 워드카운트 상위
sndBuf[11] = (byte)(pWordSize & 0x00FF);        // 워드카운트 상위

이런 형식의 Buffer를 생성하는 이유는 V680S가 알아 듣는 형식이 이렇기 때문이에요

 

 

자 이렇게 메뉴얼에 나와 있듯이 V680S는 Hex값을 분석하여 지금 나의 행동을 파악하게 되는 구조입니다

 

C#에서 Hex값을 만들기위해 저는 Byte형식을 사용한 것입니다

 

자 이렇게 읽어와라는 명령어를 Send()를 통해 전달을 하게 되면 V680S는 RFID Tag를 읽어 들여 Receive하게

 

그럼 당연히 Callback에서 Send 호출이후에는 당연히 Receive를 해야겠죠?

 

Receive역시 저는 비동기식 Soket을 구현하였기 때문에 BeginReceive로 사용합니다

 

BeginReceive를 호출하게 되면 역시 Callback을 호출하게 되구요

 

private void Receive()
        {
            try
            {
                rfSocket.BeginReceive(StateObject.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), rfSocket);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                Disconnect();
                return;
            }
        }

 

Receive 코드는 이렇습니다

 

그 다음 ReceiveCallback에서는 V680S에게 리턴 받은 값을 처리하는 구문을 작성하면 됩니다

 

이해가 좀 되셨나요??

 

나름 자세히 설명한다고 했는데 처음에는 저도 많이 해매면서 공부한것이라

 

정리를 하면

 

1. V680S와 Soket통신을 구현하고

 

2. V680S에게 Send를 통해 명령어를 전달하고

 

3. V680S의 리턴값을 받아 저장 또는 출력을 시킨다

 

이렇게 됩니다

 

해당 글을 읽으면서 시도하시다 막히는 부분이나 이해가 되지 않는 부분은 댓글 남겨주시면

 

제가 아는 범위에서 성심껏 답변드리도록 하겠습니다

 

감사합니다~

반응형
반응형

안녕하세요.

 

코딩하는남자 코딩연습생입니다

 

현재 개발 정보와 IT 개발 관련 정보를 게시하면서 블러그를 운영하고 있습니다

 

구글 애드센스 발급 이후 "1일 1게시글을 하자!"

 

독하게 맘 먹고 운영 중인데

 

다음 애드핏 심사에서 계속 보류를 맞고 있습니다ㅎㅎㅎ

 

이유는 다음과 같습니다

 

"해당 매체는 최근 콘텐츠 부족으로 보류되었습니다. 지속적인 업데이트 확인이 가능하도록 콘텐츠를 보충 후 재심사를 요청하여 주시기 바랍니다."

 

나름 열정을 가지고 운영하고 있는 중이고 최근 콘텐츠 부족 이라니...ㅋㅋㅋ

 

혹시나 하는 마음에 구글 검색을 해보니

 

첫심사 이후 6개~8개의 최신글을 등록한뒤 재심사를 요청하면 승인이 된다

 

뭐 이런 글이 있더라구요ㅋㅋ

 

그래서 도전!!

 

근데 역시나 결과는 보류입니다ㅋㅋ

 

역시 세상에는 내맘대로 되는게 하나도 없네요ㅋㅋㅋㅋ

 

그래도 뭐 제가 돈 벌자고 블러그 운영하는건 아니고 구글도 사실 애드센스만 받아놨지 수입 아직 0원이고ㅋㅋㅋ

 

블러그 방문자가 일일 한10,000명 정도 되면 수입이 생길라나요?ㅋㅋㅋ

 

IT 관련 정보 글은 아니지만 블러그를 열심히 운영하고자 하는 마음에 찬물을 끼얻은거 같은 기분이 들어

 

한탄 글 한번 써봤습니다ㅋㅋ

 

혹시 다음 애드핏에서 이 글을 보신다면 승인 부탁드립니다ㅋㅋ

 

애드핏 승인되면 결과 보고 하겠습니다~

반응형

+ Recent posts