locked
Detect if a process is running with elevated priviledges RRS feed

  • Question

  • Context: My software targets top-level Windows, so it can move them (SetWindowPlacement et al) using hotkeys. Obviously, if the target window belongs to either an elevated (e.g. VS.NET) or isolated (e.g. IE7) process, the SetWindowPlacement API does nothing.

    I'd like my software to:
    - enable elevating itself (with the UAC prompt) when necessary
    - return to normal priviledge upon user choice

    For this, I need to:
    - detect if a given foreground window belongs to such a process
    - perform elevation of my own process, and later cancel that elevation (if possible)

    How would I do this? Can anyone give me pointers?

    Thanks.
    Thursday, October 18, 2007 5:56 PM

Answers

  • If you set uiaccess=true in your manifest and meet all the other requirements (digital signing, installed in a trusted directory etc) then you should be able to do this without ever requiring elevation. That will probably result in a significantly better user experience than periodically breaking the user's workflow with a UAC dialog.

     

    Friday, October 19, 2007 3:50 PM

All replies

  • If you set uiaccess=true in your manifest and meet all the other requirements (digital signing, installed in a trusted directory etc) then you should be able to do this without ever requiring elevation. That will probably result in a significantly better user experience than periodically breaking the user's workflow with a UAC dialog.

     

    Friday, October 19, 2007 3:50 PM
  • Hurray! Thanks a lot! Such a simple solution.

     

    But the road to making this work was harder than I thought, because the web lacks good examples (or has too many bad examples) of simple manifests.

     

    For the record, here is my working manifest:

     

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <assembly xmlns="urnTongue Tiedchemas-microsoft-com:asm.v1" manifestVersion="1.0">
      <assemblyIdentity version="1.1.3.0" processorArchitecture="X86" name="slimCODE.slimKEYS" type="win32"/>
      <trustInfo xmlns="urnTongue Tiedchemas-microsoft-com:asm.v3">
        <security>
          <requestedPrivileges>
            <requestedExecutionLevel level="asInvoker" uiAccess="true" />
          </requestedPrivileges>
        </security>
      </trustInfo>
    </assembly>

    A few gotchas/infos:

    • You must leave "level" to "asInvoker". No need to set it to "highestAvailable", it will cause your app to require UAC approval (it gets the shield!).
    • In order to embed a manifest in a managed application, you must:
      • Delay sign if you are using a strong name
      • Add a call to "mt.exe" in your post-build steps, somehow like this:
        "D:\Program Files\Microsoft SDKs\Windows\v6.0\Bin\mt.exe" -manifest "$(ProjectDir)Properties\app.manifest" –outputresource:"$(TargetPath)";#1
      • Followed by a call to sn.exe to complete your delayed strong-naming:
        "D:\Program Files\Microsoft SDKs\Windows\v6.0\Bin\sn.exe" -R "$(TargetPath)" "$(ProjectDir)strong_name_file.snk"
    • Your assembly must be digitally signed, or you will get a very nice error message: "A referral was returned from the server".
    • You do NOT need to embed this manifest in your DLLs. Only the main EXE.
    • If you run your application from a folder other than your "Program Files", it will run normally and will be able to target isolated application windows (e.g. IE7) using APis like SetWindowPlacement, but not elevated app windows (e.g. VS.NET). If installed under "Program Files", it works like a charm!

    Thanks a lot!

     

     

     

    Saturday, October 20, 2007 5:15 AM