블로그 이미지
따시쿵

calendar

1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

Notice

'C# with Service Program'에 해당되는 글 3

  1. 2015.05.15 [C#] 서비스 프로그램 - 디버깅
  2. 2015.05.14 [C#] 서비스 프로그램 - 2
  3. 2015.05.11 [C#] 서비스 프로그램 - 1
2015. 5. 15. 11:58 C# with Service Program

프로그램 설명


윈도우즈 서비스 프로그램을 디버깅하는 예제입니다.

디버깅하는 방법은 콘솔 프로그램 같이 F10 버튼을 이용하여 다음 단계로 넘어가는 것입니다.


1. visual syudio 2013 을 관리자 권한으로 실행


2. 프로그램 출력 형식을 [콘솔 응용 프로그램]으로 변경



3. 현재 프로그램이 대화형으로 실행되고 있는지 확인하는 로직 추가


기존의 Main  method를 다음과 같이 변경함. Environment.UserInteractive 를 이용해서 확인합니다. 그리고 테스트 TestStartupAndStop method를 추가합니다.


        static void Main(string[] args)
        {
            if (Environment.UserInteractive)
            {
                MyNewService2 service2 = new MyNewService2();
                service2.TestStartupAndStop(args);
            }
            else
            {
                // Put the body of your old Main method here.
                ServiceBase[] ServicesToRun;
                ServicesToRun = new ServiceBase[] 
                { 
                    new MyNewService2() 
                };
                ServiceBase.Run(ServicesToRun);
            }
        }

TestStartupAndStop method를 기술합니다.

        #region TestStartupAndStop
        internal void TestStartupAndStop(string[] args)
        {
           Console.WriteLine("TestStartupAndStop");
           this.OnStart(args);
           LogFile.WriteLog("TestStartupAndStop");
            
            Console.ReadLine();
            this.OnStop();
        }
        #endregion


4. 단일 thread 인 경우, 사용자 thread 가 있는 경우


메인 Thread 에서 작업하는 경우, 즉 단일 쓰레드에서 사용자 작업을 하는 경우에는 OnStart() 안에 로직을 추가하면 됩니다.


그러나, 메인 Thread 외에 사용자 Thread를 이용하는 경우에는, 메인 Thread가 사용자 쓰레드가 정지 할때까지 기달려야 합니다. 그래서 기존의 OnStart() 안에 thread_handler.Join(); 코드를 추가했습니다.

        #region OnStart
        protected override void OnStart(string[] args)
        {
            LogFile.WriteLog("OnStart");
                        
            // Create the sub working thread...
            Thread thread_handler = new Thread(socketMain.StartSocket);
            thread_handler.IsBackground = true;
            thread_handler.Start();

            if (Environment.UserInteractive)
            {
                   thread_handler.Join();
            }
        }
        #endregion



실행 화면



소스 파일 : 

MyNewService2_debug.zip






'C# with Service Program' 카테고리의 다른 글

[C#] 서비스 프로그램 - 2  (0) 2015.05.14
[C#] 서비스 프로그램 - 1  (0) 2015.05.11
posted by 따시쿵
2015. 5. 14. 14:23 C# with Service Program

프로그램 설명


윈도우즈 서비스를 이용해서 Tcp 통신을 하는 예제입니다.

서버는 서비스로 만들었으며, 클라이언트는 윈도우즈 폼으로 작성 했습니다.

서버에서 클라이언트와 통신을 할 때 각 단계별로 로그 파일을 쌓아서 진행 상황을 체크 합니다.


1. app.config 파일에 실제 로그를 쌓을 경로 이름을 기술합니다.


    
      
    
  
     
        
    


Debug 폴더 안에서 파일을 실행 시키면 System.IO.Directory.GetCurrentDirectory() method 를 이용해서 현재의 위치를 찾을 수 있지만, 서비스 프로그램에서 실행 파일의 현재 위치를 찾게되면 64비트 컴퓨터에서는 C:\Windows\SysWOW64 폴더를 찾습니다. 따라서 SysWOW64 폴더 하위에 Log 폴더를 생성합니다. 


app.config 파일 안에서 로그 파일의 위치를 풀경로를 이용해서 명시해 줍니다.


2. 로그 파일 이용 방법 

로그 라이브러리 : LogFile.cs

LogFile.WriteLog("OnStart");

LogFile.WriteLog(ex.Message, LogFile.LogCode.Error);


3. 윈도우즈 서비스가 설치된 컴퓨터의 방화벽에서 해당하는 포트를 열러 주어야 합니다.



실행 화면







프로그램 작성 순서


1. 서비스 프로그램의 OnStart() 에서 소켓 관련 thread 를 생성합니다.


        protected override void OnStart(string[] args)
        {
            LogFile.WriteLog("OnStart");
                        
            // Create the sub working thread...
            Thread thread_handler = new Thread(socketMain.StartSocket);
            thread_handler.IsBackground = true;
            thread_handler.Start();
        }


2. 일반적인 소켓 서버 클래스를 작성합니다.


        static TcpListener server = null;
        #region StartSocket
        public void StartSocket()
        {
            LogFile.WriteLog("StartSocket");

            try
            {
                // set the TcpListener on port 14000
                Int32 port = 14000;
                
                // create the server socket & start
                server = new TcpListener(IPAddress.Any, port);
                server.Start();

                // buffer for reading data
                byte[] bytes = new byte[2014];
                string data = string.Empty;

                // waiting for a client connection
                while (true)
                {
                    LogFile.WriteLog("Waiting for a connection....");

                    TcpClient client = server.AcceptTcpClient();
                    LogFile.WriteLog("Connected!");

                    NetworkStream stream = client.GetStream();

                    // read the message from client and send the message to client
                    int bytesRead = 0;
                    while ((bytesRead = stream.Read(bytes, 0, bytes.Length)) != 0)
                    {
                        data = Encoding.UTF8.GetString(bytes, 0, bytesRead);
                        LogFile.WriteLog(string.Format("Received : {0}", data));

                        data = data.ToUpper();

                        byte[] msg = Encoding.UTF8.GetBytes(data);

                        stream.Write(msg, 0, msg.Length);
                        LogFile.WriteLog(string.Format("Sent : {0}", data));
                    }

                    client.Close();
                }

            }
            catch (SocketException se)
            {
                LogFile.WriteLog(se.Message, LogFile.LogCode.Error);
            }
            catch (Exception ex)
            {
                LogFile.WriteLog(ex.Message, LogFile.LogCode.Error);
            }
            finally
            {
                server.Stop();
            }

        }
        #endregion


3. OnStop method 에서 socket server를 닫습니다.


        protected override void OnStop()
        {
            LogFile.WriteLog("OnStop");

            socketMain.StopSocket();
        }




소스 파일 :

MyNewService2.zip   MyNewService2_Client.zip

'C# with Service Program' 카테고리의 다른 글

[C#] 서비스 프로그램 - 디버깅  (0) 2015.05.15
[C#] 서비스 프로그램 - 1  (0) 2015.05.11
posted by 따시쿵
2015. 5. 11. 17:21 C# with Service Program
프로그램 설명

서비스 프로그램을 작성하고 인스톨하며, 삭제하고 서비스의 시작과 종료를 event log 에 명시하는 프로그램입니다.


1. 서비스 만들기


서비스를 만들고 구성하려면


1. Visual Studio의 메뉴 모음에서 파일, 새로 만들기, 프로젝트를 선택합니다.   

새 프로젝트 대화 상자가 열립니다.   


2. Visual C# 프로젝트 템플릿 목록에서 Windows 서비스를 선택하고 프로젝트의 이름을 MyNewService로 지정합니다. 확인을 선택합니다. 


프로젝트 템플릿은 System.ServiceProcess.ServiceBase에서 상속된 Service1이라는 구성 요소 클래스를 자동으로 추가합니다.   


3. 편집 메뉴에서 찾기 및 바꾸기, 파일에서 찾기를 선택합니다(키보드: Ctrl+Shift+F).  모든 Service1을 MyNewService로 변경합니다. Service1.cs, Program.cs 및 Service1.Designer.cs  파일에서 인스턴스를 찾습니다. 


4. Service1.cs [디자인] 의 속성 창에서 Service1의 ServiceName 및 (이름) 속성이 아직 설정되어 있지 않으면 MyNewService로 설정합니다.  


5. 솔루션 탐색기에서 Service1.cs의 이름을 MyNewService.cs로 바꿉니다. 



2. 서비스에 기능 추가


사용자 지정 이벤트 로그 기능을 서비스에 추가하려면


1. 솔루션 탐색기에서 MyNewService.cs 뷰 디자이너를 선택합니다.  


2. 도구 상자의 구성 요소 섹션에서 EventLog 구성 요소를 디자이너로 끌어 옵니다.  


3. 솔루션 탐색기에서 MyNewService.cs 메뉴를 열고 코드 보기를 선택합니다.  


4. MyNewService 클래스에서 components 변수를 선언하는 줄 바로 다음에 eventLog 개체에 대한 선언을 추가합니다. 

this.AutoLog = false;

5. 사용자 지정 이벤트 로그를 정의하는 생성자를 추가하거나 편집합니다. 

	public MyNewService()
	{
		InitializeComponent();
		if (!System.Diagnostics.EventLog.SourceExists("MySource")) 
		{         
				System.Diagnostics.EventLog.CreateEventSource(
					"MySource","MyNewLog");
		}
		eventLog1.Source = "MySource";
		eventLog1.Log = "MyNewLog";
	}


서비스가 시작될 때 수행되는 동작을 정의하려면


• 코드 편집기에서 프로젝트를 만들 때 자동으로 재정의된 OnStart 메서드를 찾아서 코드를 다음과 같이 바꿉니다.  이렇게 하면 서비스 실행이 시작될 때 이벤트 로그에 항목이 추가됩니다. 

        protected override void OnStart(string[] args)
        {
            eventLog1.WriteEntry("In OnStart");
        }

서비스 응용 프로그램은 오랫동안 실행되도록 설계되므로 대개 시스템의 특정 항목을 폴링하거나 모니터링합니다.  모니터링은 OnStart 메서드에서 설정됩니다. 그러나 OnStart가 실제로 모니터링을 수행하지는 않습니다. 서비스의 작업이 시작되고 나면 OnStart 메서드가 운영 체제에 반환되어야 하며 무제한 순환하거나 방해가 되어서는 안 됩니다. 간단한 폴링 메커니즘을 설정하려면 System.Timers.Timer 구성 요소를 사용할 수 있습니다. 타이머는 코드에서 주기적으로 이벤트를 발생시키며 그러는 동안에도 서비스에서는 모니터링을 수행할 수 있습니다. 이렇게 하려면 다음 코드를 사용할 수 있습니다.

        protected override void OnStart(string[] args)
        {
            eventLog1.WriteEntry("In OnStart");

            // Set up a timer to trigger every minute.
            System.Timers.Timer timer = new System.Timers.Timer();
            timer.Interval = 60000; // 60 seconds
            timer.Elapsed += new System.Timers.ElapsedEventHandler(this.OnTimer);
            timer.Start();
        }


타이머 이벤트를 처리하는 코드를 추가합니다.

        public void OnTimer(object sender, System.Timers.ElapsedEventArgs args)
        {
            // TODO: Insert monitoring activities here.
            eventLog1.WriteEntry("Monitoring the System", EventLogEntryType.Information, 210001);
        }

주 스레드에서 모든 작업을 실행하는 대신 백그라운드 작업자 스레드를 사용하여 작업을 수행할수도 있습니다.


3. 서비스에 설치 관리자 추가


서비스를 위한 설치 관리자를 만들려면


1. 솔루션 탐색기에서 MyNewService.cs 의 메뉴를 열고 뷰 디자이너를 선택합니다.   


2. 디자이너의 배경을 클릭하여 서비스 내용이 아닌 서비스 자체를 선택합니다.  


3. 디자이너 창의 상황에 맞는 메뉴를 열고(포인팅 장치를 사용하는 경우 창 안쪽을 마우스 오른쪽 단추로 클릭) 설치 관리자 추가를 선택합니다.   



기본적으로 설치 관리자가 두 개 들어 있는 구성 요소 클래스가 프로젝트에 추가됩니다.  구성 요소의 이름이 ProjectInstaller로 지정되며 구성 요소에는 서비스를 위한 설치 관리자와 서비스 관련 프로세스를 위한 설치 관리자가 들어 있습니다. 


4. ProjectInstaller의 디자인 뷰에서 Visual C# 프로젝트의 경우 serviceInstaller1을 선택합니다.  


5. 속성 창에서 ServiceName 속성이 행복서비스로 설정되어 있는지 확인합니다.  


6. 설명 속성을 "샘플 서비스"와 같은 텍스트로 설정합니다.  이 텍스트는 서비스 창에 표시되며 사용자가 서비스를 식별하고 서비스의 용도를 이해하는 데 도움이 됩니다. 


7. DisplayName  속성을 서비스 창의 이름 열에 표시할 텍스트로 설정합니다.  예를 들어 "행복서비스 표시 이름"을 입력할 수 있습니다. 이 이름은 net start 명령을 사용하여 서비스를 시작하는 등의 경우 시스템에서 사용하는 이름인 ServiceName 속성과는 다릅니다. 


8. StartType  속성을 Automatic으로 설정합니다. 


9. 디자이너에서 Visual C# 프로젝트의 경우 serviceProcessInstaller1을 선택합니다.  Account  속성을 LocalSystem으로 설정합니다. 이렇게 하면 서비스가 로컬 서비스 계정으로 설치되고 실행됩니다. 



4. 시작 매개 변수 설정


다른 실행 파일과 마찬가지로 Windows 서비스에도 명령줄 인수나 시작 매개 변수를 사용할 수 있습니다.  프로세스 시작 매개 변수에 코드를 추가하면 사용자가 Windows 제어판의 서비스 창을 사용하여 고유한 사용자 지정 시작 매개 변수로 서비스를 시작할 수 있습니다. 그러나 이러한 시작 매개 변수는 다음 번에 서비스를 시작할 때 유지되지 않습니다. 시작 매개 변수를 영구적으로 설정하려는 경우 아래 절차에 나와 있는 것처럼 레지스트리에서 설정하면 됩니다. 


일반적으로 서비스에 많은 시작 매개 변수가 필요한 경우에는 레지스트리나 구성 파일을 대신 사용하는 것이 좋습니다. 

모든 Windows 서비스에는 레지스트리의 HKLM\System\CurrentControlSet\services 아래에 항목이 있습니다. 이 서비스의 키 아래에서 매개 변수 하위 키를 사용하여 서비스가 액세스할 수 있는 정보를 저장할 수 있습니다. Windows 서비스의 응용 프로그램 구성 파일은 다른 프로그램 형식에서와 같은 방식으로 사용할 수 있습니다. 예제 코드를 보려면 AppSettings를 참조하세요. 

1. Program.cs 의 Main 메서드에서 명령줄에 대해 인수를 추가합니다. 

        static void Main(string[] args) 
        { 
            ServiceBase[] ServicesToRun; 
            ServicesToRun = new ServiceBase[] 
            { 
                new MyNewService1(args) 
            }; 
            ServiceBase.Run(ServicesToRun); 
        }

2. MyNewService 생성자를 다음과 같이 변경합니다. 

        public MyNewService1(string[] args)
        {            
            InitializeComponent();
            string eventSourceName = "MySource";
            string logName = "MyNewLog";
            if (args.Count() > 0)
            {
                eventSourceName = args[0];
            }
            if (args.Count() > 1)
            {
                logName = args[1];
            }
            eventLog1 = new System.Diagnostics.EventLog();
            if (!System.Diagnostics.EventLog.SourceExists(eventSourceName))
            {
                System.Diagnostics.EventLog.CreateEventSource(eventSourceName, logName);
            }
            eventLog1.Source = eventSourceName;
            eventLog1.Log = logName;
        }

이 코드는 제공된 시작 매개 변수에 따라 이벤트 소스 및 로그 이름을 설정하거나, 인수를 제공하지 않는 경우에는 기본값을 사용합니다. 


3. 명령줄 인수를 지정하려면 ProjectInstaller.cs 의 ProjectInstaller 클래스에 다음 코드를 추가합니다. 

        protected override void OnBeforeInstall(IDictionary savedState)
        {
            string parameter = "MySource1\" \"MyLogFile1";
            Context.Parameters["assemblypath"] = "\"" + Context.Parameters["assemblypath"] + "\" \"" + parameter + "\"";
            base.OnBeforeInstall(savedState);
        }

이 코드는 기본 매개 변수 값을 추가하여 일반적으로 Windows 서비스 실행 파일의 전체 경로를 포함하는 ImagePath 레지스트리 키를 수정합니다. 경로와 개별 매개 변수는 따옴표로 묶어야 서비스가 올바르게 시작됩니다. 이 Windows 서비스의 시작 매개 변수를 변경하려는 경우 사용자는 ImagePath 레지스트리 키에 지정된 매개 변수를 변경할 수 있습니다. 그러나 해당 키를 프로그래밍 방식으로 변경하고 사용자 친화적인 방식(예: 관리 또는 구성 유틸리티)으로 기능을 노출하는 것이 보다 효율적입니다.



5. 서비스 빌드


서비스 프로젝트를 빌드하려면


1. 솔루션 탐색기에서 프로젝트의 상황에 맞는 메뉴를 열고 속성을 선택합니다.  프로젝트의 속성 페이지가 나타납니다. 


2. 응용 프로그램 탭의 시작 개체 목록에서 MyNewService.Program을 선택합니다.   


3. 솔루션 탐색기에서 프로젝트의 상황에 맞는 메뉴를 열고 빌드를 선택하여 프로젝트를 빌드합니다(키보드: Ctrl+Shift+B). 


6. 서비스 설치


Windows 서비스를 설치하려면


1. Windows 7 및 Windows Server에서는 시작 메뉴의 Visual Studio Tools에서 개발자 명령 프롬프트를 엽니다.  Windows 8 또는 Windows 8.1에서는 시작 화면의 Visual Studio Tools 타일을 선택한 다음 관리 자격 증명을 사용하여 개발자 명령 프롬프트를 실행합니다. 마우스를 사용하는 경우 개발자 명령 프롬프트를 마우스 오른쪽 단추로 클릭한 후 관리자 권한으로 실행을 선택합니다. 


2. 명령 프롬프트 창에서 프로젝트의 출력이 포함된 폴더로 이동합니다.  예를 들어, 내 문서 폴더에서 D:\win_project\winformapp2\MyNewService1\bin\Debug로 이동합니다. 


3. 다음 명령을 입력합니다. 


installutil.exe MyNewService1.exe





7. 서비스 시작 및 실행


서비스를 시작하고 중지하려면


1. Windows에서 시작 화면 또는 시작 메뉴를 열고 services.msc를 입력합니다.  

이제 서비스 창의 목록에 행복서비스 이름 표시 가 표시됩니다. 


2. 서비스 창에서 서비스의 바로 가기 메뉴를 열고 시작을 선택합니다.   


3. 서비스의 바로 가기 메뉴를 열고 중지를 선택합니다.   


4. (선택 사항) 명령줄에서 net start 행복서비스 및 net stop 행복서비스 명령을 사용하여 서비스를 시작하고 중지할 수 있습니다. 


서비스의 이벤트 로그 출력을 확인하려면


1. 명령 프롬프트 창에서 eventvwr.msc 를 입력합니다.


2. MyNewLog(선택적 절차를 사용하여 명령줄 인수를 추가한 경우에는 MyLogFile1)의 목록을 찾아서 확장합니다.  서비스에서 수행한 두 작업(시작 및 중지)의 항목을 확인할 수 있습니다. 


8. Windows 서비스 제거


서비스를 제거하려면


1. 관리 자격 증명을 사용하여 개발자 명령 프롬프트를 엽니다.  


2. 명령 프롬프트 창에서 프로젝트의 출력이 포함된 폴더로 이동합니다.  예를 들어, 내 문서 폴더에서 D:\win_project\winformapp2\MyNewService1\bin\Debug로 이동합니다. 


3. 다음 명령을 입력합니다. 


installutil.exe /u MyNewService.exe



소스 파일 : 

MyNewService1.zip





'C# with Service Program' 카테고리의 다른 글

[C#] 서비스 프로그램 - 디버깅  (0) 2015.05.15
[C#] 서비스 프로그램 - 2  (0) 2015.05.14
posted by 따시쿵
prev 1 next