天天看點

Asp.net 安裝包制作

主要參考:

      http://xucanzhao.cnblogs.com/archive/2005/10/02/248063.html 這個比較詳細,也是我看的第一個,照着一步一步來,最起碼知道添加使用者界面,添加操作了,可到最關鍵那步,代碼那出問題了,他用的是vb,我熟悉的是C#,改了半天沒改出來。

      在http://blog.csdn.net/abaowu/archive/2004/11/23/191908.aspx 提供的http://topic.csdn.net/t/20040913/17/3368253.html (7 樓goody9807的回複)裡找到了,到這也基本上明白這個“安裝程式類”的作用了

      還得在安裝的同時配置虛拟目錄,http://www.cnblogs.com/nerocool/archive/2008/08/13/1266733.html 這裡有個執行個體(示範的很詳細的,也有個制作安裝包的過程,是個pdf檔案),強烈推薦下載下傳後看看

      接下來動手做一個,先建立個空白解決方案,選“其他項目類型”裡的“Visual Studio 解決方案”,名字和位置自己随意定啊,在這就叫做InstallSolution了。

Asp.net 安裝包制作

      在解決方案資源管理裡建立項目,選“其他項目類型”裡的“安裝和部署”,選擇“安裝項目”【我選的是這個,在網上搜了幾個都用的是web安裝項目,從字面上來說web安裝項目似乎更合适,但我這web安裝項目我暫時沒試成功,下去再試試】,名字就叫setup吧,

Asp.net 安裝包制作

      注意下紅色标注的這幾個圖示,在實際操作中可以很友善切換編輯解界面,

Asp.net 安裝包制作

      然後對着項目右鍵選擇“視圖——使用者界面”在出現的“使用者界面”中

Asp.net 安裝包制作

      在“啟動”上右鍵“添加對話框(從字面上就可以猜出來這樣做的目的就是要彈出個對話框)”選擇需要的對話框

Asp.net 安裝包制作

      先添加個“許可協定”的對話框吧(這個框的功能就是安裝程式的時候彈出個視窗,内容是就是一些版權資訊或者什麼什麼的,如果使用者不點确定是不讓進行下一步操作的),之後就可以在使用者界面“啟動”下面看到這個對話框了,預設新添加的對話框是在最後的,需要右鍵“上移”至合适位置,這個原因就不多說了。

      這個對話框是加上了,可内容呢?呵呵,不急,先來建個檔案啊,打開word,在裡面寫上你想讓在“許可協定”這塊顯示的内容,然後“另存為”,在彈出來的屬性視窗中選擇“Rtf”格式(不要随便建個檔案,然後手動更改字尾名為rtf,要另存為是選擇字尾名,否則不顯示内容)

Asp.net 安裝包制作

      切換到Vs上,在“許可協定”這一項右鍵選擇“屬性視窗”,

Asp.net 安裝包制作

      在“LicenseFile”上選擇“浏覽”,找到你剛儲存的那個Rtf檔案,這個就好了

Asp.net 安裝包制作

      接下來得把網站加進去,對着解決方案,如果你的網站建立的時候用的是WebApplication(這裡指使用的是建立項目),就選添加現有項目,然後選擇你的項目,如果你用的是“網站Website(這裡隻使用的是建立網站)”,就不用選擇添加項目了,下面一個一個說。

      先說是website的,直接把你的website給生成了(就是說在你的website右鍵選擇“釋出網站”,要編譯之後的檔案【可以直接釋出的,裡面沒有.cs最字尾名的檔案,有.dll的】),接下來複制你編譯好的網站(所有的檔案),切換回剛建的這個項目中,切換到檔案系統界面(找不到?看解決方案上面得那一串圖示,把滑鼠放到第2個上,點選就好了)。

Asp.net 安裝包制作

      輕按兩下“應用程式檔案夾(我的了解這個檔案夾就是使用者在安裝程式的時候生成在使用者計算機中的檔案,就好像安裝QQ的話就會生成個名叫QQ的檔案夾,裡面的檔案應該就是編譯好的,可以直接運作,其他的幾個檔案夾功能也能夠從字面上看出來,這些自己嘗試吧),在中間(如下圖示注)”那塊粘貼剛複制的檔案(編譯好的所有檔案)

Asp.net 安裝包制作

      項目右鍵——“生成”, 這樣就做好了,點選右鍵“安裝”看看……

Asp.net 安裝包制作

      安裝之後的檔案時編譯好的,接下來咱看看WebApplication的,剛說了在解決方案上“右鍵”——添加已有項目,添加你的webApplication到這個解決方案,将滑鼠移到setup這個項目上來,右鍵——“添加”——“項目輸出”

Asp.net 安裝包制作

      在彈出來的視窗中選擇剛加入的webApplication項目,然後選中“主輸出”和“内容檔案”(這個其他的也可以選擇,根據自己的需要)。

Asp.net 安裝包制作

      點選确定即可,之後和剛才一樣,點選“生成”,按後“安裝”試試。可以發現安裝後的檔案時編譯好的。為什麼website不這樣呢?試試就知道了,

Asp.net 安裝包制作

      這裡不像webApplication那樣有那麼多的選項,隻有内容檔案,點選确定後生成,安裝後是源檔案,沒有編譯(原因尚不清楚)…… 這不行吧?如果在使用者機上沒法編譯,那這網站就跑不起來了。

      在安裝中你會發現下面這樣的情況

Asp.net 安裝包制作

      看下标記的,全是setup,安裝别的程式的時候都是顯示的程式名或者公司資訊之類,還有預設路徑怎麼是這樣的呢?這個這麼改?呵呵,切換回VS,然後選中setup項目,點選屬性視窗

Asp.net 安裝包制作

      是那個紅色的屬性,不是右鍵屬性,不一樣的。

Asp.net 安裝包制作

      把這幾個改改就好了,而且可以改别的,像“Description”的……

      這樣制作的安裝包總感覺少點什麼東西,使用者安裝之後還得自己去裝資料庫,改web.config檔案。仔細想想,感覺這個安裝包就是個解壓縮,它就是把編譯好的檔案拷貝了一份,有些活還得額外做,能不能在安裝的時候把資料庫建了。O(∩_∩)O這個是可以的……

      現在就說怎麼把資料庫給封進去,在解決方案上“建立項目”,選擇“類庫”,

Asp.net 安裝包制作

      把預設生成的class1.cs删除,建立“安裝程式類”,

Asp.net 安裝包制作
Asp.net 安裝包制作

      具體代碼先不說,一會在說

      在setup項目上,在添加個“視圖”――“使用者界面”,添加個對話框,這次選擇“文本A”,之後在文本框A上右鍵――“屬性視窗”,修改某些字段

Asp.net 安裝包制作
Asp.net 安裝包制作

      标記的那幾個名字是以後要用的“變量名”,根據自己的需要設定,這個是很靈活的,隻是我這個對話框的目的就是擷取跟資料庫有關的資料,是以就這麼寫了。

      這個界面跟寫程式時用的控件的屬性界面是一樣的,做測試屬性名,右側是值。

      其中帶有Label就是讓使用者看的,而帶有Property是以後在寫代碼的時候要用到的,這先做個記号,待會還得看上面那個圖。

      接下來在setup項目中 “視圖”——“自定義操作”

Asp.net 安裝包制作

      在自定義操作界面,選擇“安裝”,右鍵“添加自定義操作”,在彈出的視窗中輕按兩下“應用程式檔案夾”,然後選擇“添加輸出”,在“項目”中選擇“InstallClassLibruary”這個類庫項目,之後選擇“主輸出”和“内容檔案”,這樣在“自定義操作界面”就多了個内容,

Asp.net 安裝包制作

      在那個多出來的項上右鍵選擇屬性,在CustomAction中填上    /dbname=[DBNAME]  /server=[SERVER]   /user=[UNAME]  /pwd=[PWD]  /targetdir="[TARGETDIR]"  最後一個帶有“""”注意,“[]”中間的是剛在文本框A的屬性中帶有Property 那幾項填寫的的那幾個,而這些“/”之後的則是在寫程式中要用的,就是為了擷取文本框中輸入的值,targetdir是檔案的安裝路徑,需要單獨再加個雙引号,這個是很有用的;

      之後就到剛才建立的那個“安裝程式類”裡寫代碼了,看代碼

Code

/// <summary>

        /// 添加資料

        /// </summary>

        /// <param name="DataBaseName"></param>

        /// <param name="Sql"></param>

        private void ExecuteSql(string DataBaseName, string Sql)

        {

            SqlConnection sqlConnection = new SqlConnection("Data Source=" + this.Context.Parameters["server"] +

              ";Initial Catalog=master;Persist Security Info=True;User ID=" + this.Context.Parameters["user"] + ";Password=" + this.Context.Parameters["pwd"] + "");

            System.Data.SqlClient.SqlCommand Command = new System.Data.SqlClient.SqlCommand(Sql, sqlConnection);

            Command.Connection.Open();

            Command.Connection.ChangeDatabase(DataBaseName);

            try

            {

                Command.ExecuteNonQuery();

            }

            catch

            {

            }

            finally

            {

                Command.Connection.Close();

            }

        }

        /// <summary>

        /// 建立資料庫

        /// </summary>

        /// <param name="strDBName"></param>

        protected void AddDBTable(string strDBName)     

      {          

            try     

            {              

                ExecuteSql("master","CREATE   DATABASE   "+   strDBName);

            }     

            catch(Exception ee)

            {

              MessageBox.Show("資料庫建立失敗!您可以手動添加,但名稱需要和剛才填寫的資料庫名稱一緻! 錯誤資訊:/n" + ee.Message,"Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0);

            }     

      }

      這個是建立資料庫(注意隻有資料庫,沒有表啊,間表得自己寫),就是一般的方法,但僅僅這樣是不行的,它沒法執行,加上這個

Code

 public override void Install(System.Collections.IDictionary stateSaver)

        {

            base.Install(stateSaver);

            AddDBTable(this.Context.Parameters["dbname"]);

           // updateWebConfig();

           // CreateVirtualDir();

        }

      這就可以執行了,把這個方法寫到Install()裡……

      注意public override void Install(IDictionary stateSaver) 這個,需要重寫這個類,然後把你要執行的代碼放在這個方法裡,比方說

      建立資料庫,同時得修改Web.config檔案吧,再寫個修改web.config的方法,也放到Install裡,就可以執行了。

      注意到這個類中有“this.Context.Parameters["user"] ”的,這個就是剛才在自定義操作的“CustomAction”屬性中那個字段,這樣就可以把使用者輸入的資訊擷取到了。

      回憶一下啊

            第一:“添加使用者界面”,選擇文本框,

            第二:為文本框中的帶label和帶property的字段指派(如property為UNAME),

            第三:“自定義操作”,在屬性視窗的“CustomAction”再次傳遞參數,如“/name=[UNAME] ”,

            第四:在自定義操作類中,擷取這個參數,如“ this.Context.Parameters["name"] ”,這樣就可以在類中使用使用者輸入的資料了。

      再附上兩個方法,這個是修改web.config檔案的(其實就是讀取xml檔案,然後修改一個節點的屬性,需要添加命名空間System.XML)

Code

        private void updateWebConfig()

        {

            //加載配置檔案

            try

            {

                System.IO.FileInfo FileInfo = new System.IO.FileInfo(this.Context.Parameters["targetdir"] + "/web.config");

                if (!FileInfo.Exists)

                {

                    throw new InstallException("缺少配置檔案 :" + this.Context.Parameters["targetdir"] + "/web.config");

                }

                System.Xml.XmlDocument xmlDocument = new System.Xml.XmlDocument();

                xmlDocument.Load(FileInfo.FullName);

                //修改連接配接字元串

                foreach (System.Xml.XmlNode Node in xmlDocument["configuration"]["connectionStrings"])

                {

                    if (Node.Name == "add")

                    {

                        if (Node.Attributes.GetNamedItem("name").Value == "你在項目中使用的連接配接資料庫字元串的名字")

                        {

                            Node.Attributes.GetNamedItem("connectionString").Value = String.Format("Data Source={0};Initial Catalog={1};User ID={2};Password={3};", dserver, dbname, user, pwd); 

                        }

                    }

                }

                xmlDocument.Save(FileInfo.FullName);

            }

            catch

            {

                MessageBox.Show("Web.config 配置錯誤!", "安裝提示", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0);

            }

        }

      還有個生成虛拟目錄的(先添加引用 System.DirectoryServices,然後添加命名空間)

Code

 private void CreateVirtualDir()

        {

            try

            {

                string constIISWebSiteRoot = "IIS://" + iis + "/W3SVC/1/ROOT";

                DirectoryEntry root = new DirectoryEntry(constIISWebSiteRoot);

                //判斷虛拟目錄是否已存在,存在就先删除再建立【不建議這麼做,建議直接報個錯就行】

                DirectoryEntry Exist = root.Children.Find(virtualdir, root.SchemaClassName);

                if (Exist != null)

                {

                    //删除虛拟目錄

                    root.Children.Remove(Exist);

                    root.CommitChanges();

                }

                DirectoryEntry newRoot = root.Children.Add(virtualdir, root.SchemaClassName);

                newRoot.Properties["Path"][0] = physicaldir;//設定實體位址

                newRoot.Properties["AppIsolated"][0] = 2;             // 值 0 表示應用程式在程序内運作,值 1 表示程序外,值 2 表示程序池

                newRoot.Properties["AccessScript"][0] = true;          // 可執行腳本

                newRoot.Invoke("AppCreate", true);

                //tbEntry.Properties["DefaultDoc"][0] = "Default.aspx";//設定起始頁

                newRoot.Properties["AppFriendlyName"][0] = virtualdir;   // 應用程式名

                newRoot.CommitChanges();

                root.CommitChanges();

            }

            catch

            {

                MessageBox.Show("虛拟目錄建立失敗!", "Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0);

            }

        }

      再次生成看看,安裝時就可以看到輸入框了,資料庫的資料也是有效的了……

      這兩段代碼均是參考http://www.cnblogs.com/nerocool/archive/2008/08/13/1266733.html 

      這裡隻是簡單說了一下,還有些功能就沒提,像修改系統資料庫了(c/s用的比較多),添加桌面快捷方式,添加到快速啟動欄等等,這些自己都去試試,對着那些項點選右鍵看看都有什麼,都是什麼,多摸索摸索……

      最後再給個連結:http://blog.csdn.net/superes/archive/2009/03/16/3994939.aspx  介紹了3種把資料庫附件到安裝程式裡的,務必試試,剛我給的代碼中隻是見了個空庫,沒有表……

 ---------2009-10-29-----   

   對建立虛拟目錄的代碼加以修改,主要原因是按照原先的代碼釋出後,IIS中ASP.NET的版本是1.1.4322,這樣是無法通路的,需要改成2.0.50727,在網上搜尋之後,用”ASP.NET IIS注冊工具“可以實作,下面就多加了修改的代碼(搜到網上的還是1.1的,後來改成2.0的了)

建立虛拟目錄

  /// <summary>

        /// 建立虛拟目錄

        /// </summary>

        void CreateVirtualDir()

        {

            try

            {

                string constIISWebSiteRoot = "IIS://" + this.Context.Parameters["IISServer"] + "/W3SVC/1/ROOT";

                MessageBox.Show("start");

                DirectoryEntry root = new DirectoryEntry(constIISWebSiteRoot);          

                MessageBox.Show("no");

                DirectoryEntry newRoot = root.Children.Add(this.Context.Parameters["virtualdir"], root.SchemaClassName);

             //   newRoot.Properties["Path"][0] = @"D:/web";//設定實體位址

                newRoot.Properties["Path"][0] = this.Context.Parameters["targetdir"];

                newRoot.Properties["AppIsolated"][0] = 2;             // 值 0 表示應用程式在程序内運作,值 1 表示程序外,值 2 表示程序池

                newRoot.Properties["AccessScript"][0] = true;          // 可執行腳本

                newRoot.Invoke("AppCreate", true);

                newRoot.Properties["DefaultDoc"][0] = "Default.aspx";//設定起始頁

                newRoot.Properties["AppFriendlyName"][0] = this.Context.Parameters["virtualdir"];   // 應用程式名

                newRoot.CommitChanges();

                root.CommitChanges();

                //修改IIS中asp.net版本

                //用v2.0.50727下的aspnet_regiis.exe,網上給的都是v1.1.4,如果這樣就相當于沒改

                string fileName = Environment.GetEnvironmentVariable("windir") + @"/Microsoft.NET/Framework/v2.0.50727/aspnet_regiis.exe";

                ProcessStartInfo startInfo = new ProcessStartInfo(fileName);

                //處理目錄路徑

                string path = newRoot.Path.ToUpper();

                int index = path.IndexOf("W3SVC");

                path = path.Remove(0, index);

                //啟動aspnet_iis.exe程式,重新整理教本映射

                startInfo.Arguments = "-s " + path;

                startInfo.WindowStyle = ProcessWindowStyle.Hidden;

                startInfo.UseShellExecute = false;

                startInfo.CreateNoWindow = true;

                startInfo.RedirectStandardOutput = true;

                startInfo.RedirectStandardError = true;

                Process process = new Process();

                process.StartInfo = startInfo;

                process.Start();

                process.WaitForExit();

                string errors = process.StandardError.ReadToEnd();

                if (errors != string.Empty)

                    throw new Exception(errors);

             //   Console.WriteLine(process.StandardOutput.ReadToEnd());

            }

            catch (Exception ee)

            {

                MessageBox.Show("虛拟目錄建立失敗!您可以手動建立! " + ee.Message, "Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0);

            }

        }

 建立web安裝項目的也試了,這次可以了,原因未知,不過我這次用的是2003系統,上次是2008的,建立虛拟目錄的代碼在2008下也無法運作,在03上就可以

web安裝項目好處是可以自動生成虛拟目錄,不用額外的添加代碼,但遇到的新問題是檔案的安裝路徑沒法修改(沒有選擇路徑[浏覽]的那個對話框)……網上也查到了個,說是用orca軟體修改 生成後的msi檔案