c# 调用win32 API

[DllImport("User32.dll")]
        public static extern int MessageBox(int h, string m, string c, int type);

        static int TestWinApi()
        {
            MessageBox(0, "Hello Win32 Api", "peter", 4);
            Console.ReadLine();
            return 0;
        }

C#


sender

using System;
using System.Collections.Generic;
using System.Text;
using NamedPipeLib;
using System.Runtime.InteropServices;

namespace Client
{
    /// <summary>
    /// Sender(Client)
    /// </summary>
    class Program
    {

        static void Main(string[] args)
        {
            // 定义管道的名字
            string pipeName = "\\\\.\\pipe\\MyPipe";

            while (true)
            {
                Console.WriteLine("input:");

                string msg = Console.ReadLine();

                if (msg == "EXIT")
                    break;

                #region  package infomation

                    //定义转换类的一个对象并初始化

                    Converter Convert = new Converter();

                    //定义消息结构体

                    MyMessage m;
                    //初始化消息结构体

                    m = new MyMessage(msg);

                    m.cmd_type = 1633837924;

                    m.srcID = 1633837925;

                    m.dstID = 1633837926;

                    //使用转换类的对象的StructToBytes方法把m结构体转换成Byte

                    Byte[] msgBuffer = Convert.StructToBytes(m);

                #endregion

                IntPtr fileHandle;

                while (true)
                {
                    // 创建命名管道
                    fileHandle = NamedPipeNative.CreateFile(pipeName,
                        NamedPipeNative.GENERIC_READ | NamedPipeNative.GENERIC_WRITE,
                        0, null, NamedPipeNative.OPEN_EXISTING, 0, 0);

                    // 创建失败时,跳出循环
                    if (fileHandle.ToInt32() != NamedPipeNative.INVALID_HANDLE_VALUE)
                    {
                        break;
                    }

                    // 无法打开管道时,不再执行下面的操作
                    if (NamedPipeNative.GetLastError() != NamedPipeNative.ERROR_PIPE_BUSY)
                    {
                        Console.WriteLine("pipe is busing");
                        return;
                    }
                    if (!NamedPipeNative.WaitNamedPipe(pipeName, 20000))
                    {
                        Console.WriteLine("can't open pipe");
                        return;
                    }
                }

                uint pipeMode = NamedPipeNative.PIPE_READMODE_MESSAGE;

                bool success = NamedPipeNative.SetNamedPipeHandleState(fileHandle, ref pipeMode, IntPtr.Zero, IntPtr.Zero);

                if (!success)
                {
                    Console.WriteLine("设置管道状态失败");
                    return;
                }

                // 定义信息的长度
                uint len = (uint)msgBuffer.Length;

                byte[] numReadWritten = new byte[4];

                // 把数据写到管道
                success = NamedPipeNative.WriteFile(fileHandle, BitConverter.GetBytes(len), 4, numReadWritten, 0);

                // 写入数据失败时的处理
                if (!success)
                {
                    Console.WriteLine("写入数据失败");
                    return;
                }
                else
                {
                    NamedPipeNative.WriteFile(fileHandle, msgBuffer, len, numReadWritten, 0);
                }

                // 关闭打开的管道
                NamedPipeNative.CloseHandle(fileHandle);
            }
        }
    }
}

reveiver


using System;
using System.Collections.Generic;
using System.Text;
using NamedPipeLib;
using System.Threading;

namespace Server
{
    /// <summary>
    /// Receive(Server)
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            while (true)
            {
                // 实例化跨网通讯,双向的可靠的管道
                IntPtr pipeHandle = NamedPipeNative.CreateNamedPipe(
                             "\\\\.\\pipe\\MyPipe",
                             NamedPipeNative.PIPE_ACCESS_DUPLEX,
                             NamedPipeNative.PIPE_TYPE_MESSAGE | NamedPipeNative.PIPE_READMODE_MESSAGE,
                             NamedPipeNative.PIPE_UNLIMITED_INSTANCES,
                             1024,
                             1024,
                             0,
                             IntPtr.Zero);

                // 返回前一个异常
                uint u = NamedPipeNative.GetLastError();

                // 创建实例失败时,返回INVALID_HANDLE_VALUE
                if (pipeHandle.ToInt32() == NamedPipeNative.INVALID_HANDLE_VALUE)
                {
                    Console.WriteLine("创建管道出错");
                    return;
                }

                // 启用命名管道服务器进程等待一个客户进程连接到命名管道实例。成功时返回true,失败时返回ERROR_PIPE_CONNECTED
                bool connected = NamedPipeNative.ConnectNamedPipe(pipeHandle, null) ? true : (NamedPipeNative.GetLastError() == NamedPipeNative.ERROR_PIPE_CONNECTED);
                
                // 成功启用命名管道服务器进程等待一个客户进程连接到命名管道实例
                if (connected)
                {
                    // 将ReadMessage方法排入队列以便执行,并指定包含该方法所用数据的对象pipeHandle。
                    // 此方法在有线程池线程变得可用时执行。
                    ThreadPool.QueueUserWorkItem(new WaitCallback(ReadMessage), pipeHandle);
                }
                else
                {
                    // 失败时,关闭打开的pipeHandle对象
                    NamedPipeNative.CloseHandle(pipeHandle);
                }
            }
 
        }

        /// <summary>
        /// 读取客户端数据
        /// </summary>
        /// <param name="arg"></param>
        public static void ReadMessage(object arg)
        {
            // 取得管道对象
            IntPtr pipeHandle = (IntPtr)arg;
  
            byte[] numReadWritten = new byte[4];
            byte[] intBytes = new byte[4];

            NamedPipeNative.ReadFile(pipeHandle, intBytes, 4, numReadWritten, 0);

            int len = BitConverter.ToInt32(intBytes, 0);

            byte[] recBuffer=new byte[len];

            NamedPipeNative.ReadFile(pipeHandle, recBuffer, (uint)len, numReadWritten, 0);

            // 取得客户端发送的信息
            //string str=Encoding.UTF8.GetString(recBuffer);

            #region  package infomation
            //定义转换类的一个对象并初始化
            Converter Convert = new Converter();
            MyMessage m = new MyMessage();
            MyMessage mm = (MyMessage)Convert.BytesToStruct(recBuffer, m.GetType());
            Console.WriteLine("1"+mm.cmd_type);
            Console.WriteLine("2"+mm.username);
            Console.WriteLine("3"+mm.srcID);
            Console.WriteLine("4"+mm.dstID);
            #endregion

            // 一个已被某客户端连接的管道句柄在被另一客户通过 ConnectNamedPipe建立连接之前,服务端必须用DisconnectNamedPipe函数对已存在的连接进行强行拆离。
            // 服务端拆离管道会造成管道中数据的丢失,用FlushFileBuffers函数可以保证数据不被丢失。
            NamedPipeNative.FlushFileBuffers(pipeHandle); // 刷新缓冲区的指定文件,并把所有缓冲数据写入到一个文件。
            // 从客户端进程断开以服务器端命名的管道实例
            NamedPipeNative.DisconnectNamedPipe(pipeHandle);
            // 关闭打开的管道对象
            NamedPipeNative.CloseHandle(pipeHandle); 
        }
    }
}

namlib


using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;


namespace NamedPipeLib
{

    public static class NamedPipeNative
    {
        /// <summary>
        /// 3
        /// </summary>
        public const uint PIPE_ACCESS_DUPLEX = 0x00000003;
        /// <summary>
        /// 2
        /// </summary>
        public const uint PIPE_READMODE_MESSAGE = 0x00000002;
        /// <summary>
        /// 4
        /// </summary>
        public const uint PIPE_TYPE_MESSAGE = 0x00000004;
        /// <summary>
        /// 0
        /// </summary>
        public const uint PIPE_WAIT = 0x00000000;

        public const uint PIPE_UNLIMITED_INSTANCES = 255;

        public const int INVALID_HANDLE_VALUE = -1;

        public const ulong ERROR_PIPE_CONNECTED = 535;
        /// <summary>
        /// 1G
        /// </summary>
        public const uint GENERIC_WRITE = (0x40000000);

        /// <summary>
        /// 2G
        /// </summary>
        public const uint GENERIC_READ = (0x80000000);

        public const uint OPEN_EXISTING = 3;

        public const ulong ERROR_PIPE_BUSY = 231;
        
        /// <summary>
        /// 非托管代码调用  把win32要转成c#数据类型
        /// </summary>
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern IntPtr CreateFile(
            String lpFileName,						  // file name
            uint dwDesiredAccess,					  // access mode
            uint dwShareMode,								// share mode
            SecurityAttributes attr,				// SD
            uint dwCreationDisposition,			// how to create
            uint dwFlagsAndAttributes,			// file attributes
            uint hTemplateFile);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern IntPtr CreateNamedPipe(
            String lpName,									// pipe name
            uint dwOpenMode,								// pipe open mode
            uint dwPipeMode,								// pipe-specific modes
            uint nMaxInstances,							// maximum number of instances
            uint nOutBufferSize,						// output buffer size
            uint nInBufferSize,							// input buffer size
            uint nDefaultTimeOut,						// time-out interval
            IntPtr pipeSecurityDescriptor		// SD
            );


        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool ConnectNamedPipe(
            IntPtr hHandle,									// handle to named pipe
            Overlapped lpOverlapped					// overlapped structure
            );


        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool ReadFile(
            IntPtr hHandle,											// handle to file
            byte[] lpBuffer,								// data buffer
            uint nNumberOfBytesToRead,			// number of bytes to read
            byte[] lpNumberOfBytesRead,			// number of bytes read
            uint lpOverlapped								// overlapped buffer
            );


        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool WriteFile(
            IntPtr hHandle,											// handle to file
            byte[] lpBuffer,							  // data buffer
            uint nNumberOfBytesToWrite,			// number of bytes to write
            byte[] lpNumberOfBytesWritten,	// number of bytes written
            uint lpOverlapped								// overlapped buffer
            );


        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool FlushFileBuffers(
            IntPtr hHandle);


        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool DisconnectNamedPipe(
            IntPtr hHandle);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool SetNamedPipeHandleState(
            IntPtr hHandle,
            ref uint mode,
            IntPtr cc,
            IntPtr cd);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool WaitNamedPipe(
            String name,
            int timeout);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool CloseHandle(
            IntPtr hHandle);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern uint GetLastError();

    }

    [StructLayout(LayoutKind.Sequential)]
    public class Overlapped
    {
    }

    [StructLayout(LayoutKind.Sequential)]
    public class SecurityAttributes
    {
    }
}

mymessage


using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace NamedPipeLib
{
    /// <summary>
    /// define struct message
    /// </summary>
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct MyMessage
    {

        public UInt32 cmd_type;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]

        public string username;

        public UInt32 dstID;

        public UInt32 srcID;

        public MyMessage(string s)
        {

            cmd_type = 0;

            username = s;

            dstID = 0;

            srcID = 0;
        }

    }
}

cover


using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace NamedPipeLib
{
    public class Converter
    {
        public Byte[] StructToBytes(Object structure)
        {

            Int32 size = Marshal.SizeOf(structure);

            //Console.WriteLine(size);

            IntPtr buffer = Marshal.AllocHGlobal(size);

            try
            {

                Marshal.StructureToPtr(structure, buffer, false);

                Byte[] bytes = new Byte[size];

                Marshal.Copy(buffer, bytes, 0, size);

                return bytes;

            }

            finally
            {

                Marshal.FreeHGlobal(buffer);

            }

        }

        public Object BytesToStruct(Byte[] bytes, Type strcutType)
        {

            Int32 size = Marshal.SizeOf(strcutType);

            IntPtr buffer = Marshal.AllocHGlobal(size);

            try
            {

                Marshal.Copy(bytes, 0, buffer, size);

                return Marshal.PtrToStructure(buffer, strcutType);

            }

            finally
            {

                Marshal.FreeHGlobal(buffer);

            }

        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值