﻿# ASP.NET 網站專案如何利用 MSDeploy 工具進行部署

我之前寫過一篇〔[如何使用 Visual Studio 2010 的「單鍵發行」功能](/post/2010/05/03/Deploying-Web-Application-Project-Using-One-Click-Publish.aspx)〕文章，當時簡直挖到寶一樣，可惜最近又開始維護幾個多年前用 ASP.NET 2.0 建置的網站，當時是以 **網站專案** (WebSite Project) 的專案類型開發的，因此 Visual Studio 2010 的「單鍵發行」功能就變的英雄無用武之地，還好透過 [Visual Studio 2010 Web Deployment Projects](http://web.archive.org/web/20110807083930/http://www.microsoft.com/download/en/details.aspx?id=24509) (WDP) 可以將網站專案封裝起來，但是上週遇到一個怎樣都無法發行成功的問題，查了兩個小時才找到這原來是一個 Visual Studio 2010 ( 含 SP1 ) 的 Bug，使用的人要特別注意這個小問題。

關於 Web Deployment Projects 的使用方式我在之前也寫過文章教學，在此不多做說明，不會的人請參考 [ASP.NET 網站部署可考慮使用 Web Deployment Project](/post/2009/01/27/Visual-Studio-2008-Web-Deployment-Project) 文章說明。

有了 Web Deployment Project 之後，Visual Studio 2010 有新增一個「建置部署套件」功能，此功能會很貼心的幫你建立所有跟部署相關的檔案：

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/72de91d66df888378a62-image_828.png)

當你執行完「建置部署套件」後，會在 Web Deployment Project 專案檔的所在目錄看到一個 obj 目錄，點進去 obj 目錄，還會再看到一個 Debug 目錄，所以千萬不要進到第一層的 Debug 目錄了：

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/7ebf910a8f37dc1db2b7-image_829.png) ![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/07c63fcec096f12c7069-SNAGHTML63be521.png)

接著會在目錄裡看見一個 Package 目錄：

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/042f4f2e8a52905d9128-image_830.png)

進入此目錄後，這裡包含 MSDeploy 專用的建置套件：

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/4bf35aaac18a33c7f65a-image_831.png)

這裡有幾個重要的目錄與檔案，分別說明如下：

-   **PackageTmp**
    -   建置部署套件時最後的封裝檔，這些只是暫存檔，部署時用不到這個目錄，因為 Visual Studio 2010 已經幫你壓縮成 **{**專**案名}.zip** 了！
-   **{專案名}.deploy.cmd**
    -   這是個可用在命令提示字元模式下的指令檔（批次檔），幫你簡化使用 MSDeploy.exe 工具的複雜度（因為 MSDeploy.exe 需要輸入的參數比較多）。
-   **{專案名}.deploy-readme.txt**
    -   這是 {專案名}.deploy.cmd 的說明文件。
-   **{專案名}.SetParameters.xml**
    -   當要利用 **{專案名}.deploy.cmd** 或 **MSDeploy.exe** 進行部署時，會需要用這個參數檔。
-   **{專案名}.SourceManifest.xml**
    -   這個檔案是 Visual Studio 2010 用來產生封裝檔之用，你看到這個目錄時其實已經都完成所有封裝檔了，因此此檔案一般用不到。
-   **{專案名}.zip**
    -   主要的部署檔案，包含所有要部署的檔案與一些設定檔在內。

這幾個檔案彼此之間的關係，可以透過下圖瞭解：

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/183f6c20aa01b501be4a-image_832.png)

-   Visual Studio 2010 讀入專案檔 ( \*.csproj ) 設定
-   先產生 4 個檔案，分別是：
    -   **{專案名}.deploy.cmd**
    -   **{專案名}.deploy-readme.cmd**
    -   **{專案名}.SetParameters.xml**
    -   **{專案名}.SourceManifest.xml**
-   然後透過 **MSBuild** 、**{專案名}.SourceManifest.xml** 與 **Web Deploy API** 與產生最終的部署套件檔 ( Web Deployment Package ) ( **{專案名}.zip** )

Visual Studio 2010 裡只有 **ASP.NET 網站應用程式專案** 才能設定完整的 **封裝/發行** 設定 (如下圖示)，其他像是 ASP.NET 網站專案或是 Web Deployment Project 便無法進行如下圖的詳細設定：

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/ffdb89145999ec9fd59c-image_833.png)

也因此透過 Web Deployment Project 封裝過的部署參數裡我們就無法自由設定參數，我們開啟 **{專案名}.SetParameters.xml** 檔案起來查看，發現 **IIS Web Application Name** 參數永遠是安裝到 Default Web Site 站台下的 {專案名}WDP 應用程式目錄，這也代表著，每次使用 Visual Studio 2010 建置部署套件後都要手動修改這個檔案的內容才能進一步透過指令檔部署封裝檔，這實在太不方便了。

```
<?xml version="1.0" encoding="utf-8"?><parameters>  <setParameter name="IIS Web Application Name"      value="Default Web Site/{專案名}WDP" /></parameters>
```

還好我們可以透過指令列透過 **\-setParam** 參數來直接指定 **IIS Web Application Name** 參數，這樣我們就可以直接將網站發佈到特定站台下了，如下例會部署該封裝檔到本機 IIS 的 TEST 站台下：  
**注意:** /T 為測試安裝，/Y 才是正式安裝！

```
website_deploy.deploy.cmd /T "-setParam:'IIS Web Application Name'='TEST'"
```

以上的語法是 100% 正確的，但是 Visual Studio 2010 SP1 幫我們產生的批次檔有問題，以致於以上指令執行時會出現以下錯誤： ( 如下圖箭頭指出的就是無法執行的元凶 )

[![錯誤: 無法辨識的 '"-setParam:'IIS Web Application Name'='TEST'"' 引數。所有引數都必須以 "-" 開頭。 錯誤計數: 1。](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/2683aa0c6691058a96c7-SNAGHTML66e169d_4__thumb.png "錯誤: 無法辨識的 '\"-setParam:'IIS Web Application Name'='TEST'\"' 引數。所有引數都必須以 \"-\" 開頭。 錯誤計數: 1。")](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/0651984ec8197238efb7-SNAGHTML66e169d_4.png)

要解決此問題請參考 [KB2537134](https://web.archive.org/web/20130620005859/http://support.microsoft.com/kb/2537134) 所示的步驟進行修正有問題的檔案即可，以下是更新步驟說明：

步驟 1：先找到負責產生 **部署套件** 的 **Microsoft.Web.Publishing.targets** 檔案，並先備份該檔案

如果是 x64 環境下，此檔案會放在以下路徑

```
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets
```

如果是 x86 環境下，此檔案會放在以下路徑

```
C:\Program Files\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets
```

步驟 2：下載微軟製作的新版 **Microsoft.Web.Publishing.targets** 檔案，並直接覆蓋掉現有的檔案：

-   下載連結  
    [http://go.microsoft.com/fwlink/?LinkID=216789&clcid=0x409](http://go.microsoft.com/fwlink/?LinkID=216789&clcid=0x409)

步驟 3：為了確保 Visual Studio 2010 產生新的封裝檔，建議將 obj\\ 目錄全部刪除乾淨。

步驟 4：重新啟動 Visual Studio 2010 然後開啟專案後執行「建置部署套件」，即可完成更新！

如上述四個步驟執行完後，就可以正常執行部署了：

[![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/64550067b30544e56e3f-SNAGHTML66d27eb_thumb.png)](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/92e4db378b0a3483e719-SNAGHTML66d27eb.png)

當然，我個人的習慣是另外寫一支批次檔，因為我還是喜歡「單鍵發行」的感覺，你知道的，工程師就是懶嘛～ 寧願花好幾個小時去省幾秒鐘的時間 XD  
( 註: 其實我們看的是終身價值，這次學會省時的作法如果換算到一輩子，我們省去的時間可以不只幾小時了！^\_^ )

**相關連結**

-   [使用 MSDeploy 手動部署網站時如何避免 Web.config 被更新](/post/2010/09/01/MSDeploy-Skip-Command-for-Webconfig-file.aspx)
-   [使用 MSDeploy 部署網站時如何避免刪除遠端網站的檔案](/post/2011/05/31/Avoid-Delete-Files-on-Remote-Website-using-MSDeploy-tool.aspx)
-   [ASP.NET Web Application Project Deployment Overview](http://msdn.microsoft.com/en-us/library/dd394698.aspx)
-   [Running a deployment package with quoted parameters fails in Visual Studio 2010 SP1](https://web.archive.org/web/20130620005859/http://support.microsoft.com/kb/2537134)
-   [Web Packaging: Installing Web Packages using Command Line](http://vishaljoshi.blogspot.com/2009/03/web-packaging-installing-web-packages.html)
-   [MSDeploy batch file does not handle quotes anymore](http://stackoverflow.com/questions/5539968/msdeploy-batch-file-does-not-handle-quotes-anymore)
-   [Deployment package contains vague information should be modified in Visual Studio 2010 Service Pack 1](https://connect.microsoft.com/VisualStudio/feedback/details/671798/deployment-package-contains-vague-information-should-be-modified-in-visual-studio-2010-service-pack-1)
