WebSetup/Windows Setup Project Summary

来源:互联网 发布:淘宝仓库出货流程 编辑:程序博客网 时间:2024/05/16 04:48

 http://devcity.net/Articles/339/2/article.aspx good article.

1. That's it, those are the steps to create an Installer Class. As you can see it is inheriting from the Installer abstract class, and because of this, several installation events are exposed for you to override, like:

  • Commit
  • Install
  • OnAfterInstall
  • OnAfterRollback
  • OnAfterUninstall
  • OnBeforeInstall
  • OnBeforeRollback
  • OnBeforeUninstall
  • OnCommitted
  • OnCommitting
  • Rollback
  • Uninstall
The sequence these events are raised is shown next:



Play attention to the facts: (a) untrapped exceptions on the OnBeforeInstall event will not trigger any of the Rollback events; and (b) you may reach the Rollback events from anyone of the installations events. 

UN-WRITTEN RULES

  • All these events should be bullet proof without throwing unexpected exceptions, if anyone of these methods throw an exception the installation or uninstallation request will fail.
  • It does not make much sense calling the Rollback event in the middle of a different event; you should implement these events independent of each other, your installation class may have common methods shared by these events, but cross calling installation related events are risky business.
  • Practice extreme caution when coding the Uninstall event, failure to do so may render your application un installable.
  • If you are using the savedState event's variable (more about this variable later), you should assign your installer class to all the Custom Action's modes (Install, Commit, Rollback and Uninstall) in the Deployment project.
  • Your installer class should not reference classes located outside its assembly because there is no way to know if those assemblies will be available (installed) at the time you reference a class or method from an external assembly.

UNPLEASANT FEATURES

  • None of the deployment project's properties is automatically available within your installer class.
  • Your Installer Class could be instantiated several times by the Windows Installer (installation) process, for this reason you can't rely on global variables to keep track of its different stages, that's why you should use the StateSaver and SavedState objects explained later on this article. 



 用Visual Studio 可以创建2种类型的Setup Project.

一篇不错的文章:

http://weblogs.asp.net/scottgu/archive/2007/06/15/tip-trick-creating-packaged-asp-net-setup-programs-with-vs-2005.aspx

1. Windows Setup Project

优点:用户可以选择安装路径,但不能有Default WebSite列表框的输入。

2.WebSetup Project

优点:用户不能选择安装路径,有Default WebSite列表框的输入。

 如果用户要修改自定义的安装目录(C:/Inetpub/wwwroot)到指定的目录(用户界面输入的参数)

1) 可以在 public override void Commit(IDictionary savedState) {UpdateWebsite();}

2) 添加Custom Folder,然后把安装的文件放在这个目录里面(而不要放在缺省的Web Application Folder),并且设置属性[Default location]=界面输入的参数[MYTARGETDIR],设置属性AlwaysCreate=True

3)Custom Action,添加:/myTargetDir=[MYTARGETDIR]

详细信息参照:

http://social.msdn.microsoft.com/forums/en-US/winformssetup/thread/47153558-b60c-426a-8036-0fa746fbf977/

1。定义一个CustomSetup Project (Class Library),重写Install/UnInstall记得要添加[RunInstallertrue)]  

[RunInstaller(true)]
    public class SummitCustomSetup : Installer
    {
        public override void Install(System.Collections.IDictionary stateSaver)
        {
            base.Install(stateSaver);

            // Retrieve configuration settings
            string targetSite = Context.Parameters["targetsite"];
            string targetVDir = Context.Parameters["targetvdir"];
            string targetDir = Context.Parameters["targetdir"];


            if (serverName == null)
                throw new InstallException("IIS ServerName Not Specified!");

            if (targetSite == null)
                throw new InstallException("IIS TargetSite Not Specified!");

            if (targetVDir == null)
                throw new InstallException("IIS Virtual Directory Not Specified!");

            //if (targetRDir == null)
            //    throw new InstallException("IIS Virtual Directory Real Local Path Not Specified!");

            if (targetDir == null)
                throw new InstallException("IIS Virtual Directory Default Local Path Not Specified!");

            if (targetSite.StartsWith("/LM/"))
                targetSite = targetSite.Substring(4);

            RegisterScriptMaps(targetSite, targetVDir);

           UpdateConfigure(targetSite, serverName, targetVDir, connectionstring, olap, targetDir, webserviceName, mailServer, mailsenderAccount, defaultRecipient, password,protocolwebserviceName);
            //if (!IISManager.UpdateWebSite(targetSite, serverName, targetVDir, targetRDir, targetVDir))
            //    throw new InstallException("Update IIS WebSite error");
        }

        private void RegisterScriptMaps(string targetSite, string targetVDir)
        {
            // Calculate Windows path
            string sysRoot = System.Environment.GetEnvironmentVariable("SystemRoot");

            // Launch aspnet_regiis.exe utility to configure mappings
            ProcessStartInfo info = new ProcessStartInfo();
            info.FileName = Path.Combine(sysRoot, @"Microsoft.NET/Framework/v2.0.50727/aspnet_regiis.exe");
            info.Arguments = string.Format("-s {0}/ROOT/{1}", targetSite, targetVDir);
            info.CreateNoWindow = true;
            info.UseShellExecute = false;

            Process.Start(info);
        }

        public override void Uninstall(IDictionary savedState)
        {
            if (savedState == null)
            {
                throw new ApplicationException("Cann't uninstall!");
            }
            else
            {
                base.Uninstall(savedState);
            }
        }

        private void UpdateConfigure(string targetSite, string serverName, string targetVDir, string connectionString, string olap, string targetDir, string webserviceName, string mailServer, string mailsenderAccount, string defaultRecipient, string password, string protocolwebserviceName)
        {
            // Retrieve "Friendly Site Name" from IIS for TargetSite
            DirectoryEntry entry = new DirectoryEntry("IIS://" + serverName + @"/" + targetSite);
            string friendlySiteName = entry.Properties["ServerComment"].Value.ToString();
            if (targetDir.EndsWith("//"))
            {
                targetDir = targetDir.Substring(0, targetDir.Length - 1);
            }

            try
            {
                // Open Application's Web.Config
                Configuration config = WebConfigurationManager.OpenWebConfiguration("/" + targetVDir, friendlySiteName);
                AppSettingsSection appSettingsSection = (AppSettingsSection)config.GetSection("appSettings");
                appSettingsSection.Settings[DATABASE_CONNECTION_KEY].Value = appSettingsSection.Settings[NAVIGATION_CONNECTION_KEY].Value = appSettingsSection.Settings[WORKFLOW_CONNECTION_KEY].Value = appSettingsSection.Settings[SECURITY_CONNECTION_KEY].Value = connectionString;
                appSettingsSection.Settings[DATABASE_CONNECTION_KEY].Value = appSettingsSection.Settings[DATABASE_CONNECTION_KEY].Value + @";Asynchronous Processing=true;";
               
                appSettingsSection.Settings[OLAP_CONNECTION_KEY].Value = olap;

                appSettingsSection.Settings[MAPPER_ASSEMBLY_KEY].Value = targetDir + @"/Bin/DNVS.BRIX.BRUM.Mappers.dll";
                appSettingsSection.Settings[SQLSERVER_ACCESS_ASSEMBLY_KEY].Value = targetDir + @"/Bin/DNVS.BRIX.BRUM.DataAccess.SQL.dll";
                appSettingsSection.Settings[CACHE_ASSEMBLY_KEY].Value = targetDir + @"/Bin/DNVS.BRIX.Caching.dll";
                appSettingsSection.Settings[SMART_APPLICATION_KEY].Value = targetDir + @"/SummitRecordingTool/";
                appSettingsSection.Settings[NAVI_FILE_KEY].Value = targetDir;
                appSettingsSection.Settings[NAVI_FILE_KEY].Value = appSettingsSection.Settings[NAVI_FILE_KEY].Value.Replace(@"/", @"//");
                appSettingsSection.Settings[ADD_PROTOCOL_TEMPLATE_FILE_PATH_KEY].Value = targetDir + @"/TempProtocols";

                appSettingsSection.Settings[BRIX_NAVI_KEY].Value = targetDir + @"/SecurityControls/NewPassword.txt";
                appSettingsSection.Settings[BRIX_SEC_SCRIPTPATH_KEY].Value = @"C:/perforce/depot/BRIX.Net/main/Security/SecurityMSSQLDAL/";
                appSettingsSection.Settings[BRIX_SEC_SMTPPASSWORDPATH_KEY].Value = targetDir + @"/SecurityControls/";

                RoleManagerSection configRoles = (RoleManagerSection)config.GetSection("system.web/roleManager");
                configRoles.Providers[BRIX_ROLE_PROVIDER_KEY].Parameters["connectionString"] = connectionString;

                appSettingsSection.Settings[MAIL_SERVER_KEY].Value = mailServer;
                appSettingsSection.Settings[MAIL_SENDER_ACCOUNT_KEY].Value = mailsenderAccount;
                appSettingsSection.Settings[DEFAULT_RECIPIENT_KEY].Value = defaultRecipient;
                appSettingsSection.Settings[WEB_SERVICEURL_KEY].Value = webserviceName;

                // Persist web.config settings
                config.Save();
            }
            catch
            {
                throw new InstallException("Web.config File Update Error!");
            }

          
           
        }
    }        

 

 

2.修改WebSetup/Windows Setup Project,添加CustomSetup Action。

Project Output:添加要安装文件/项目的ContentFile,PrimaryOutput。

Bin目录:添加CustomSetup Project.Dll。

3.添加CustomActions:

Install:Primary output from CustomSetup(Active),并且定义CustomActionData

(/targetdir="[TARGETDIR] " /db="[DATABASENAME]" /targetvdir="[TARGETVDIR]" /targetsite="[TARGETSITE]" /username="[USERNAME]" /servername="[SERVERNAME]" /password="[PASSWORD]" /analysis="[ANALYSISSERVICEIP]" /analysisdb="[ANALYSISCATALOGNAME]" /webservice="[WEBSERVICEURL]" /mailserver="[MAILSERVER]" /mailsenderaccount="[MAILSENDERACCOUNT]" /recipient="[DEFAULTRECIPIENT]" /protocolwebservice="[PROTOCOLWEBSERVICEURL]"

):

格式:/XXX=YYY,=号两边没有空格,严格按照上面的定义。

4.添加UserInterface(可以用orca.exe工具设置自定义的UI Dialog,比如下拉列表框等等)

参考:http://www.codeproject.com/KB/install/vsSetupCustomDialogs.aspx

 

一个小技巧,对于Password TextBoxInput,可以把Control/TextBox设置Attribute=2097152(Password) + 7(原来的Attribute) = 2097159来显示*.参考:http://www.codeproject.com/KB/install/setupprjpwd.aspx

Control Table:找到对应的TextBox,设置Attribute Value.

然后生成一个TransformFile,自动运行msitran.exe修改MSI File.

"C:/Program Files/Microsoft SDKs/Windows/v6.0A/bin/msitran.exe" -a XXX.mst "YYY.msi"