I’ve run into this exact same problem 3 times now in one week, so I figure that probably doesn’t bode well and I should attempt to do something about it.

With 3 different pieces of software (one of them ours), the remote control functionality is imperfectly implemented. Let’s see if this sounds familiar to anyone. You are the helpdesk. You attempt to connect to a user’s desktop. You have to elevate an application. When you do, you (the helpdesk who actually has the password) doesn’t see the UAC dialog – instead, the end user (who does not have the password) does. Even if you decide to give the user the password (it happens), you then can’t control or even see the elevated application.

Kind of makes it hard to be a helpdesk when that happens.

Here are the 3 solutions that I have seen to this problem:

  • Do nothing. That’s what our solution did. It just failed every time elevation was involved.
  • Install a service. That’s what company X did. It requires the user to know an admin password, and that’s a problem for my customers
  • Run the application elevated. That’s what company Y did. It requires the user to know an admin password (a problem with my customers), and also won’t allow you to interact with any windows running at System integrity level (so an incomplete solution)

Here’s what I wish all 3 had done:

  • Manifest with uiAccess = true

Now, most people don’t really understand what this is for, and the UAC manifest is typically just a copy/paste affair. But it pays for the remote desktop developer to pay attention to it. For any regular piece of software, you generally want to stay away from it – it’s dangerous, and sidesteps a significant security feature (UIPI). But if you are remoting the desktop, it’s precisely what you want – you need to be able to see everything!

It’s dangerous enough, in fact, that we won’t allow you to set it without digitally signing your application. By default, you also have to have it installed in a secure location (such as Program Files). You can set a group policy to not require a secure location, but there is no option to not require a signature.

However, once set up, it’s really powerful. You’ll be able to remote every possible kind of window – any integrity level at all. No more blank, unresponsive screens. Everything comes across, regardless of integrity level.

You’ll also be able to leverage the group policy that lets you prompt NOT on the secure desktop if you are a UIAccess application – that way you don’t have to lose the defense in depth of using the secure desktop for normal elevation, but you also avoid writing code to remote the secure desktop when your remote desktop application is running.

All in all, you are just full of win.

Now, it’s my job to fix up apps that are written suboptimally, so you may be wondering how I did getting these working?

  • Our application, rather conveniently, used an external manifest. All I had to do was open up the manifest in Notepad, and type four characters (t-r-u-e) in the uiAccess attribute. Done. Now it works great. (Of course, everyone who downloads it will download a new broken one, so they’ll have to text edit it too – clearly we want to work with the team that makes this to fix it on their end, but you aren’t stuck – you can fix it without depending on anyone else.)
  • Company x, the one that used a service (claiming of course that it was UACs fault that they had to do this)? I can’t fix it. They used an internal manifest, which has precedence over any external one I might lay down there. I could extract that manifest with mt.exe, edit it, and then re-inject it, but then I invalidate the digital signature. Remember that this is a non-optional requirement for a uiAccess app! So, there is nothing I can do. I’m trying to contact the vendor.
  • Company y, the one that elevates to admin – this one I didn’t have time to examine – they do a “just in time” install and uninstall, so I couldn’t explore the manifest, but since it’s so transitive it’d be hard for me to do much anyway that would last.

Anyone writing desktop remoting applications, please consider using this. And feel free to contact me if you have questions. I would be delighted to help you.

For the record, here is the corrected manifest for the one I was able to fix:

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1'
 
manifestVersion='1.0'>
  <assemblyIdentity
   version="1.0.0.0"
   processorArchitecture="X86"
   name="Microsoft.FixedUpApp.SupportConsole"
   type="win32"
  />
  <description>Fixed Up App</description>
    <dependency>
      <dependentAssembly>
        <assemblyIdentity type='win32'
         name='Microsoft.Windows.Common-Controls'
         version='6.0.0.0'
        
processorArchitecture='x86'
         publicKeyToken='6595b64144ccf1df'
         language='*'
        />
      </dependentAssembly>
    </dependency>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker"
         uiAccess="true"/>
      </requestedPrivileges>
    </security>
  </trustInfo>
</assembly>