来自Windows服务的PostMessage

时间:2018-05-29 05:41:51

标签: c# winapi windows-services

我的问题是PostMessage windows API在从控制台应用程序运行时无法正常工作。

工作代码:

我有2个应用程序[1]是控制台应用程序[2] Windows窗体应用程序。

要求是我想向所有正在运行的应用程序实例发送消息。

控制台应用程序代码:

class Program
{
    #region Dll Imports
    public const int HWND_BROADCAST = 0xFFFF;

    [DllImport("user32.dll")]
    public static extern bool SetForegroundWindow(IntPtr hWnd);

    [DllImport("user32")]
    public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);

    [DllImport("user32")]
    public static extern int RegisterWindowMessage(string message);
    #endregion Dll Imports

    public static readonly int WM_ACTIVATEAPP = RegisterWindowMessage("CLOSE");

    static void Main(string[] args)
    {
            //we tried to create a mutex, but there's already one (createdNew = false - another app created it before)
            //so there's another instance of this application running
        Process currentProcess = Process.GetCurrentProcess();

        //get the process that has the same name as the current one but a different ID
        foreach (Process process in Process.GetProcessesByName("ClientApp1"))
        {
            if (process.Id != currentProcess.Id)
            {
                IntPtr handle = process.MainWindowHandle;

                //if the handle is non-zero then the main window is visible (but maybe somewhere in the background, that's the reason the user started a new instance)
                //so just bring the window to front
                //if (handle != IntPtr.Zero)
                    //SetForegroundWindow(handle);
                //else
                    //tough luck, can't activate the window, it's not visible and we can't get its handle
                    //so instead notify the process that it has to show it's window
                    PostMessage((IntPtr)HWND_BROADCAST, WM_ACTIVATEAPP, IntPtr.Zero, IntPtr.Zero);//this message will be sent to MainForm

                break;
            }
        }

    }
}

Windows窗体应用程序代码:

 public partial class Form1 : Form
{
    #region Dll Imports
    public const int HWND_BROADCAST = 0xFFFF;

    [DllImport("user32.dll")]
    public static extern bool SetForegroundWindow(IntPtr hWnd);

    [DllImport("user32")]
    public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);

    [DllImport("user32")]
    public static extern int RegisterWindowMessage(string message);
    #endregion Dll Imports

    public static readonly int WM_ACTIVATEAPP = RegisterWindowMessage("CLOSE");

    public Form1()
    {
        InitializeComponent();
    }

    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
        //someone (another process) said that we should show the window (WM_ACTIVATEAPP)
        if (m.Msg == WM_ACTIVATEAPP)
            this.Close();
    }
}

上面的代码按预期工作。

我的问题从这里开始。我想从Windows服务而不是控制台应用程序运行相同的代码。需要立即指导。

似乎当我从Windows服务运行此代码时,它没有获取进程或服务在不同的帐户中运行,因此消息无法传递。

1 个答案:

答案 0 :(得分:5)

很可能您在会话0中将您的服务作为本地系统帐户运行,并且由于充分的理由而相当孤立。例如,您无权访问其他桌面/会话。

您必须实施不同的IPC方法,例如管道或内存映射文件。