0

My issue is PostMessage windows API is not working properly as it works when running from console application.

Working code:

I have 2 application [1] is console application [2] Windows Forms application.

Requirement is I want to send message to all the running instances of application.

console application code:

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 Forms application code:

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

Above code is working as expected.

My issues start from here. I want to run the same code from windows service instead of console application. Need immediate guidance.

It seems when I run this code from windows service its not getting hold of the process or service runs in different account so message is not getting delivered.

3
  • PostMessage works correctly and as designed. Your expectations are wrong. You can't send windows messages between different desktops. And your service is isolated in session 0. Commented May 29, 2018 at 8:14
  • 1
    "You can't send window messages between different sessions, or between different desktops of the same session." Commented May 29, 2018 at 19:53
  • I need not to have message between different desktop. I want to send from the windows service in the same desktop. Commented May 30, 2018 at 4:47

1 Answer 1

6

Most probably you run your service as Local System account in session 0 and it is rather isolated for good reasons. For example you don't have access to other desktops/sessions.

You have to implement a different IPC method, e.g. pipes or memory mapped files.

Sign up to request clarification or add additional context in comments.

2 Comments

Yes you are right. Both the processes are in different sessions so not able to send message.
I found working example that is suitable for the problem faced by me. Refer "Non-Persisted Memory-Mapped Files example " from this URL : learn.microsoft.com/en-us/dotnet/standard/io/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.