반응형

안녕하세요

 

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

 

저번 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#으로 파워포인트 슬라이드 실행하기와 이어서 같이 사용하시면

 

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

반응형
반응형

안녕하세요.

 

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

 

이번 블로그 주제는 C#의 Soket 통신을 이용해서 OMRON RFID V680S 모델과 통신을 해서

 

단거리 무선 통신을 구현해볼려고 해요

 

이걸 시도하게 된 계기는 회사에서 진행되는 프로젝트 때문인데요

 

특정 바구니에 RFID Tag를 달고 임의 위치에 바구니가 사용될 때마다 Tag를 읽어들여

 

바누니의 현재 상황을 파악하기 위해 구성해봤습니다

 

현재 프로젝트의 규모는 RFID Reader 20ea + RFID Tag 80ea정도 공사가 진행되었구요

 

제가 만든 프로그램에서 20개의 Reader를 동시에 제어하여 20곳에 사용될 바구니의 정보를

 

실시간 습득합니다

 

전체 SourceCode를 Open할수 있다면 좋을거 같은데 아무래도 상용의 목적으로 구축된 부분이라

 

일부만 공개할수 있어서 아쉽습니다

 

혹시 저와 비슷한 프로그램을 목적으로 구성중이시라면 도움이 되셨으면 좋겠습니다

 

내용이 많아서 이번 블로그에서는 C#으로 소켓 통신 하는 부분만 설명 하겠습니다

 

[Source Code]

using System.Net;
using System.Net.Sockets;

 

public class AsynchronousClient
{
    private Socket rfSocket = null;
    private EndPoint rfEP;
    private ManualResetEvent connectDone = new ManualResetEvent(false);
    private ManualResetEvent DisconnectDone = new ManualResetEvent(false);
    private ManualResetEvent sendDone = new ManualResetEvent(false);
    private ManualResetEvent receiveDone = new ManualResetEvent(false);

    private string response = string.Empty;



    private int pByteSize = 0;
    private int pWordSize = 0;



public void StartClient()
{
    connectDone.Reset();
   DisconnectDone.Reset();

   try
   {
      rfSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
      rfEP = new IPEndPoint(IPAddress.Parse(RFIDIP), RFIDPORT);

      connectDone.Reset();
      rfSocket.BeginConnect(rfEP, new AsyncCallback(ConnectCallback), rfSocket);
      connectDone.WaitOne();
   }
   catch (Exception e)
   {
      Console.WriteLine(e.ToString());
   }
}



private void Disconnect()
{
      if((rfSocket != null) && (rfSocket.Connected))
      {
          DisconnectDone.Reset();
          rfSocket.Shutdown(SocketShutdown.Both);
          rfSocket.BeginDisconnect(true, DisconnectCallback, rfSocket);
      }
      else
     {
         StartClient();
     }

}



private void ConnectCallback(IAsyncResult ar)
{
    connectDone.Set();

    try
    {
       Socket client = (Socket)ar.AsyncState;
       client.EndConnect(ar);

      Send();     
      Receive();
    }
    catch (Exception e)
   {
      Console.WriteLine(e.ToString());
      Disconnect();
   }
}



private void DisconnectCallback(IAsyncResult ar)
{
    DisconnectDone.Set();

    try
    {
       Socket client = (Socket)ar.AsyncState;
       client.EndDisconnect(ar);
       client.Close();
    }
    catch (Exception e)
    {
       Console.WriteLine(e.ToString());
    }

       StartClient();
}



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



private void ReceiveCallback(IAsyncResult ar)
{
    try
    {
        Socket client = (Socket)ar.AsyncState;
        client.EndReceive(ar);

    }

    catch (Exception e)
    {
        Console.WriteLine(e.ToString());
        if (rfSocket.Connected)
           Send();
        else
           StartClient();
        return;
    }
}



private void Send()
{
     try
    {
        if ((rfSocket != null) && (rfSocket.Connected))
        {
               rfSocket.BeginSend(CurrfidCommand(), 0, CurrfidCommand().Length, 0,

                                        new AsyncCallback(SendCallback), rfSocket);
        }
    }
    catch (Exception e)
    {
       Console.WriteLine(e.ToString());
       Disconnect();
    }
}



public void Reset_Send()
{
    try
    {
         if ((rfSocket != null) && (rfSocket.Connected))
         {
                rfSocket.BeginSend(ResetCommand(), 0, ResetCommand().Length, 0,

                                         new AsyncCallback(SendCallback), rfSocket);
          }
    }
    catch (Exception e)
    {
        Console.WriteLine(e.ToString());
        Disconnect();
    }
}



private void SendCallback(IAsyncResult ar)
{
     try
    {
          Socket client = (Socket)ar.AsyncState;

          int bytesSent = client.EndSend(ar);

          sendDone.Set();

    }
    catch (Exception e)
    {
          Console.WriteLine(e.ToString());
          Disconnect();
          return;
    }
}

}

 

 

 

 

 

 

해당 위의 Source Code는 비동기식 Soket 통신입니다

 

그래서 BeginConnect(), BeginReceive(), BeginSend()를 사용합니다

 

해당 공개한 Source Code를 응용해서 비동기식 Soket 통신 모듈을 직접 개발하여 이더넷 여러 기기와

 

통신이 가능한 프로그램 제작을 시도해 보시면 좋을거 같습니다

 

이어 두번째 영상에는 현재 만들어진 비동기식 Soket 프로그램을 통해 OMRON RFID V680S 모델과

 

통신하는 방법에 대한 글을 이어서 작성하도록 하겠습니다

 

 

반응형
반응형

안녕하세요

 

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

 

프로그래밍을 하다보면 CallBack 함수를 사용해야 되는 상황이 발생합니다

 

예를들면 Soket통신을 구현할때 수신/응답을 비동기식으로 구현해야할 경우가 이에 해당하죠

 

Soket 통신의 원리르 보면 이더넷 환경의 장비에 응답코드를 송신하여 그에 해당하는 결과 값을 받아오게 되죠

 

이경우 두가지 형식으로 구현을 합니다 동기식/비동기식.

 

동기식은 송신후 응답코드가 수신될때까지 멈춰 대기 하게 됩니다

 

구현할려는 장비와 운영 방법에 따라 즉시 응답이 가능하다면 동기식으로 구현하는것이 맞겠죠

 

하기만 한번에 여러대의 장비와 통신을 해야 하는 경우 혹은 수신까지 걸리는 ReadTime이 길 경우에는 무한정

 

기다릴수 만은 없기 때문에 비동기식 구현 방법을 사용 합니다

 

비동기식은 동기식과 반대로 응답코드를 송신하고 수신이 올때까지 다른 대기자가 대기하고 다른 프로세스를 실행 할 수 있죠 

 

 

비동식에서 사용해야 하는 "대리자"가 바로 이번 작성할려는 주제입니다

 

CallBack 함수를 사용할려면 누군가는 항상 값을 받을 준비를 하고 있어야 합니다

 

그 대리자가 Delegate 입니다

 

이번 C#으로 RFID 통신을 구현하면서 사용한 Source Code의 일부를 가지고 설명을 해드릴께요

 

 

1. Delegate 선언

   - RFID Tag와 Reader간 통신을 하면서 Reader가 Tag의 값을 읽기 전까지 무한 대기 합니다

   - 그후 선언된 Delegate를 통해 Tag가 읽히게 되면 나머지 프로세서를 처리하게 되는 구조 입니다

   - Delegate선언 방법은 간단합니다

     

//delegate 선언
//CallBack Fucntion 타입 정의
public delegate void OnSendToRFIDDelegate(int nCmdID, byte[] bBuf, int nSize, string sDump);
public delegate void OnReceiveFromRFIDDelegate(int nCmdID, byte[] bBuf, int nSize, string sDump);
public delegate void OnAddRFIDMsgDelegate(string sMsg);
public delegate void OnRFIDExceptionDelegate();

//CallBack 호출을 위한 전역함수 정의
Public OnSendToRFIDDelegate OnSendToFRID;
public OnReceiveFromRFIDDelegate OnReceiveFromRFID;
public OnAddRFIDMsgDelegate OnAddRFIDMsg;
public OnRFIDExceptionDelegate OnRFIDException;

 

다음과 같이 Delegate를 선언하고 그 Delegate 호출을 위한 전역함수를 선언합니다

 

그리고 Soket 통신을 위한 구문을 작성하죠.

private byte[] RcvBuf = new byte[4096];
byte[] sndBuf = new byte[12];

using(Socket socket = new Socket(AddressFamily.interNetwork, SocketType.Stream, ProtocolType.Tcp))
{
	EndPoint plcEP = new IPEndPoint(IPAddress.Parse("IP주소"), 포트번호);
    
    socket.Connect(plcEP);
    socket.Send(sndBuf);
    
    //Delegate 사용
    if(OnSendToRFID != null)
    	OnSendToRFID(CurCmd, SndBuf, 12, DumpBytes(sndBuf, 12));
        
    int nRecv = 0;
    
    nRecv = socket.Receive(RcvBuf);
    
    //Delegate 사용
    if(OnReceiveFromRFID != null)
    	OnReceiveFromRFID(CurCmd, RcvBuf, nRecv, DumpBytes(RcvBuf, nRecv));
    
    socket.Close();
}

 

운영 원리는 다음과 같습니다 Socket으로 접속하여 송신 응답 메세지를 보낸뒤 대리자를 선언하여 대리자가 null이 아닐때까지 By Psss 되고 null이 아닌 값이 들어오게 되면 대리자를 호출하여 처리 요청을 한뒤 바로 다름 응답코드를 수신할 수 있도록 운영합니다.

 

해당 글은 필자가 개인적인 코딩 연습을 위한 구현이므로 실제 정의와는 다른 의미가 있을 수 있으니

 

참고하시기 바랍니다

 

반응형

+ Recent posts