views:

121

answers:

3

I'm writing a little WPF utility to manage entries in the hosts file for dev purposes. As you might know the hosts file is protected by the newer OSs (Win 7/2008/Vista).

I've added a manifest to my application to set the requestedExecutionLevel to "requireAdministrator", as detailed here (using "the easy way") and in the related question here.

Unfortunately this has not worked for me. There is no elevation prompt when I start the app, and calling File.AppendText for the hosts file still causes a System.UnauthorizedAccessException to be thrown: "Access to the path 'C:\Windows\System32\drivers\etc\hosts' is denied."

HostsChanger.exe.manifest:

<?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="HostsChanger" type="win32"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
        <requestedPrivileges>
            <requestedExecutionLevel level="requireAdministrator"/>
        </requestedPrivileges>
    </security>
</trustInfo>
</assembly>

Any ideas?

A: 

I'm not sure if it'll make any difference but your manifest snippet is slightly different from my understanding of how it should be (though that might be different versions):

<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
   <assemblyIdentity version="1.0.0.0" name="HostsChanger" />
   <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
      <security>
         <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
            <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
         </requestedPrivileges>
      </security>
   </trustInfo>
</asmv1:assembly>

Otherwise, a work around might be to have a separate "Loader" app that the user starts with and that only starts your real WPF tool using the Verb runas as detailed in this blog post (so Process.StartInfo.Verb = "runas";).

ho1
Unfortunately your manifest snippet didn't work either. I had thought to start a new process with the runas verb whenever a change to the hosts file is needed - but this would severly impact the usability of the app for user with UAC enabled (ie: it would be downright annoying). One UAC prompt at start would be better. No offence, but a loader app is a hack and I'd rather avoid it, but thanks for the input.
bszom
So, that's EXACTLY how the manifest looks for app I'm working on at work, and elevation is working for it. The difference here may be that the filename is "app.manifest", and the project option "Manifest" (on the Application tab) is pointing to it.
Merlyn Morgan-Graham
I do have my project properties set to the manifest file. I'll try renaming it to app.manifest... though that seems hopeful. So you get the prompt on start of the application? Is it WPF? My app is windowless (trayicon and WPF user-control only), could that be a factor?
bszom
Renaming to app.manifest did the trick - wow. If you want to post that as an answer I'll mark it accordingly. Thanks for the tip.
bszom
@bszom: Since you're just replying to a comment you'll have to add @username (or at least part of the username) to your comment to make sure he'll see it. So if you add @Merlyn to your comment he'll be notified I think.
ho1
@Merlyn Morgan-Graham - you were right! see above :)
bszom
@ho1 - Thanks for the heads up :) Yes, I didn't see it until you did @.
Merlyn Morgan-Graham
+1  A: 

I am going to take a stab in the dark here and say that it is an authenticode signature issue. I have not heard you mention anything about signing your application. As far as my understanding goes, unlike Vista, in Windows 2008/7 the only way to run an application elevated is to have a signed application manifest that identifies the privilege level that the application needs. If you need help signing, here's an article on how to sign your application: http://msdn.microsoft.com/en-us/library/bb756995.aspx

Paranoid Android
Also assuming you've already followed this workflow but going to provide here for reference or checklist: http://msdn.microsoft.com/en-us/library/bb756973.aspx
Paranoid Android
Well after renaming to app.manifest, VS notifies that it must be run as administrator in order to debug (as expected; see the 1st link I posted). The app now has write access to the hosts file. In other words: elevation now works correctly, even with an unsigned app. I think the advantage of signing is that no user-intervention is required to elevate, but that's just an assumption. Thanks for the info!
bszom
+1  A: 

Paraphrased from my earlier comment, turned into an answer:

The answer ho1 gave contains an app.manifest that is exactly the same as the app I'm working on at work, and elevation is working for it. The difference here is that the filename is "app.manifest", and the project option "Manifest" (on the Application tab) is pointing to it.

Merlyn Morgan-Graham