Reputation: 73
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.
Upvotes: 0
Views: 1708
Reputation: 1836
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.
Upvotes: 6