ShowWindow Function Doesn't Work When Target Application Is Run As Administrator
Asked Answered
C

2

7

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.

Cockerel answered 20/11, 2012 at 7:21 Comment(0)
S
9

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.

Sleepwalk answered 20/11, 2012 at 12:30 Comment(1)
Wow very good information. The one thing that I don't understand is I have another program that I did not write that does the same thing and it works. Is there another method I could use to show/hide the window that doesn't need this workaround?Cockerel
A
1

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.

Austronesia answered 23/8, 2013 at 8:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.