C # object transfer methods between processes,
1. Origin
The underlying reconstruction and upgrade of KV project download determine to use an independent process for Media download, so as to achieve the purpose of reusing modules. Therefore, data transmission between independent processes is involved.
Currently, WM_COPYDATA, shared dll, memory ing, and Remoting are used to transmit data between processes. The WM_COPYDATA method is relatively easier, and its usage is everywhere on the Internet.
In addition, the Marshal static class has multiple built-in methods to facilitate data transmission between different processes, such as strings and struct.
What about objects? How to transfer?
2. serialization
Think of Newtonsoft. Json. dll. I prefer Json compared to the built-in XmlSerializer.
So, let's create a Demo solution, which contains two projects: HostApp and ClildApp for data transmission.
3. ChildApp Project
First, I did not extract the shared data separately. As a Demo, I directly write this notebook, and the HostApp references this project to reference the public data type.
Code for data structure:
[StructLayout (LayoutKind. sequential)] public struct COPYDATASTRUCT {public IntPtr dwData; public int cbData; [financialas (UnmanagedType. LPStr)] public string lpData;} public class Person {private string name; private int age; private List <Person> children; public Person (string name, int age) {this. name = name; this. age = age; this. children = new List <Person> ();} public string Name {get {return This. name;} set {this. name = value ;}} public int Age {get {return this. age;} set {this. age = value ;}} public List <Person> Children {get {return this. children ;}} public void AddChildren () {this. children. add (new Person ("liuxm", 9); this. children. add (new Person ("liuhm", 7);} public override string ToString () {string info = string. format ("Name: {0}, age: {1}", this. name, this. age); if (t His. children. Count! = 0) {info + = (this. children. Count = 1 )? "\ R \ n Children:": "\ r \ n Children:"; foreach (var child in this. children) info + = "\ r \ n" + child. toString () ;}return info ;}}
Form code:
public partial class ChildForm : Form { public const int WM_COPYDATA = 0x004A; private IntPtr hostHandle = IntPtr.Zero; Person person = new Person("liujw", 1999); [DllImport("User32.dll", EntryPoint = "SendMessage")] private static extern int SendMessage( IntPtr hWnd, // handle to destination window int Msg, // message int wParam, // first message parameter ref COPYDATASTRUCT lParam // second message parameter ); public ChildForm(string[] args) { InitializeComponent(); if (args.Length != 0) this.hostHandle = (IntPtr)int.Parse(args[0]); } private void btnSubmit_Click(object sender, EventArgs e) { this.person.Name = txtName.Text; int age; this.person.Age = int.TryParse(txtAge.Text, out age) ? age : 0; this.person.AddChildren(); if (this.hostHandle != IntPtr.Zero) { string data = GetPersionStr(); COPYDATASTRUCT cds = new COPYDATASTRUCT(); cds.dwData = (IntPtr)901; cds.cbData = data.Length + 1; cds.lpData = data; SendMessage(this.hostHandle, WM_COPYDATA, 0, ref cds); } } private string GetPersionStr() { return JsonConvert.SerializeObject(this.person); } }
In this way, the data is passed to the HostApp string form in the form button btnSubmit_Click event.
How can I obtain the window handle of the Host Program? Modify the ChildApp's Program. cs Process:
/// <Summary> /// main entry point of the application. /// </Summary> [STAThread] static void Main (string [] args) {Application. enableVisualStyles (); Application. setCompatibleTextRenderingDefault (false); Application. run (new ChildForm (args ));}
3. HostApp Project
Let's call it a host project. Its form code is:
public partial class MainForm : Form { public const int WM_COPYDATA = 0x004A; public MainForm() { InitializeComponent(); } protected override void WndProc(ref Message m) { base.WndProc(ref m); switch (m.Msg) { case WM_COPYDATA: COPYDATASTRUCT copyData = new COPYDATASTRUCT(); Type type = copyData.GetType(); copyData = (COPYDATASTRUCT)m.GetLParam(type); string data = copyData.lpData; RestorePerson(data); break; } } private void RestorePerson(string data) { var person = JsonConvert.DeserializeObject<Person>(data); if (person != null) txtInfo.Text = person.ToString(); } private void btnSubmit_Click(object sender, EventArgs e) { RunChildProcess(); } private void RunChildProcess() { string appPath = Path.GetDirectoryName(Application.ExecutablePath); string childPath = Path.Combine(appPath, "ChildApp.exe"); Process.Start(childPath, this.Handle.ToString()); } }
It is used to receive the string passed back by the sub-process and deserialize it into a Person object using JsonConvert.
Is it easy?
In fact, the WM_COPYDATA string transmission function is used, and Json serialization and deserialization are added to implement object transmission between different processes in c #.
4 ,:
Json reference: http://www.newtonsoft.com/json