Передать сообщение другому exe из exe C # - PullRequest
4 голосов
/ 07 июня 2009

У меня работает два exe, консольные программы на C #. От одного мне нужно сказать второму exe что-то делать? Как я могу это сделать? Я посмотрел на

(Remotable.CommonAssembly)Activator.GetObject(typeof(Remotable.CommonAssembly)

но отсюда я могу вызвать метод CommonAssembly (ссылка на dll), а не exe.

Ответы [ 5 ]

5 голосов
/ 07 июня 2009

Для простых сценариев было бы достаточно простого старого события Windows - программа ожидает сигнала, чтобы что-то сделать.

Создать поток в программе ожидания, которая ожидает события.

//Program 1

EventWaitHandle evt = OpenOrCreateEvent("Global\\MyEvent");
evt.WaitOne(); // this thread will block waiting without wasting CPU cycles, 
               // it will be be signaled from the kernel 
               // when the event is set
DoStuff();


//Program 2

EventWaitHandle evt = OpenOrCreateEvent("Global\\MyEvent");
evt.Set();

Посмотрите на классы EventWaitHandle, ManualResetEvent, AutoResetEvent.

  • Рассмотрите, какая программа собирается создать событие - вы можете попытаться открыть событие из обеих программ, если оно не существует, чем создать его.
  • Префикс имени события «Global \», если одна из программ является службой (и / или выполняется в другом сеансе / пользователе). Иначе это не будет работать на Vista или позже.
  • При создании события может потребоваться установить атрибуты безопасности, чтобы его можно было открывать из других процессов из других сеансов.

Расширенные механизмы IPC, такие как WCF, Remoting, DCOM, CORBA и т. Д., Могут быть лучше, если у вас более сложный протокол связи с различными действиями для запуска, возврата значений и так далее. Для простых случаев (пара) событий Windows будет достаточно.

Примечание Если вам нужно передавать данные между процессами, рассмотрите файлы, отображенные в памяти «Официальные» .NET классы для них будут доступны с .NET 4.0, в настоящее время вы можете использовать http://github.com/tomasr/filemap/tree/master

3 голосов
/ 07 июня 2009

Посмотрите в WCF для межпроцессного взаимодействия в .NET. Существует множество протоколов, доступных для связи на одном и том же компьютере или на удаленном компьютере. Для той же машины я бы порекомендовал проверить именованные каналы или привязку .NET TCP.

Существует небольшая кривая обучения для WCF, но есть множество учебных пособий, и это то, что определенно стоит изучить.

2 голосов
/ 18 июня 2009

Это должно помочь вам ...

[код]

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace TestApp
{
public static class Messenger
{
    public const uint WM_USER = 0x0400;

    public const int MyMessage = 0x00000001;;

    [DllImport("User32.dll")]
    private static extern int RegisterWindowMessage(string lpString);

    [DllImport("User32.dll", EntryPoint = "FindWindow")]
    internal static extern IntPtr FindWindow(String lpClassName, String lpWindowName);

    //For use with WM_COPYDATA and COPYDATASTRUCT
    [DllImport("User32.dll", EntryPoint = "SendMessage")]
    internal static extern int SendMessage(int hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);

    //For use with WM_COPYDATA and COPYDATASTRUCT
    [DllImport("User32.dll", EntryPoint = "PostMessage")]
    internal static extern int PostMessage(int hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);

    [DllImport("User32.dll", EntryPoint = "SendMessage")]
    internal static extern uint SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, int lParam);

    [DllImport("User32.dll", EntryPoint = "PostMessage")]
    internal static extern int PostMessage(int hWnd, int Msg, int wParam, int lParam);

    [DllImport("User32.dll", EntryPoint = "SetForegroundWindow")]
    internal static extern bool SetForegroundWindow(int hWnd);


    //Used for WM_COPYDATA for string messages
    public struct COPYDATASTRUCT
    {
        public IntPtr dwData;
        public int cbData;
        [MarshalAs(UnmanagedType.LPStr)]
        public string lpData;
    }


    internal static int sendWindowsStringMessage(int hWnd, int wParam, string msg)
    {
        int result = 0;

        if (hWnd > 0)
        {
            byte[] sarr = System.Text.Encoding.Default.GetBytes(msg);
            int len = sarr.Length;
            COPYDATASTRUCT cds;
            cds.dwData = (IntPtr)100;
            cds.lpData = msg;
            cds.cbData = len + 1;
            result = SendMessage(hWnd, (int)WM_USER, wParam, ref cds);
        }

        return result;
    }

    internal static uint sendWindowsMessage(IntPtr hWnd, uint Msg, IntPtr wParam, int lParam)
    {
        uint result = 0;

        if (hWnd != IntPtr.Zero)
        {
            result = SendMessage(hWnd, Msg, wParam, lParam);
        }

        return result;
    }

    internal static IntPtr getWindowId(string className, string windowName)
    {
        return FindWindow(className, windowName);
    }
}

}

В вашем методе вызова:

uint result = 0;
IntPtr hWnd = Messenger.getWindowId(null, "MyOtherApp-Window_Title");
result = Messenger.sendWindowsMessage(hWnd, Messenger.WM_USER, Handle, Messenger.MyMessage);

[/ код]

2 голосов
/ 07 июня 2009

Я часто использую MSMQ для этого.

http://www.csharphelp.com/archives3/archive581.html

1 голос
/ 07 июня 2009

Вы могли бы рассмотреть IPC. NamedPipeClientStream и NamedPipeServerStream довольно просты. Вот пример , где IPC используется для передачи аргументов командной строки из одного экземпляра приложения в другой. Это не совсем то, что вы хотите сделать, но довольно близко.

...