Recently wrote a simple music player, every time you double-click the music file, will run an instance again, feel not very convenient, just a running instance, so start to solve the problem.
The most common method, of course, is to find the current same process name, if any, then exit without initializing this instance. The method is relatively simple, but effective.
private static bool Foundrunninginstance ()
{
Process currentprocess = process.getcurrentprocess ();
process[] proclist = Process.getprocessesbyname (currentprocess.processname);
foreach (Process proc in proclist)
{
if (Proc. Id! = currentprocess.id)
{
return true;
}
}
return false;
}
public static void Main (string[] args)
{
if (args. Length = = 0)
Application.Run (New MainForm ());
if (args. Length = = 1)
{
if (! Foundrunninginstance ())
Application.Run (New MainForm (Args[0]));
Else
Environment.exit (0);
}
}
This is OK to run, but the problem also comes, if you have run an instance, and then double-click a music file, although no longer run the new instance, but double-click the music is not expected to think of it. Later thinking of Microsoft's media Player as the default player, each time you double-click on a new music file, the already running instance will play the selected music.
What if this effect is achieved?
To let an already running instance accept the new music file path, give running instance a parameter before you double-click to initialize the new instance. As a result, communication between processes is involved. The most common use of the Windows API SendMessage function is to implement interprocess communication. Definition of the SendMessage function:
private static extern int SendMessage (IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
Of the four parameters, the integer is all, but the one that needs to be passed here is a string. It is not possible to use SendMessage to transfer strings directly, but you can send a WM_COPYDATA message that sends custom read-only data, a custom data that is implemented in C # using a struct.
public struct PROCESSCOPYDATASTRUCT
{
public int dwdata; Maybe the four-byte ID you need
public int cbdata;
[MarshalAs (UNMANAGEDTYPE.LPSTR)]//lpdata length of string
public string lpdata; Strings that need to be transferred
}
Here, the definition of the SendMessage function needs to be changed again.
private static extern int SendMessage (IntPtr hWnd, int Msg, IntPtr wParam, ref processcopydatastruct LParam);
MSG the message to be transmitted wm_copydata the defined value: Public const int wm_copydata = 0X004A;
Write here to say a lot of articles irresponsible, such as wm_copydata variables, although the use of the API, can be found, but for the novice is confused, the code set, the error variable is undefined, so a copy and paste, a lot of the article is not to put the actual value, It's irresponsible.
The structure is defined so that the message can be sent. Now go back and modify the Foundrunninginstance method and the main method.
wherein the structure of dwdata, its own definition is: Wm_qingmusic = 0x8888;
private static bool Foundrunninginstance (string musicfile)
{
Process currentprocess = process.getcurrentprocess ();
process[] proclist = Process.getprocessesbyname (currentprocess.processname);
foreach (Process proc in proclist)
{
if (Proc. Id! = currentprocess.id)
{
if (Musicfile = = null) return true;
Processcopydatastruct CopyData;
Copydata.dwdata = Wm_qingmusic;
Copydata.lpdata = Musicfile;
Copydata.cbdata = System.Text.Encoding.Default.GetBytes (musicfile). Length + 1;
SendMessage (Proc. Mainwindowhandle, Wm_copydata, Currentprocess.handle, ref copydata);
return true;
}
}
return false;
}
public static void Main (string[] args)
{
if (args. Length = = 0)
{
if (! Foundrunninginstance (NULL))
Application.Run (New MainForm ());
Else
Environment.exit (0);
}
if (args. Length = = 1)
{
if (! Foundrunninginstance (Args[0]))
Application.Run (New MainForm (Args[0]));
Else
Environment.exit (0);
}
}
Sent here to send a message is done, the rest is to running instance receive the message. Here to reload a method WndProc.
protected override void WndProc (ref Message m)
{
if (m.msg = = Wm_copydata)
{
Processcopydatastruct CopyData = (processcopydatastruct) M.getlparam (typeof (Processcopydatastruct));
Playmusic (Copydata.lpdata); This is the path of the music file that is passed over and can be handled freely.
}
Base. WndProc (ref m); This sentence is still not forgotten.
}
The process of transferring custom structure data between processes is complete. In fact, this is not complicated, trouble can only blame Microsoft to make an API so much, so that people can not remember, check also difficult to check.
interprocess communication-Passing of strings