简体   繁体   中英

How to get handle for menu items of an application running in the back ground from an application in C#

I am working on a application, which would be the face of lot of other tools running in background. I am facing an issue. During the launch of a background application ,it needs to load a specific file(file-->load--> file name).

Let the front end application be Fapp and the background application be Bapp . Is it possible for Fapp to get the handle of Bapp's menu item and trigger the load function. I am able to get the handle for buttons but not able to do the same for menu items.

Now we are achieving this using AutoIt, I am trying to achieve this in C# itself.

After you have obtained the handle of the window that you want to invoke its menus, then you may use

  • HMENU GetMenu(HWND) windows api to get menu
  • HMENU GetSubMenu(HMENU, int) to get to the file menu and again to open menu.
  • BOOL GetMenuItemInfo( ... ) to get info about menu
  • and you can use PostMessage((IntPtr)hWnd, WM_COMMAND, 0, ID_MENU_ITEM); ( related post ) to perform a click on that item.

all these apis are what AutoIt calls (I think). This solution works if your Bapp is a normal windows application with a normal windows menu, not a fancy WPF app, or a ribbon. If this is the case, then what you see as menu probably is not a menu (technically anyway)

Are you sure this is the right way to get two applications talking to each other?

If you don't have source code for BApp, and it also doesn't have an API that you can use, then pretending to be an interactive user could be the only way to interact with it. Just be aware that it is fraught with issues, consider what will happen when

  • BApp isn't already running
  • BApp has a modal dialog open
  • BApp is in the middle of an operation (or hanging) and its menu is disabled
  • BApp is updated to a new version and its UI changes
  • An interactive user changes focus, in the middle of an operation.

An alternative to this would be to do the same thing that you do when you are unit testing an application with a UI. This is because you are doing the same thing, automating an application by making calls that execute its functions, in this case to test the results are as expected. Since this is a WPF post lets assume that you are writing an application with MVVM, and the best way (to avoid brittleness when we are change the UI) is to ignore the UI (View) and call the layer that sits underneath ie the VM (ViewModel).

In fact its quite easy just to add a self-hosted WCF connection inside your BApp application so that it can be called externally.

        this._host = new ServiceHost(service);
        this._host.AddServiceEndpoint(typeof(IContract), new NetTcpBinding(), address);
        this._host.Open();

This would then enable you to get the two talking totally independently.

If your Bapp is able to somehow invoke Win32 API - then this can be achieved by sending a custom WM_USER message to your Fapp - using SendMessage() . In your Fapp you handle this message and take appropriate action.

I don't think getting handle to a control and invoking its handler is the right way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM