- [STAThread]
- static void Main()
- {
-
- if (IsExistAnotherInstance())
- return;
-
- Application.EnableVisualStyles();
- Application.SetCompatibleTextRenderingDefault(false);
- Application.Run(new Form1());
- }
-
- private static bool IsExistAnotherInstance()
- {
- bool createdNew;
- Mutex mutex = new Mutex(true, Application.ProductName, out createdNew);
- if (createdNew)
- {
-
- return false;
- }
-
-
- Process[] viewProcesses = Process.GetProcessesByName(Application.ProductName);
- if (null != viewProcesses && 2 == viewProcesses.Length)
- {
- Process view = (viewProcesses[0].Id == Process.GetCurrentProcess().Id) ?
- viewProcesses[1] : viewProcesses[0];
-
- IntPtr hWndOfPrevInstance = view.MainWindowHandle;
- if (Win32.IsIconic(hWndOfPrevInstance))
- Win32.ShowWindowAsync(hWndOfPrevInstance, Win32.SW_RESTORE);
- Win32.SetForegroundWindow(hWndOfPrevInstance);
-
- return true;
- }
- return false;
- }
위 코드에서 사용하고 있는 Win32 클래스의 내용(일부 발췌)- public class Win32
- {
-
-
-
-
-
-
- [DllImport("user32.dll")]
- public static extern bool SetForegroundWindow(IntPtr hWnd);
-
-
-
-
- [DllImport("user32.dll")]
- public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
-
-
-
-
- [DllImport("user32.dll")]
- public static extern bool IsIconic(IntPtr hWnd);
-
-
-
-
- public static int SW_RESTORE = 9;
- }
[이미 실행중인 프로그램에 데이터 전달하기]WM_COPYDATA 메시지를 사용하는 원리프로그램은 ClickOnce 로 배포되고 있고, 웹페이지에서 파라미터를 사용하여 프로그램을 실행시키는 경우라고 가정함.프로그램 실행시 전달된 파라미터 수집 : GetQueryStringParameters()- [STAThread]
- static void Main()
- {
-
- Dictionary<string, string> dicParams = GetQueryStringParameters();
-
-
- if (IsExistAnotherInstance(ref dicParams))
- return;
-
- Application.EnableVisualStyles();
- Application.SetCompatibleTextRenderingDefault(false);
- Application.Run(new Form1());
- }
-
- private static Dictionary<string, string> GetQueryStringParameters()
- {
- Dictionary<string, string> nameValueTable = new Dictionary<string, string>();
-
- try
- {
- if (ApplicationDeployment.IsNetworkDeployed)
- {
- string url = AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData[0];
- string queryString = ApplicationDeployment.CurrentDeployment.ActivationUri.Query;
- if (string.Empty == queryString) return (nameValueTable);
-
- int nIndex = queryString.IndexOf("?");
-
- if (nIndex > -1) queryString = queryString.Remove(nIndex, 1);
- queryString = HttpUtility.UrlDecode(queryString);
- string[] nameValuePairs = queryString.Split('&');
- if (nameValuePairs != null && nameValuePairs.Length > 0)
- {
- foreach (string pair in nameValuePairs)
- {
- string[] vars = pair.Split('=');
- if (!nameValueTable.ContainsKey(vars[0]))
- {
- nameValueTable.Add(vars[0], vars[1]);
- }
- }
- }
- }
- }
- catch (Exception)
- {
- }
-
- return (nameValueTable);
- }
프로그램의 인스턴스가 이미 존재하는지 확인하고 이미 존재하면 해당 인스턴스에게 프로그램 실행시 전달받은 파라미터 문자열을 전달함.- private static bool IsExistAnotherInstance(ref Dictionary<string, string> dicParams)
- {
- bool createdNew;
- Mutex mutex = new Mutex(true, Application.ProductName, out createdNew);
- if (createdNew)
- {
-
- return false;
- }
-
- Process[] viewProcesses = Process.GetProcessesByName(Application.ProductName);
- if (null != viewProcesses && 2 == viewProcesses.Length)
- {
- Process view = (viewProcesses[0].Id == Process.GetCurrentProcess().Id) ?
- viewProcesses[1] : viewProcesses[0];
-
- IntPtr hWndOfPrevInstance = view.MainWindowHandle;
- if (Win32.IsIconic(hWndOfPrevInstance))
- Win32.ShowWindowAsync(hWndOfPrevInstance, Win32.SW_RESTORE);
- Win32.SetForegroundWindow(hWndOfPrevInstance);
-
-
- SendParams(hWndOfPrevInstance, ref dicParams);
-
- return true;
- }
- return false;
- }
-
- private static void SendParams(IntPtr hWndTarget, ref Dictionary<string, string> dicParams)
- {
-
- StringBuilder sb = new StringBuilder();
- foreach (string key in dicParams.Keys)
- {
- if (sb.Length > 0)
- sb.Append("&");
- sb.AppendFormat("{0}={1}", key, dicParams[key]);
- }
-
- if (sb.Length > 0)
- SendArgs(hWndTarget, sb.ToString());
- }
-
- private static void SendArgs(IntPtr hWndTarget, string text)
- {
- Win32.CopyDataStruct cds = new Win32.CopyDataStruct();
- try
- {
- cds.cbData = (text.Length + 1) * 2;
- cds.lpData = Win32.LocalAlloc(0x40, cds.cbData);
- Marshal.Copy(text.ToCharArray(), 0, cds.lpData, text.Length);
- cds.dwData = (IntPtr)1;
- Win32.SendMessage(hWndTarget, Win32.WM_COPYDATA, IntPtr.Zero, ref cds);
- }
- finally
- {
- cds.Dispose();
- }
- }
위 코드에서 사용된 Win32 클래스의 내용(전체)- public class Win32
- {
-
-
-
-
-
-
- [DllImport("user32.dll")]
- public static extern bool SetForegroundWindow(IntPtr hWnd);
-
-
-
-
- [DllImport("user32.dll")]
- public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
-
-
-
-
- [DllImport("user32.dll")]
- public static extern bool IsIconic(IntPtr hWnd);
-
-
-
-
- public static int SW_RESTORE = 9;
-
-
-
-
-
-
-
-
-
- [DllImport("user32.dll")]
- public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, ref CopyDataStruct lParam);
-
- [DllImport("kernel32.dll", SetLastError = true)]
- public static extern IntPtr LocalAlloc(int flag, int size);
-
- [DllImport("kernel32.dll", SetLastError = true)]
- public static extern IntPtr LocalFree(IntPtr p);
-
- public const int WM_COPYDATA = 0x004A;
-
- public struct CopyDataStruct : IDisposable
- {
- public IntPtr dwData;
- public int cbData;
- public IntPtr lpData;
-
- public void Dispose()
- {
- if (this.lpData != IntPtr.Zero)
- {
- LocalFree(this.lpData);
- this.lpData = IntPtr.Zero;
- }
- }
- }
- }
프로그램의 메인폼에서는 WM_COPYDATA 메시지를 처리함.- public partial class Form1 : Form
- {
- public Form1()
- {
- InitializeComponent();
- }
-
- protected override void WndProc(ref Message m)
- {
- switch (m.Msg)
- {
- case Win32.WM_COPYDATA:
- Win32.CopyDataStruct st = (Win32.CopyDataStruct)Marshal.PtrToStructure(m.LParam, typeof(Win32.CopyDataStruct));
- string strData = Marshal.PtrToStringUni(st.lpData);
- textBox1.Text = strData;
- break;
- default:
-
- base.WndProc(ref m);
- break;
- }
- }
- }
OneInstanceAndParameterExecute.zip
출처 : http://iwoohaha.tistory.com/90