Question

I am writing a program that shows/hides the window of some target application. I was testing it out earlier and noticed something strange. If I run the target application as Administrator (right-click->Properties, "Compatability" tab, "Run this program as administrator") it doesn't work.

To demonstrate I wrote a simple GUI app called "TargetApplication" and then I wrote the following code to test showing/hiding this application:

class Program
{
  static void Main(string[] args)
  {
    IntPtr windowPtr = FindWindow(null, "TargetApplication");
    ShowWindow(windowPtr, 0); // 0 = Hide            
    Console.WriteLine("The window is now hidden. Press Enter to restore");
    Console.ReadLine();
    ShowWindow(windowPtr, 9); // 9 = Restore
    Console.WriteLine("The window is now restored. Press Enter to exit.");            
    Console.ReadLine();
  }

  [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
  static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

  [DllImport("user32.dll")]
  static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
}

If I start the windowed application without Administrator rights it doesn't work.

Would anyone mind testing this for me? I have uploaded the .exe's for both applications here:

TestShowWindow Download

All you have to do is download them and run TestApplication.exe then run TestShowWindow.exe. You will find that by changing TestApplication.exe to run as Administrator causes ShowWindow to no longer work.

Of course if you don't trust downloading my stuff you can always compile my code and test it on any target application in Windows that you are able to change compatability mode of.

P.S. I am not sure if it makes a difference but I am running Windows 8 Pro. 64-bit.

Était-ce utile?

La solution

This is by design. It is the lesser known twin of UAC, called UIPI or User Interface Privilege Isolation. An un-elevated program cannot commandeer an elevated one. Given the capabilities of UI Automation, this is an obvious counter-measure to stop programs from hijacking the capabilities of an elevated process. A security violation called a shatter attack.

Workarounds are to provide a manifest with uiAccess = true for a program stored in c:\windows or c:\program files and provided with a certificate. And for the target program to call ChangeWindowMessageFilter to allow certain messages to be sent. In your case that ought to be WM_SHOWWINDOW.

Autres conseils

If you don't mind the window acting like you minimized it to the taskbar; You can, generally, show and hide windows from elevated processes by posting WM_SYSCOMMAND with a wParam of SC_RESTORE or SC_MINIMIZE.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top