본문 바로가기
프로그래밍

프로세스간 메시지 전송[0]

by minimax95 2020. 4. 30.

 

독립된 프로그램 간에 메시지를 전송해야 할 때가 있다. 

Agent 프로그램으로 어떤 프로그램 실행 제어를 한다거나 종료 방지를 하기 위해서 Alive 메시지를 확인하고 싶을 때가 있다. 

여기서 알아보는 것은 Window Message를 이용해서 프로세스 간에 COPYDATASTRUCT 구조체를 전달하는 기능을 살펴보고자 한다.

 

간단하게 한 프로세스에서 시스템 시간을 담아서 다른 프로세스로 전송하는 것을 구현한다면 핵심 코드는 아래와 같다.

 

전송받는 프로세스와 전송하는 프로세스 공통

먼저 using문을 이용하여 필요한 네임스페이스를 추가한다.

using System.Diagnostics;

using System.Threading;

using System.Runtime.InteropServices;  // WinAPI 사용

 

그리고 프로세스간 메시지를 전달할 구조체(COPYDATASTRUCT)를 정의한다.

const in WM_COPYDATA = 0x4A

public struct COPYDATASTRUCT

{

    public IntPrt dwData;  // 헤더로 사용(데이터 종류 구분)

    public int cdData;  // 데이터 사이즈

    [MarshalAs(UnmanagedType.LPStr)]

    public string lpData;  // 실제 데이터를 싣는 변수

}

 

전송받는 프로세스

전달받는 메시지 저장 변수를 선언해 준다.

private string Msg = String.Empty;

 

다음은 Window Message를 전달 받기 위해 WinProc() 메서드 오버라이드를 한다.

protected override void WndProc(ref Message msg)  // Message 는 Windows 메시지를 처리하는 구조체임

{

    try

    {

        switch(msg.Msg)

        {

            case WM_COPYDATA:

                COPYDATASTRUCT cds = (COPYDATASTRUCT)msg.GetLParam(typeof(COPYDATASTRUCT));

                if(cds.lpData > 0)

                {

                    Msg = cds.lpData;

                    Debug.WriteLine("전송받은 메시지 시간 : " + Msg);  // 콘솔에 출력

                }

                break;

             default:

                base.WndProc(ref msg);

                break;

        }

    }

    catch(Exception ex)

    {

        Debug.WriteLine("메시지 에러 : " + ex.ToString());

    }

}

 

전송하는 프로세스

전송하는 프로세스에서는 'user32.dll' 라이브러리의 SendMessage( ) 함수를 사용하기 위해 DllImport 문을 추가해 준다.

[DllImport("user32.dll", CharSet = CharSet.Auto)]

public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, uint wPararm, ref COPYDATASTRUCT lParam);

 

시스템 전송시간은 작업자 스레드에 위임하기 위해서 스레드를 추가한다.

private Thread TimeSendThread = null;

 

TimeSendThread 함수 처리기를 정의한다.

private void TimeSendThreadRun( )

{

    while(true)

    {

        Thead.Sleep(1000);

        var proc = Process.GetProcessesByName("TimeSendExe");   // "TimeSendExe"는 시간을 전송받는 프로세스 이름

        if(proc.Length !=0) // TimeSendExe가 실행 중이면

        {

            Inthwd = proc[0].MainWindowHandle;

            byte[] buf = System.Text.Encoding.Default.GetBytes(DataTime.Now.ToString("HH.mm.ss"));

            COPYDATASTRUCT cds = new COPYDATASTRUCT( );

            cds.dwData = IntPtr.Zero;

            cds.cbData = buf.Length + 1;

            cds.lpData = "01_" + DataTime.Now.ToString("HH.mm.ss");

            SendMessage(Inthwd, WM_COPYDATA, 0, ref cds);   // 메시지 전송

        }

        Thread.Sleep(1000);

    }

}

 

각 프로세스 실행시 프로세스간 메시지 전송(시간)을 확인 할 수 있다.

댓글