Sunday, May 13, 2007

Vista, Visual C# Express Edition, UnauthorizedAccessException and SecurityException just to use PerformanceCounter - the Solution!

So like me you've just 4 hours researching System.Security just to allow you to use a PerformanceCounter in Visual Studio Express Edition without getting SecurityException and UnauthorizedAccessException.

You've looked at the project security tab and seen "ClickOnce" settings and added what you thought was the relevant setting "PerformanceCounterPermission" for the Intranet realm, but it didn't work.

You've added permissions declaratively (using assembly attribute) and imperatively (by using the permissions object directly) trying to get the code to prompt a UAC box on access in Vista, basically the stuff this article talks about.

You've even considered a hack to add the user to the relevant groups.

None of them worked or were ideal.

Save yourself some time - here's the quick solution (important bit is the requested permission in the manifest xml) - note some of the lines are wrapped below use common sense :)

- If you've only installed Visual C# Express (or other express version) install the .Net SDK (this is for .Net 2.0 - you may want 3.0). You need this for the tools that are missing from the Express install that you can find in the full Visual Studio (i.e. we need mt.exe - manifest tool)

- Modify the manifest associated with your Express project (in the built-in editor to ensure saved as UTF-8 encoding) to something resembling this:

<?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">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" />
</requestedPrivileges>
<applicationRequestMinimum>
<defaultAssemblyRequest permissionSetReference="Custom" />
<PermissionSet class="System.Security.PermissionSet" version="1" ID="Custom"
SameSite="site" />
</applicationRequestMinimum>
</security>
</trustInfo>
</asmv1:assembly>


- Add under "Post-build event command line" in the project build events tab (note -manifest points to the modified application's manifest mentioned above - so you may need to change its location):

"$(DevEnvDir)..\..\SDK\v2.0\bin\mt.exe" -manifest "$(ProjectDir)Properties\app.manifest"
–outputresource:"$(TargetDir)$(TargetFileName)";#1


This procedure alters the application manifest to ensure that the code is built requiring administrator permission to run. The command line argument updates the modified manifest into the application post build replacing the default app manifest already included.

Now under Vista your built project will have a small shield on the icon meaning it prompts for administrator rights on startup - hoorah!

No comments: