Article Options
Premium Sponsor
Premium Sponsor

 »  Home  »  Deployment  »  Installer Class and Custom Actions  »  Page 4
Installer Class and Custom Actions
by Arnaldo Sandoval | Published  10/15/2007 | Deployment | Rating:
Page 4
We should highlight few important things at this stage
  1. As the Commit event knows the Target Directory where the application is being installed, you can save it to the register for future references from the application, which is a Frequent Asked Question.
  2. The Commit event can reference the TargetDir property from the Context.Parameters variable because it was initialized by the Install event.
  3. You may use the code shown in the Commit example above to explore what is available on any event in your Installer Class.
  4. You should never attempt to modify the InstallState file, if you damage this file and the Uninstall event requires any information from it, you will not be able to uninstall the application.
  5. You should use the Commit event to apply final changes, like writing information to the register, changing folder permissions, etc.

USING THE COMMIT EVENT TO CHANGE THE TARGET DIRECTORY PERMISSIONS

If your deployment project is installing a Windows Services, and the Windows Services creates or write to files located on the TARGET DIRECTORY (Its home directory), you should change its permissions with the COMMIT event as long as the Windows Services is running under the LocalService, NetworkService or LocalSystem.


The code below changes the TARGETDIR permission for a Windows Services running under the LocalService account.

Code:

DirectorySecurity dirSec = Directory.GetAccessControl(savedState["TargetDir"].ToString());
FileSystemAccessRule fsar = new FileSystemAccessRule(@"NT AUTHORITY\SERVICE"

                              , FileSystemRights.FullControl
                              , InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit
                              , PropagationFlags.None
                              , AccessControlType.Allow);
dirSec.AddAccessRule(fsar);
Directory.SetAccessControl(savedState["TargetDir"].ToString(), dirSec);



You should add the following reference at the top of your class for the code above to work

Code:

using System.Security.AccessControl;

We get the Directory Security for the target directory (Windows Services home directory) using the GetAccessControl method on it; We already know it is save to use savedState["TargetDir"].ToString() from the explanations given before.

We create a new File System Access Rule for the NT AUTHORITY\SERVICE account, granting it (allowing, as the last parameter specifies AccessControlType.Allow) FullControl and setting the Inheritance Flags to ContainerInherit and ObjectInherit (both of them, the pipe between them works like a logical or, giving both of them), and setting the propagation flags to none. Why should we do this? the answer is simple, because it worked (after few hours of trial and error).

The complete code for the Commit event granting full permissions to the Windows Services' LocalService account is shown below:

Code:

public override void Commit(System.Collections.IDictionary savedState) 

   base.Commit(savedState); 

   DirectorySecurity dirSec = Directory.GetAccessControl(savedState["TargetDir"].ToString()); 
   FileSystemAccessRule fsar = new FileSystemAccessRule(@"NT AUTHORITY\SERVICE"
 
                                 , FileSystemRights.FullControl
                                 , InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit
                                 , PropagationFlags.None
                                 , AccessControlType.Allow); 
   dirSec.AddAccessRule(fsar); 
   Directory.SetAccessControl(savedState["TargetDir"].ToString(), dirSec); 
}


 
We removed the code using the streamWriter as it is not relevant to change the TARGETDIR permissions. After these changes and installing the application, the target directory permissions for the NT AUTHORITY\SERVICE account are shown below; the account NT AUTHORITY\SERVICE is represented by the SERVICE account in the picture:



USING THE UNINSTALL EVENT TO CLEAN THE TARGET DIRECTORY

Well, after working long hours and having countless meetings with your client, they decided to Uninstall your solution, or perhaps they were so thrilled that a new and more powerful one will replace the original one. Regardless of the reason, applications will not remain installed forever, sometime they have to go, and when this happens you want everything under its home directory (known as target directory by the deployment project) to get deleted. The deployment project's uninstall process will get rid of all the objects it installed (including your installer class), but its home directory may not be deleted if it is not empty and your application may have created files (log files, temp files, config files, registry entries, etc) that the deployment project is unaware of, so it will not consider deleting them at uninstallation time; this is a situation that your installer class' UNINSTALL event should take care of.

The code below is for an installer class UNINSTALL event cleaning the target directory.

Code:

public override void Uninstall(System.Collections.IDictionary savedState) 
{ 
   base.Uninstall(savedState); 

   String _TargetDir; 

   _TargetDir = savedState["TargetDir"].ToString(); 

   if (File.Exists(_TargetDir + "DB.log") == true) 
   { 
      File.Delete(_TargetDir + "DB.log"); 
   } 
   if
(File.Exists(_TargetDir + "DB_Settings.log") == true) 
   { 
      File.Delete(_TargetDir + "DB_Settings.log"); 
   } 
   if (File.Exists(_TargetDir + "DB.config") == true) 
   { 
      File.Delete(_TargetDir + "DB.config"); 
   }
}



You should not be concerned about deleting the Installer Class and its InstallState files as the un-install process will delete them at the very end, your IC's Uninstall event should delete whatever was created outside the initial installation.

WHERE IS THE "NT AUTHORITY\SERVICE" ACCOUNT COMING FROM?

One way to find the account a windows service is running under is by adding these lines of code in the Windows Service's OnStart event:

Code:

   WindowsIdentity self = WindowsIdentity.GetCurrent(); 
   SecurityIdentifier selfSID = self.User; 

   StreamWriter sw = new StreamWriter("C:\\Temp\\Iam.txt"); 
   sw.WriteLine("I am " + self.Name); 
   sw.WriteLine("wow " + self.Groups.ToString()); 
   sw.Flush(); 
   sw.Close();



You will need the following namespaces for the code above to work

Code:

using System.Security;
using System.Security.AccessControl;
using System.Security.Principal;
using System.IO;



You should make sure, the Temp folder exists on the machine where you are running the Windows Service. The account NT AUTHORITY\SERVICE was found with the code above on a Windows Xp machine, it may change elsewhere, like Windows 2000 or 2003 Servers.

 

Comments    Submit Comment

Comment #1  (Posted by jipfromparis@hotmail.fr on 10/23/2007)
Rating
Very instructive. Just a point, its always a good idea to take globalization into account. Network service account name is OS language dependent. Thus, on page 4, the first parameter for FileSystemAccessRule constructor should be :

new SecurityIdentifier(WellKnownSidType.NetworkServiceSid, null).Translate(typeof(NTAccount)).Value

The above line requires using the System.Security.Principal namespace. This said, thanks again for this article.
 
Comment #2  (Posted by an unknown user on 11/20/2007)
Rating
Great! Short but detailed. Thanks
 
Comment #3  (Posted by an unknown user on 11/21/2007)
Rating
Good One.
 
Comment #4  (Posted by Gil Yoder on 11/29/2007)
Rating
Just what I've been looking for! You won't believe how hard it was to find a good explanation of customer actions. Thanks!
 
Comment #5  (Posted by Iván Gracia on 12/14/2007)
Rating
Hi! Great article! Came across it while searching for a way to include a custom action that asks the user whther he wants to empty the install folder or not on uninstall. Is possible to do this with Orca? How can I add a custom action to an installer project, but only the uninstall part?

Thanks in advance!
 
Comment #6  (Posted by Arnaldo Sandoval on 12/14/2007)
Rating
Hi Ivan, it seems the answer to your question is on page 3, you can assign the custom action to the UnInstall action; if you want to talk about it, why don't you join VbCity (www.vbcity.com) and post a question there. I will be glad to help; my user name there is rock.

Cheers,
 
Comment #7  (Posted by Jimmy Huang on 12/25/2007)
Rating
Very useful
 
Comment #8  (Posted by an unknown user on 12/28/2007)
Rating
It was a brilliant explanation. Before this article I didn't understand how it worked, and I couldn't find a good explanation anywhere else.
 
Comment #9  (Posted by an unknown user on 01/15/2008)
Rating
Trapping the mouse within the form seems like a hack which will not work in all cases. Any other ideas?
 
Comment #10  (Posted by Arnaldo Sandoval on 01/15/2008)
Rating
I agree with you regarding the issue with the mouse, and the way it is handled; I had two options at the time I wrote the article (a) make the community aware of the problem, giving a possible workaround or (b) exclude any reference to the odd behaviour, which will frustrate those following these directions; I think that option (a) better services the community, if anyone knows a better way to resolve the mouse issue, please post the code or email it to me, I will gratefully amend the article with a recognition note to the person assisting me with the issues.
 
Comment #11  (Posted by vhjraerhlj on 01/23/2008)
Rating
Hello! Good Site! Thanks you! wmsoloxrdxhw
 
Comment #12  (Posted by Andrei on 01/28/2008)
Rating
I can use following parameters:

[TARGETDIR]
[TARGETVDIR]
[TARGETPORT]

But I need to pass Product Name. It this possible? If so, which parameter I should use?
Thank you.

 
Comment #13  (Posted by willfread on 01/29/2008)
Rating
great Article ...The way he/she present the Topic
 
Comment #14  (Posted by an unknown user on 01/30/2008)
Rating
Just what I was looking for! Step-by-step, very complete and very easy to follow. Great article!
 
Comment #15  (Posted by Tomek on 02/07/2008)
Rating
great article

really great
 
Comment #16  (Posted by Tom on 02/08/2008)
Rating
This is the most helpful thing I've found on custom actions. Thanks.
 
Comment #17  (Posted by an unknown user on 02/10/2008)
Rating
It gives through knowledge of installer class and it's uses
 
Comment #18  (Posted by Blumen on 02/17/2008)
Rating
Great article! Very useful indeed!!
 
Comment #19  (Posted by Mustafa on 02/22/2008)
Rating
Thanks for the great post.. That covers many points and details of installation and uninstallation, thanks again..
 
Comment #20  (Posted by Greg Askew on 03/02/2008)
Rating
Thank you for writing this article, it is very helpful!
 
Comment #21  (Posted by an unknown user on 03/15/2008)
Rating
Excellent and many thanks. This article really helped. A section on how to add shortcuts into the start/programs menu along with the application's icon (non default) would be a great addition.
 
Comment #22  (Posted by an unknown user on 03/17/2008)
Rating
I was able to create a custom install package with limited experience.
 
Comment #23  (Posted by an unknown user on 04/18/2008)
Rating
bcas it has the more detailed and helpful info than the other articles on the net have..
 
Comment #24  (Posted by ducnm on 04/25/2008)
Rating
Great article, but I have a problem. When I unistall program, i want it not delete some file in directory. How do you do?

 
Comment #25  (Posted by Mayank Kukadia on 04/29/2008)
Rating
Greate article. Greate Efort. Thanks a lot.
 
Comment #26  (Posted by Geof on 05/06/2008)
Rating


hi,
first, sorry for my english…
I have made an Installer Class, it works, but my trouble is when the user want to stop the installation, it doesn’t stop… I have a message, but the installation goes on.
I have made method override for “RollBack” , but the programm doesn’t get in on clicking Cancel_Button.
How can I made for stopping or calling the rollback method, when the Cancel_Button is clicking?
thanks

 
Comment #27  (Posted by Arnaldo on 05/07/2008)
Rating
Hi Geof,

Why don't you join www.vbcity.com and post your question there, it will be easier to assist you this way, it will not be practical to engage into a technical discussion inside these comments, once your issue is resolve we can post a link to the VbCity's thread.

Regards,
Arnaldo
 
Comment #28  (Posted by an unknown user on 05/07/2008)
Rating
Fantastic effort thank you for that. That helped me a lot.
 
Sponsored Links