С# найти уже запущенный дескриптор окна экземпляра приложения для HWND_BROADCAST

Я новичок в С# и IPC, пытаюсь создать приложение, которое является единственным экземпляром, и когда другой процесс пытается запустить его, он просыпается уже работающим экземпляром приложения и передает ему 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);
        }
    }
}

Класс SendMessage

    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);
    }
}

Вндпрок

    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);
    }

person aadi1295    schedule 17.04.2020    source источник
comment
Вы должны зарегистрировать общесистемный уникальный идентификатор сообщения с помощью RegisterWindowMessage. Таким образом, процесс может прослушивать сообщения именно с этим идентификатором и игнорировать все другие идентификаторы, которые ему не известны. Если какая-то другая программа все равно реагирует на получение неизвестного идентификатора сообщения, это вина этой программы. Кроме этого, вы можете попробовать использовать EnumWindows и вручную отфильтровать соответствующие целевые окна.   -  person dialer    schedule 17.04.2020
comment
@dialer Спасибо за ответ, я отправляю данные между разными экземплярами, используя WM_COPYDATA. Я обновил вопросы с кодом SendMessageClass и WndProc. Не могли бы вы проверить и помочь мне. Спасибо   -  person aadi1295    schedule 17.04.2020
comment
stackoverflow.com/questions/11923785/   -  person Hans Passant    schedule 17.04.2020
comment
@ aadi1295 aadi1295 Лучше сначала проверьте, подходит ли вам ответ Ганса. Это было бы намного проще. И это также избавит вас от неприятного состояния гонки в вашем текущем коде.   -  person dialer    schedule 17.04.2020
comment
@HansPassant, спасибо за ваш комментарий. Я смотрю на ваш ответ и у меня есть вопрос. Как отправить args в Form1?   -  person aadi1295    schedule 17.04.2020
comment
Используйте eventArgs.CommandLine, передайте его публичному методу Form1.   -  person Hans Passant    schedule 17.04.2020
comment
@HansPassant Я сделал общедоступный метод в Form1, который принимает аргументы, и когда я пытаюсь добавить OnStartupNextInstance, я получаю сообщение об ошибке 'Form' does not contain a definition for 'Form1_New_Instance_Method' and no accessible extension method 'Form1_New_Instance_Method' accepting a first argument of type 'Form' could be found (are you missing a using directive or an assembly reference?)   -  person aadi1295    schedule 17.04.2020
comment
Требуется приведение, ((Form1)this.MainForm).Foo(eventArgs.CommandLine);   -  person Hans Passant    schedule 17.04.2020
comment
@HansPassant Большое спасибо за вашу помощь и доброту. Я использовал грязный подход, и вы изменили все для меня. Пожалуйста, опубликуйте ответ, чтобы я мог его принять. Спасибо. Вы можете просто скопировать свой пример из stackoverflow.com/questions/ 11923785/   -  person aadi1295    schedule 17.04.2020