I found that one has to us process shared memory when communicating with windows OS toolbars; I thought this only applied when reading back structs in a SendMessage. Below is update of my code. I do not get any errors this time, but nothing happens. No registry key value is created, nothing. I probably need someone with PInvoke experience to OK my code ot NOT. That would help. // get toolbar handle IntPtr hWndToolBar = TrayIcons.GetIconTrayWnd(); // get handle to other process // open process for all access or get access denied error int processID = 0; int threadID = Win32ProcessThread.GetWindowThreadProcessId( hWndToolBar, ref processID); IntPtr hProcess = Win32ProcessThread.OpenProcess( Win32Const.PROCESS_ALL_ACCESS, false, processID); // set up shared memory for struct // make it big enough to hold dynamic data int bufferSize = 16000; IntPtr hGlobalBuffer = Win32Memory.VirtualAllocEx( hProcess, IntPtr.Zero, bufferSize, Win32Const.MEM_RESERVE | Win32Const.MEM_COMMIT, Win32Const.PAGE_READWRITE); // allocate local memory to hold struct IntPtr hLocalBuffer = Marshal.AllocHGlobal(bufferSize); // set up save struct Win32Struct.TBSAVEPARAMS tbSaveParams = new Win32Struct.TBSAVEPARAMS(); string regKey = @"SOFTWARE\TEST"; tbSaveParams.hkr = (UIntPtr)Win32Const.HKEY_LOCAL_MACHINE; tbSaveParams.pszSubKey = regKey; tbSaveParams.pszValueName = "IconsBackup"; // convert struct to pointer Marshal.StructureToPtr(tbSaveParams, hLocalBuffer, false); // put struct in place Win32Memory.WriteProcessMemory(hProcess, hGlobalBuffer, hLocalBuffer, bufferSize, 0); // save tray icon state // no return value Win32Windows.SendMessage(hWndToolBar, (uint)Win32Const.TB_SAVERESTOREA, true, hLocalBuffer); // clean up Win32Memory.VirtualFreeEx(hProcess, hGlobalBuffer, bufferSize, Win32Const.MEM_RELEASE); Marshal.FreeHGlobal(hLocalBuffer); Win32ProcessThread.CloseHandle(hProcess);