-->

How to receive simplest Windows message on UWP XAM

2019-06-18 23:30发布

问题:

My big-picture problem: I need to send a signal from a Windows 10 desktop app (or a service, really) to a UWP XAML MVVM app on the same OS instance / machine.

I was using named semaphores in the global namespace, but these don't work at all on UWP (by design, for security reasons maybe). No joy.

I tried UWP sockets, and this works with the UWP as listener only if the client is on a remote machine. Is this a security design decision, too? No idea. Exempting the app from loopback restriction does not help, since that only applies if the UWP app is the client making the request. No joy.

OK, so I'm left with sending a Windows message to the specific window on the OS...

My test app is the AdventureWorks sample for UWP on GitHub. How do I get this to handle a Windows message sent from a different process? I'm stumped.

Below is my test client code.

QUESTION: How do I handle this message in AdventureWorks? It's important to keep code changes to a minimum, but currently I'm stuck and have no idea to proceed. (It seems to be a tightly-held secret...)

Please help! Sample code please.

class Program
{
    [DllImport("user32.dll")]
    public static extern IntPtr FindWindow(string lpClassName, String lpWindowName);

    [DllImport("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, uint wMsg, IntPtr wParam, IntPtr lParam);

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern uint RegisterWindowMessage(string lpString);

    [DllImport("kernel32.dll")]
    static extern uint GetLastError();

    static void Main(string[] args)
    {
        const string lpClassName = "ApplicationFrameWindow";
        const string lpWindowName = "AdventureWorks.Shopper";
        IntPtr hwnd = FindWindow(lpClassName, lpWindowName);

        uint messageId = RegisterWindowMessage("MetaAutomationMessage");


        int sendMessageResult = SendMessage(hwnd, messageId, IntPtr.Zero, IntPtr.Zero);
        Console.WriteLine(string.Format("Message result is '{0}', ", sendMessageResult));

        uint lastError = GetLastError();
        Console.WriteLine(string.Format("GetLastError result is '{0}', ", lastError));
    }
}

回答1:

Windows 10 UWP App service communication can be one of the options to send set of key-values between UWP apps.

Reference: https://msdn.microsoft.com/en-us/windows/uwp/launch-resume/how-to-create-and-consume-an-app-service



回答2:

The UWP app is sandboxed, so you can't send or receive messages, etc. by design to a Win32 app.

There are somewhat potentially less desirable options like enabling loopback communications over a local socket: https://stackoverflow.com/a/33263253/95190 (which maybe is what you tried -- it's not clear).

However a UWP app may not be the best platform choice today if you need to communicate from a locally installed service to your Universal app.

There are some ways of launching an app and providing some data as part of the launch, but a Win32 service should not launch interactive user processes (so, it wouldn't be a good way to pass data either).

You may want to consider building your app as a WPF app if communication with a Win32 app/service is needed.