Disabling GUI features of elevated windows program

Viewed 185

I wish to make it so that when a user of my program does a certain action (such as clicking on a button that is in my program's WinForm), the Windows On-Screen Keyboard (osk.exe) launches, but the caveat is that I want the On-Screen Keyboard to launch with a title bar that is disabled or removed—for example, disabling the Minimize button and the Exit/Close button.

My question is if anyone knows of a safe way to do this.

My reasoning is this: I want the windows on-screen keyboard to automatically come up during parts of my program, but we all know Murphy's law: Anything that can go wrong, will go wrong. I don't want the user to be able to easily exit out of the OSK via its GUI half-way through typing. The underlying program itself will know when to close/hide the osk.

I have tried searching for questions with similar problems, and the best that I found was the following, where the question wasn't really answered, but one of the comments says

If you want to avoid the access denied error, you'll need to elevate your process.

I know how to disable the Maximize/Exit/TitleBar/TitleMenu parts of the GUI myself, through previous C# SO questions (thank you!). But the problem is when the process is "auto-elevated" when started. A normal user then doesn't have a way to edit the GUI without themselves being "elevated". And elevation seems to be an all-or-nothing deal; you're either an Administrator, or you're not. Horrible for security if the end user has to run as Administrator!

So I'm pleading for some safe solutions to this: Some way to be able to have a non-admin user be able to see and use an On-Screen Keyboard that doesn't have the Exit or Minimize button enabled. Perhaps there is a way to force another user, that the end-user doesn't have access to, to start and modify the OSK, so that the end-user themselves doesn't have to be privileged. Or a way to escalate the end-user just to have permission for this one specific process. Are privileges like this really all-or-nothing deals?

Additional information: Here are some links to people explaining how to disable certain parts of the GUI of a windows process.

  • remove components such as the Menu Bar of a GUI process.
  • Run an independent application inside a winforms application. For example, here is how you would get rid of the border of a notepad process and embed into a windows form: [DllImport("user32.dll")] static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

    [DllImport("user32.dll")]
    static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
    
    [DllImport("user32.dll", SetLastError = true)]
    private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);
    
    private const int GWL_STYLE = (-16);
    private const int WS_VISIBLE = 0x10000000;
    private const int WS_MAXIMIZE = 0x01000000;
    
    private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
    private const UInt32 SWP_NOSIZE = 0x0001;
    private const UInt32 SWP_NOMOVE = 0x0002;
    private const UInt32 TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE;
    
    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
    
    
    public Form1()
    {
        InitializeComponent();
    
        Process p = System.Diagnostics.Process.Start("notepad");
    
        p.WaitForInputIdle();
        if (p.MainWindowHandle == null)
        {
            MessageBox.Show(this, "hello", "Error");
        }
        SetParent(p.MainWindowHandle, this.Handle);
        SetWindowLong(p.MainWindowHandle, GWL_STYLE, WS_VISIBLE);
    
        MoveWindow(p.MainWindowHandle, 0, 0, this.Width, this.Height, true);
    }
    

This works fine for a program that doesn't require elevation to use. But programs like the On-Screen keyboard, or MMC snap-ins, will give a non-administrative users Access Denied (5) errors when they attempt to use P/Invoke functions on the window, such as SetWindowPos.

0 Answers
Related