Developer, Former MVP, now at Microsoft - Best of 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
// SERVER PROCESS //write data private void cmdWrite_Click(object sender, System.EventArgs e) { IntPtr hWnd = Win32Api.CreateEvent(IntPtr.Zero, true, false, "YOUR_NAME_HERE"); // TODO write to reg //e.g. with opennetcf Registry class Win32Api.SetEvent(hWnd); System.Threading.Thread.Sleep(500); Win32Api.CloseHandle(hWnd); } // CLIENT PROCESS private System.Threading.Thread mMonitorThread; private bool mStayAlive; private IntPtr mMonitorHwnd; //read data private void cmdRead_Click(object sender, System.EventArgs e) { mStayAlive = true; mMonitorHwnd = Win32Api.CreateEvent(IntPtr.Zero, true, false, "YOUR_NAME_HERE"); mMonitorThread = new System.Threading.Thread( new System.Threading.ThreadStart( this.MonitorOtherProc)); mMonitorThread.Start(); } // on background thread so make sure we don't // touch GUI controls from here private void MonitorOtherProc(){ while (mStayAlive){ Win32Api.WaitForSingleObject(mMonitorHwnd, -1); if (mStayAlive == false) return; MessageBox.Show("Got data "+ DateTime.Now.ToString(), "TODO read from reg"); // TODO read data from reg Win32Api.ResetEvent(mMonitorHwnd); } } // must call this before closing app - e.g. from Form_Closing public void Shutdown(){ if (mMonitorThread == null) return; mStayAlive = false; Win32Api.SetEvent( mMonitorHwnd); System.Threading.Thread.Sleep(500); Win32Api.CloseHandle( mMonitorHwnd); mMonitorThread = null; }
// BOTH CLIENT & SERVER PROCESS NEED THESE // Returns pointer to shared memory private IntPtr ObtainHandleToSharedMemory(){ const uint PHYS_ADDR =0x80230000;//Make sure this is not used on your platform const int MEM_SIZE = 10; IntPtr hwnd = Win32Api.VirtualAlloc(0, MEM_SIZE, Win32Api.MEM_RESERVE, Win32Api.PAGE_READWRITE|Win32Api.PAGE_NOCACHE); if (hwnd.ToInt32() != 0){ if (Win32Api.VirtualCopy(hwnd, PHYS_ADDR, MEM_SIZE, (Win32Api.PAGE_READWRITE|Win32Api.PAGE_NOCACHE)) == true){ return hwnd; } } MessageBox.Show( Marshal.GetLastWin32Error().ToString(),"Failed"); return IntPtr.Zero; } // Define common structure/class in both client and server e.g. private class SharedMemory{ public byte b1; public byte b2; public char c; public bool flag; public int i; public SharedMemory(bool aFlag){ flag=aFlag; if (aFlag){ b1=1;b2=2;c='!';i=3; }else{ b1=0;b2=0;c=' ';i=0; } } public override string ToString() { return "b1=" + b1.ToString() + ", b2="+b2.ToString() + ", c=" + c + ", i=" + i.ToString(); } } // CLIENT // As in previous example but instead of reading the registry // read the following in MonitorOtherProc IntPtr memHwnd=ObtainHandleToSharedMemory(); if (memHwnd.ToInt32() !=0 ){ SharedMemory sm=new SharedMemory(false); Marshal.PtrToStructure(memHwnd,sm); MessageBox.Show(sm.ToString(),sm.flag.ToString()); } // SERVER // As in previous example but instead of writing to registry // do the following in cmdWrite_Click IntPtr memHwnd=ObtainHandleToSharedMemory(); if (memHwnd.ToInt32() !=0 ){ SharedMemory sm=new SharedMemory(true); Marshal.StructureToPtr(sm,memHwnd,false); }