当前位置:编程学习 > C#/ASP.NET >>

C#中如何创建共享内存,然后进程之间通信?

C#中如何创建共享内存,然后进程之间通信?
最好能有实例代码. --------------------编程问答-------------------- 可以用AutoResetEvent类 --------------------编程问答-------------------- 进程之间的通讯倒是一个比较复杂的课题,我没有研究过。
但是可以利用System.Xml.Serialization 把数据对象 序列化成为xml文件,通过文件达到共享数据的目的! --------------------编程问答-------------------- 调用API函数 CreateFileMapping, MapViewOfFile --------------------编程问答-------------------- 关注 --------------------编程问答-------------------- 三个方法吧。
一是共享文件,每个进程都去读写同一个文件,用来实现数据的共享。
二是利用数据库。
三是利用socket,每个进程通过socket来连接,相互发送数据。
--------------------编程问答-------------------- 参考C++的做法 --------------------编程问答-------------------- Mark --------------------编程问答-------------------- 进程间通行最方便是通过消息:WM_COPYDATA --------------------编程问答-------------------- 远程调用也可以 --------------------编程问答-------------------- 使用内存文件的一个例子,在这个例子中,内存文件里存放的是主窗口的句柄.
(ApiShell是我收集Api函数和常量的声明,你可以自行声明.)
static void Main() 
{
    IntPtr hMemoryFile;
    IntPtr hMapView;

    Process current = Process.GetCurrentProcess();
    Process[] processes = Process.GetProcessesByName(current.ProcessName);
    foreach (Process process in processes)
    {
        if (process.Id != current.Id)
        {
            if (process.MainModule.FileName == current.MainModule.FileName)
            {
                hMemoryFile = ApiShell.OpenFileMapping(ApiShell.PAGE_READWRITE, false, process.Id.ToString());
                hMapView = ApiShell.MapViewOfFile(hMemoryFile, ApiShell.FILE_MAP_READ, 0, 0, 8);
                IntPtr hwnd = Marshal.ReadIntPtr(hMapView);
                ApiShell.UnmapViewOfFile(hMapView);
                ApiShell.CloseHandle(hMapView);
                ApiShell.ShowWindow(hwnd, ApiShell.SW_SHOWNORMAL);
                ApiShell.UpdateWindow(hwnd);
                return;
            }
        }
    }

    Form1 frm = new Form1();

    hMemoryFile = ApiShell.CreateFileMapping(ApiShell.INVALID_HANDLE_VALUE, IntPtr.Zero, ApiShell.PAGE_READWRITE, 0, 8, current.Id.ToString());
    hMapView = ApiShell.MapViewOfFile(hMemoryFile, ApiShell.FILE_MAP_WRITE, 0, 0, 8);
    Marshal.WriteIntPtr(hMapView, frm.Handle);
    ApiShell.UnmapViewOfFile(hMapView);
    ApiShell.CloseHandle(hMapView);

    Application.Run(frm);

    ApiShell.CloseHandle(hMemoryFile);
}
--------------------编程问答-------------------- 进程间通讯用IPC啊。如果你愿意用.NET 3.0  WCF,那是最简单的,用NamedPipeBinding就好了 --------------------编程问答-------------------- .net上用管道通讯,Remoting。
--------------------编程问答--------------------
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace ShareMemLib
{
    public class ShareMem
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, IntPtr lParam);

        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr CreateFileMapping(int hFile, IntPtr lpAttributes, uint flProtect, uint dwMaxSizeHi, uint dwMaxSizeLow, string lpName);
        
        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr OpenFileMapping(int dwDesiredAccess,[MarshalAs(UnmanagedType.Bool)] bool bInheritHandle,string lpName);

        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr MapViewOfFile(IntPtr hFileMapping,uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow,uint dwNumberOfBytesToMap);

        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        public static extern bool UnmapViewOfFile(IntPtr pvBaseAddress);

        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        public static extern bool CloseHandle(IntPtr handle);

        [DllImport("kernel32", EntryPoint="GetLastError")]
        public static extern int GetLastError ();

        const int ERROR_ALREADY_EXISTS = 183;

        const int FILE_MAP_COPY = 0x0001;
        const int FILE_MAP_WRITE = 0x0002;
        const int FILE_MAP_READ = 0x0004;
        const int FILE_MAP_ALL_ACCESS = 0x0002 | 0x0004;

        const int PAGE_READONLY = 0x02;
        const int PAGE_READWRITE = 0x04;
        const int PAGE_WRITECOPY = 0x08;
        const int PAGE_EXECUTE = 0x10;
        const int PAGE_EXECUTE_READ = 0x20;
        const int PAGE_EXECUTE_READWRITE = 0x40;

        const int SEC_COMMIT = 0x8000000;
        const int SEC_IMAGE = 0x1000000;
        const int SEC_NOCACHE = 0x10000000;
        const int SEC_RESERVE = 0x4000000;

        const int INVALID_HANDLE_VALUE = -1;

        IntPtr m_hSharedMemoryFile = IntPtr.Zero;
        IntPtr m_pwData = IntPtr.Zero;
        bool m_bAlreadyExist = false;
        bool m_bInit = false;
        long m_MemSize=0;

        public ShareMem()
        {
        }
        ~ShareMem()
        {
            Close();
        }

        /// <summary>
        /// 初始化共享内存
        /// </summary>
        /// <param name="strName">共享内存名称</param>
        /// <param name="lngSize">共享内存大小</param>
        /// <returns></returns>
        public int Init(string strName, long lngSize)
        {
            if (lngSize <= 0 || lngSize > 0x00800000) lngSize = 0x00800000;
            m_MemSize = lngSize;
            if (strName.Length > 0)
            {
                //创建内存共享体(INVALID_HANDLE_VALUE)
                m_hSharedMemoryFile = CreateFileMapping(INVALID_HANDLE_VALUE, IntPtr.Zero, (uint)PAGE_READWRITE, 0, (uint)lngSize, strName);
                if (m_hSharedMemoryFile == IntPtr.Zero)
                {
                    m_bAlreadyExist = false;
                    m_bInit = false;
                    return 2; //创建共享体失败
                }
                else
                {
                    if (GetLastError() == ERROR_ALREADY_EXISTS)  //已经创建
                    {
                        m_bAlreadyExist = true;
                    }
                    else                                         //新创建
                    {
                        m_bAlreadyExist = false;
                    }
                }
                //---------------------------------------
                //创建内存映射
                m_pwData = MapViewOfFile(m_hSharedMemoryFile, FILE_MAP_WRITE, 0, 0, (uint)lngSize);
                if (m_pwData == IntPtr.Zero)
                {
                    m_bInit = false;
                    CloseHandle(m_hSharedMemoryFile);
                    return 3; //创建内存映射失败
                }
                else
                {
                    m_bInit = true;
                    if (m_bAlreadyExist == false)
                    {
                        //初始化
                    }
                }
                //----------------------------------------
            }
            else
            {
                return 1; //参数错误     
            }

            return 0;     //创建成功
        }
        /// <summary>
        /// 关闭共享内存
        /// </summary>
        public void Close()
        {
            if (m_bInit)
            {
                UnmapViewOfFile(m_pwData);
                CloseHandle(m_hSharedMemoryFile);
            }
        }

        /// <summary>
        /// 读数据
        /// </summary>
        /// <param name="bytData">数据</param>
        /// <param name="lngAddr">起始地址</param>
        /// <param name="lngSize">个数</param>
        /// <returns></returns>
        public int Read(ref byte[] bytData, int lngAddr, int lngSize)
        {
            if (lngAddr + lngSize > m_MemSize) return 2; //超出数据区
            if (m_bInit)
            {               
                Marshal.Copy(m_pwData, bytData, lngAddr, lngSize);
            }
            else
            {
                return 1; //共享内存未初始化
            }
            return 0;     //读成功
        }

        /// <summary>
        /// 写数据
        /// </summary>
        /// <param name="bytData">数据</param>
        /// <param name="lngAddr">起始地址</param>
        /// <param name="lngSize">个数</param>
        /// <returns></returns>
        public int Write(byte[] bytData, int lngAddr, int lngSize)
        {
            if (lngAddr + lngSize > m_MemSize) return 2; //超出数据区
            if (m_bInit)
            {
                Marshal.Copy(bytData, lngAddr, m_pwData, lngSize);
            }
            else
            {
                return 1; //共享内存未初始化
            }
            return 0;     //写成功
        }
    }
}
--------------------编程问答-------------------- 路过学习~
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,