Tuesday, December 1, 2009

Making .Net Applications UAC compliant (Vista,Server 2008, etc)

UAC(User access control) is a feature which users started feeling the pain of :) in Vista and this legacy will continue in most of the microsoft products which will be released in subsequent future. Take for eg windows 2008, windows 7 etc. they all will feature those popups which prompt you when an application is started. Sometimes i think..."Why does it ask me for some action i have taken in all good sense"... well i havent got a good answer yet and just as i started working on making software UAC compatible.... I got a good chance to explore it. So here I am trying to share the experience and the knowledge in as small an article as much i can shorten.


Before embarking on making a software for the UAC feature rich vista or Os's to come, we have to know about what a Standard User is. A standard user is any system user who doesnt need to know about anything except use the box and leave it. Actually 90% of users of a system are supposed to be Standard users and a few must be eligible to be Admin powered users. So whats the difference between a standard user and an admin user. A standard user has limited rights... since he is not supposed to do a variety of things like,,,, accessing the registry, changing it... create files where you are not authorized, trying to delete files made by other users, trying to rename a file created by some other user, peeping around dark corners in your PC etc. More over the security features revolving around UAC also restrict applications to doing any write/create/delete/update IO operation in Program Files.

Rule 1. If your application writes to any file/folder within "Program Files"... its gonna fail. So change this to a location which is common for any kind of a user (especially our so dear Standard User).

Rule 2. If your application needs to store user specific data then use %userprofile% location. Programatic access can be found by using the Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) method in C#. This would give you the current user's application data path.

Rule 3. Rule 1 and Rule 2 are as a result of the virtualization that takes place in Vista and server 2008. The writes to any directory in C:\program files is directed to a user specific store. Tring to save a txt file to c:\Program Files will prompt the user to save it to My documents folder for eg:
C:\Users\rmathew\Documents.

To re-route the reads and writes which occur at the program files directory to a common path we should consider the Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) folder. This will Get the folder named "ProgramData" in Vista and 2k8. A common path on vista would look like C:\ProgramData. Developers wanting to share common data across all users on a sytem for a specific application, will have to store their data at this specific location. All reads and writes which occured at C:\Program Files folder structure will have to be redirected to the CommonApplicationData folder. Read writes would include log files, config files, xml files generated on the fly etc. Developers will have to give FULL RIGHTS to "EveryOne" user on this folder and all files must inherit security attributes from the above folder.

Rule 4. Add a Manifest file to your Application. The manifest file is used by the OS to read the specifics of the application requesting to start execution. The effective authorization and rights of the applications are specified in the manfiest file. Embed the same as resource. If the name of the executable is Abc.exe, the manifest will be Abc.exe.manifest. These manifest files are generated in visual Studio 2008 by default but in previous versions of visual studio this manifes file needs to be added as a post build event.
In Visual Studio 2005 a Post Build Event can be fired  to add the assembly manifest file

"C:\Program Files\Microsoft Visual Studio 8\VC\bin\mt.exe" -manifest "$(ProjectDir)$(TargetName).exe.manifest" -outputresource:"$(TargetDir)$(TargetName).exe;#1"


Rule 5. Give the ACL(Access control list) to specific folders where write operations have to be performed.

if (!Directory.Exists(initialCachePath))
{

    //Creating Directory
    DirectoryInfo dirinf= Directory.CreateDirectory(<some directory you need to create>);

   //Get the access control list on the created directory
    DirectorySecurity dSecurity = dirinf.GetAccessControl();

    //Adding accessing rights for "Everyone" on that folder with full control
    dSecurity.AddAccessRule(new FileSystemAccessRule("Everyone", FileSystemRights.FullControl,  InheritanceFlags.ContainerInherit
InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow));

//apply permissions to directory(s)
dirinf.SetAccessControl(dSecurity);

}


Rule 6. Test Test and retest.

Thursday, October 1, 2009

Common FAQs - App configs, NLog, UAC, Folder Enumeration etc

Although App configs bring flexibity and configurability to our applications, working with it can be quite confusing. I will clear atleast two most common questions that arise in our minds

a) Can we load a windows application App.Config from a different Location ?

Answer: Yes. We do not necessarily need to have the app config in the same directory as the executable. We know that every windows app has atleast one app domain to run in, so we fool the app domain by setting one of its internal variables to locate to a web config from a different location.

Use the following line of code to do so.
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", _path );
Here _path = path to your distant location App.config.

b) How to Make my Windows App re-read my App config or Reload my App config without restarting the application?

Answer: Use the following piece of code, which sets a private variable reflectively and fools the configuration manager to reload the config file.

RuntimeFieldHandle initStateFieldHandle = typeof(System.Configuration.ConfigurationManager).GetField("s_initState", (BindingFlags.NonPublic BindingFlags.Static BindingFlags.ExactBinding)).FieldHandle;

FieldInfo fi = FieldInfo.GetFieldFromHandle(initStateFieldHandle);
// retrieve reference to registered client variable
fi.SetValue(null, 0);


c) Can we set the Log File Directory dynamically in NLog?

Answer: As we know NLog is a great component for Logging in .Net applications. It aliveates the users from the hassles of creating the infrastructure to enable logging in .net applications. I came across a similar issue while working on UAC stuff to create a Log File in a different directory based upon the Operating system.


Nlog has provided us with some functionality to inject the programatically generated Path/Log file location into the configuration specifed in config files. Take a look at the highlighted piece of code in the following configuration section. We could see a variable gdc:logdirectory. This pertains to a variable name logdirectory which has been set somewhere globally.



xsi:type="File" layout="${message}"
filename="${gdc:logdirectory}/Log/MyLogFileName.log"

archiveFileName="${gdc:logdir}/Log/MyLogFileName.{##}.log" archiveAboveSize="1048576" archiveNumbering="Rolling" concurrentWrites="true" maxArchiveFiles="20" keepFileOpen="false" encoding="iso-8859-2" />

To Set the variable we must use the following piece of code at an appropriate location eg: Static constructor, class initializer.Etc. so that before the logging code is called, we have the value set.

NLog.GDC.Set("logdirectory", ComputedLogDirectory);



c) Can we merge two configs ??
Answer: Aha... that goes for a blog of itself.... watchout for my next blog.

Wednesday, July 29, 2009

.Net Application Performance Profiling, Performance metrics, Performance Monitoring and Optimization Part 1

Profiling, Performance metrics.

Application performance is a core element of any software's success. People spend all the time writing code and developing solutions but when it comes to performance, raising an eyebrow is the first expression that's is evident on every team members face.

Performance tuning, performance optimization, performance review, profiling are the jargon which people are wary about. Its psychological that any developer would not like to be the person who's code did the most amount of work and contributed extensively towards making the application slow, but an honest introspection is something that gives a definitive edge.


Wisdom in terms of software development comes by retrospection, code review and facts which establish that writing a certain piece of code has definitive measurable impact on performance.

Let me stop this verbal jugglery and try to show you some facts and figures which i came across while performance tuning a critical application.

I had the massive task of improving the start up time and performance of an application that had to be used in a critical situation. Errors, flaws, ignorance, exceptions, exclusions are strictly unacceptable. As a matter of fact they are Lethal to existence.



I started with the CLR profiler and got some startling facts.




Its bang on. It will show u your code's mettle. how much memory is allocated and how does it contribute to the application memory allocation.

a) Use RuntimeMethodHandle, RuntimeFieldHandle etc in place of MethodInfo. Method handles are lightweight, efficient and fast. Check out

b) Try to use BeginInvoke instead of Invoke. The difference being that one is synchronous call and the other is an async call.

c) Try to use Async calls. Eventing is a very good strategy. It may be a little confusing to follow in code but it establishes a decent async method call routine and is considered robust. Sequential flow must be broken down to such eventing mechanisms where after a step an event in raised and the second event would then commence. Beware of updating a User interface on a BeginInvoke method since in WPF only the main thread is the UI thread and any other thread updating the UI is considered a villain.

d) String operations and concatenations are killers. Replace them with string builders.

e) The foreach on a List is slower than the for loop with count. Try to use the FOR loop instead of the FOREACH loop for mission critical places where performance is needed. Etc startups etc.


d) Locking and multi threaded scenarios. For multi threaded scenarios where there are chances for a raise condition or for a deadlock condition we use the LOCK construct in C#. It has to be noted that Lock will slow the application since when two threads simultaneously try to access a resource there would be one thread which succeeds and the other will wait until the first thread leaves the lock. This can be tested in load testing scenarios for eg, try to write to a Hashtable or array with 200 users load on a load test. There will be exceptions that occur.

The solution. Don't use a lock for READING from a hashtable. Use the LOCK for Writing to a HashTable and release it as soon as possible.

eg:

INCORRECT USAGE

Hashtable hs = new Hashtable();
object lockObj = new object()
lock(lockObj)
{
//read the object from hashtable.
object readObject = hs["key"];

//Create new object and write to the hashtable.
hs.Add("writeKey","WriteVALUE");
}

CORRECT USAGE


//We wont use the lock for reading
object readObj = hs["key"]

//We will use the lock for writing.
lock(lockObj)
{
hs.Add("writeKey","WriteValue");
}


f) Remove un-necessary references from your project. Adding references which are not useful or not used anywhere will increase time in loading these assemblies on startup. Make sure that the reference are updated when u remove the "using ----" statement.

g) Remember that loading an assembly in memory is not = JITTIng assembly. Assembly JITTING is a costly affair and takes CPU cycles. Loading an assembly would just load it in memory but JIT is performed when any method in the loaded assembly is called.

h) Make sure that object creation is not costly and time consuming. What happens is that we clutter the constructor of a class with lots of code which have a catastrophic impact on the speed of an application. The application cannot create instance of the class or it may take time instantiating the class hence the application is now slow.


i) For WPF applications, Try not to make extra overheads and wrappers around in-build controls. They can tremendously slow your application. So try to use the controls provided in .net framework as much as possible and try to avoid un-necessary wrappers around them.


j) App domains are an interesting topic of discussion and they are extremely useful for application development. If you are creating an application, which would host other applications, or other assemblies, then it does make a lot of sense to use loader optimization. AppDomain creation is a costly process, assemblies are loaded into the newly created app-domain and the loading takes place in spite of some of the common assemblies already being loaded into the default appdomain. So use LoaderOptimization Attribute.

For WPF applications delete the file named App.XAML and App.Xaml.cs. Now use the following piece of code

public partial class App: Application
{


[STAThread]
[LoaderOptimization(LoaderOptimization.MultiDomainHost)]
static void Main()
{
App app = new App();
app.InitializeComponent();
app.Run();
}


}


k) Use tools like CLR Profiler and .Net Performance analysis wizard to analyze memory allocation. I have tried to use JetBrains DotTrace and found it to be quite good. You could get a trial for 30 days and could buy it if u like it,

l) Although these are some of the ways we could improve the performance of ,net applications it has to been seen that constant review, constant change, constant trials are the only way to improvise on it.


I wish to blog in detail about other aspects of application performance improvement and will do so in the next sessions. If you like or dislike this article, i would like to listen to your feedback and thoughts.