C# найти уже запущенный дескриптор окна экземпляра приложения для HWND_BROADCAST - PullRequest
0 голосов
/ 17 апреля 2020

Я новичок в C# и IP C, пытаюсь создать приложение, которое является единичным экземпляром, и когда другой процесс пытается запустить его, просыпается уже запущенный экземпляр приложения и передает ему args. Все работает в соответствии с моими потребностями. Но одна проблема заключается в том, что я не знаю, как установить дескриптор назначения в program.cs, поэтому он только отправляет сообщение в приложение назначения. в настоящее время он вещает в глобальном масштабе, и другое программное обеспечение (мини-приложение), которое также прослушивает HWND_BROADCAST, получает его и активирует. Мой уже запущенный экземпляр также слушает его. Я хочу установить целевой дескриптор для (IntPtr)NativeMethods.HWND_BROADCAST

static Mutex mutex = new Mutex(true, "mutex-unique-string-id");
[STAThread]
static void Main(string[] args)
{
    if (mutex.WaitOne(TimeSpan.Zero, true))
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        if (args.Length == 0)
        {
            Application.Run(new MainForm(null));
        }
        else
        {
            Application.Run(new MainForm(args[0]));
        }
        mutex.ReleaseMutex();
    }
    else
    {
        if (args.Length == 0)
        {
            SendMessageClass.SendMessageWithDataUsingHGlobal((IntPtr)NativeMethods.HWND_BROADCAST, "", IntPtr.Zero);
        }
        else
        {
            SendMessageClass.SendMessageWithDataUsingHGlobal((IntPtr)NativeMethods.HWND_BROADCAST, args[0], IntPtr.Zero);
        }
    }
}

SendMessageClass

    public class SendMessageClass
    {

        [System.Runtime.InteropServices.DllImport("user32.dll",CharSet = CharSet.Auto)]
        public static extern IntPtr SendMessage(System.IntPtr hwnd, int msg,
        IntPtr wparam, IntPtr lparam);

        const int WM_COPYDATA = 0x4A;
        const int WM_CLOSE = 0x0010;

    public static void SendMessageWithDataUsingHGlobal(IntPtr destHandle, string str, IntPtr srcHandle)
    {
        COPYDATASTRUCT cds;

        cds.dwData = srcHandle;
        str = str + '\0';

        cds.cbData = str.Length + 1;
        cds.lpData = Marshal.AllocHGlobal(str.Length);
        cds.lpData = Marshal.StringToHGlobalAnsi(str);
        IntPtr iPtr = Marshal.AllocHGlobal(Marshal.SizeOf(cds));
        Marshal.StructureToPtr(cds, iPtr, true);

        // send to the MFC app
        SendMessage(destHandle, WM_COPYDATA, srcHandle, iPtr);

        // Don't forget to free the allocatted memory 
        Marshal.FreeCoTaskMem(cds.lpData);
        Marshal.FreeCoTaskMem(iPtr);
    }
}

WndPro c

    protected override void WndProc(ref Message m)
    {
        switch (m.Msg)
        {
            // program receives WM_COPYDATA Message from target app
            case WM_COPYDATA:
                if (m.Msg == WM_COPYDATA)
                {
                    // get the data
                    COPYDATASTRUCT cds = new COPYDATASTRUCT();
                    cds = (COPYDATASTRUCT)Marshal.PtrToStructure(m.LParam, typeof(COPYDATASTRUCT));
                    if (cds.cbData > 0)
                    {
                        byte[] data = new byte[cds.cbData];
                        Marshal.Copy(cds.lpData, data, 0, cds.cbData);
                        Encoding unicodeStr = Encoding.ASCII;
                        MessageBox.Show(new string(unicodeStr.GetChars(data)), "Received");
                    }
                }
                break;
        }
        base.WndProc(ref m);
    }
...