19

我如何制作包裹

我像这样制作 msdeploy 包:

msdeploy.exe -verb:sync -source:iisApp=c:\content\ -dest:package=c:\pkg.zip

c : \content目录有一个index.html文件。

结果

输出如下所示:

Info: Adding package (package).
Info: Adding child iisApp (c:\content\).
Info: Adding child createApp (c:\content\).
Info: Adding child contentPath (c:\content\).
Info: Adding child dirPath (c:\content\).
Info: Adding child filePath (c:\content\index.html).
Total changes: 6 (6 added, 0 deleted, 0 updated, 0 parameters changed, 0 bytes copied)

如果我将c:\pkg.zip的内容提取到目录c:\pkg中,它看起来像这样:

archive.xml
systemInfo.xml
Content\c_C
Content\c_C\content
Content\c_C\content\index.html

如果我像这样转储包裹:

msdeploy.exe -verb:dump -source:package=c:\pkg.zip -xml

我得到:

<output>
    <MSDeploy.iisApp>
        <iisApp path="c:\content\">
            <createApp 
                path="c:\content\" 
                isDest="False" 
                managedRuntimeVersion="" 
                enable32BitAppOnWin64="" 
                managedPipelineMode="" 
                applicationPool="" 
                appExists="True" />
            <contentPath path="c:\content\">
                <dirPath 
                    path="c:\content\" 
                    securityDescriptor="D:" 
                    parentSecurityDescriptors="" 
                    attributes="Directory">
                    <filePath 
                        path="index.html" 
                        size="0" 
                        attributes="Archive" 
                        lastWriteTime="07/07/2011 20:58:00" 
                        securityDescriptor="D:" />
                </dirPath>
            </contentPath>
        </iisApp>
    </MSDeploy.iisApp>
</output>

我希望它如何

我不希望包依赖于站点文件的当前位置。我将把包裹寄给客户,我不希望包装过程的任何细节随包裹一起发货。我希望包c:\pkg.zip的内容是这样的:

archive.xml
systemInfo.xml
Content\index.html

我希望包能够创建一个 IIS 应用程序,所以我需要一个虚拟路径。我还想将软件包安装到默认位置。所以物理路径也必须改变。我希望转储看起来像这样:

<output>
    <MSDeploy.iisApp>
        <iisApp path="Default Web Site\Site">
            <createApp 
                path="Default Web Site\Site"
                isDest="False" 
                managedRuntimeVersion="" 
                enable32BitAppOnWin64="" 
                managedPipelineMode="" 
                applicationPool="" 
                appExists="False" />
            <contentPath path="c:\inetpub\wwwroot\site">
                <dirPath 
                    path="c:\inetpub\wwwroot\site" 
                    securityDescriptor="D:" 
                    parentSecurityDescriptors="" 
                    attributes="Directory">
                    <filePath 
                        path="index.html" 
                        size="0" 
                        attributes="Archive" 
                        lastWriteTime="07/07/2011 20:58:00" 
                        securityDescriptor="D:" />
                </dirPath>
            </contentPath>
        </iisApp>
    </MSDeploy.iisApp>
</output>

我已将iisAppcreateApp提供程序路径属性更改为Default Web Site\Site. 我将contentPathdirPath提供程序路径属性更改为c:\inetpub\wwwroot\site.


问题

  • 我怎样才能做到这一点?
4

4 回答 4

18

您需要查看 MS Deploy 替换规则,这是一个很好地隐藏在 MS Deploy 团队博客中的有用功能。

在您的情况下,您将需要使用一堆替换表达式来扩展命令行,如下所示:

msdeploy.exe 
-verb:sync 
-source:iisApp=c:\content\ 
-dest:package=c:\pkg.zip
-replace:objectName=iisApp,targetAttributeName=path,
         replace="Default Website\Site"
-replace:objectName=createApp,targetAttributeName=path,
         replace="Default Website\Site"
-replace:objectName=contentPath,targetAttributeName=path,
         replace="c:\inetpub\wwwroot\site"
-replace:objectName=dirPath,targetAttributeName=path,match="^c:\content",
         replace="c:\inetpub\wwwroot\site"

运行它应该会产生您想要的输出。

在上面的示例中,前 3 个替换规则按标记名称 ( objectName) 和属性名称 ( targetAttributeName) 匹配,并用指定的替换字符串覆盖。dirPath最后一个替换规则将匹配以“c:\content”开头的所有标记的所有路径属性,并且仅将属性值的那部分替换为替换字符串。

最后,我还没有找到避免包 zip 文件包含原始源文件夹名称的方法。唯一的解决方法是从一个中立的临时位置(如“c:\site”)打包。

所以程序是:

  • 将你的东西复制到一个中立的临时位置。
  • 从这里创建你的包。
  • 使用verb:dump 查看生成的xml。
  • 再次创建您的包,并为您想要在包中更改的所有内容添加替换规则。
  • 服用头痛药;-)
于 2011-08-04T22:50:19.130 回答
5

我或多或少有同样的问题。

第一件事:

特定于部署机器的长路径

为此,我使用了在http://sedodream.com/2013/01/13/WebPackagingFixingTheLongPathIssue.aspx找到的技巧

正如帖子中所建议的,可以在项目的Properties/PublishProfiles文件夹下修改所需的(可以有多个) .pubxml 文件。这是我遵循的方法,因为它允许我自定义每个发布配置文件的行为。

如果我没记错的话,我相信您可以对项目根目录上的{project-name}.wpp.targets文件(可能尚不存在)应用相同的修改。但是,此处的更改会影响Web 发布管道(wpp),从而影响项目中找到的所有发布配置文件。

然而...

当需要用发布配置文件提供的连接字符串替换连接字符串时,这种方法将破坏您的部署。原因:上述技巧不会影响连接字符串,因为它们是由 wpp 在构建时自动创建的。嗯!

我为该问题找到的解决方案是双重的:

1.) 创建了一个parameters.xml文件,我在其中手动声明了连接字符串。好的,也许我从包的 .zip 文件中的 parameters.xml 文件中复制了它们,因为我正在部署到包。这有帮助。

它们看起来像这样:

<parameter name="myConnection-Web.config Connection String" defaultValue="" tags="SqlConnectionString" 
        description="myConnection Connection String used in web.config by the application to access the database.">
    <parameterEntry kind="XmlFile" scope="DeploymentPackage\\Web\.config$" match="/configuration/connectionStrings/add[@name='myConnection']/@connectionString" />
</parameter>

2.) 在我们之前修改的同一个.pubxml文件的顶部包含以下行

<AutoParameterizationWebConfigConnectionStrings>false</AutoParameterizationWebConfigConnectionStrings>

还有……瞧!

创建国际空间站应用程序

希望通过上述方法,您声明了几个参数,包括连接字符串。

但是,当您创建一个包时,无论您是否创建了 parameters.xml,都会为您创建一个*.SetParameters.xml 模板文件。在其中,您将看到“IIS Web 应用程序名称”作为第一个参数,它将默认为您在发布配置文件中插入的任何内容。你可以改变它;随心所欲。

还记得我之前说的模板吗?我是认真的;它只是一个模板。您假设获取该*.SetParameters.xml文件并根据需要制作尽可能多的副本。它们是干什么用的?环境相关参数。你可以有一个:

  • DEV.SetParameters.xml
  • QA.SetParameters.xml
  • 暂存.SetParameters.xml
  • Production.SetParameters.xml
  • ... 等等等等

然后使用最适合工作(或环境)的参数文件,如下所示:

{yourProjectName}.deploy.cmd /Y /M:{targetServer} [...] -setParamFile:QA.SetParameters.xml

或者它的等效 MsDeploy 命令行当然。

现在,默认情况下,在构建时为您创建的清单,并存储在您的包中的archive.xml文件下,将首先使用iisApp提供程序。这很好,因为这个提供程序与createApp提供程序不同,如果目录不存在,它实际上会为您创建目录。至少根据 TechNet 的这份说明:

“与 iisApp 提供程序不同,如果新应用程序的物理文件夹不存在,则 createApp 提供程序不会在父站点的文件夹下创建物理文件夹;它只会在配置中创建对此类文件夹的引用。如果需要创建一个物理文件夹,您必须在使用 createApp 之前或之后手动创建它。因此,您通常应该改用 iisApp 提供程序。iisApp 提供程序是更合适的选择,因为它使用 createApp 提供程序作为初始步骤一系列步骤,包括在配置中创建应用程序、为应用程序创建物理文件夹(如果该文件夹不存在)以及将内容文件复制到新应用程序的文件夹中。”

我很乐意包含这些链接……但由于我没有 10 多分,所以每个帖子只能获得 1 分。去搞清楚!:)

所以,简而言之...

...通过第一部分完成的工作,您可能不需要做太多事情就可以在部署时在目标服务器中创建文件夹。

如果您确实需要覆盖它,您可以定义自己的清单文件并部署它(一个单独的主题)......或者您可以遵循@peter_raven 的建议并使用-Replace来自 MsDeploy 的规则覆盖它的值。

任何一个都可以作为一种魅力。

于 2014-01-28T00:59:23.520 回答
4

通过提供如下所示的种类、范围和匹配属性来删除包前缀:

"msdeploy.exe" \
     -verb:sync                                                   \
     -source:iisApp="[Path to your website contents]"             \
     -declareParam:name="IIS Web Application Name",kind="ProviderPath",scope="IisApp",match="^C:\\path\\to\\your\\site\\folder",defaultValue="Default Web Site/SomeSite"  \
     -dest:package=[WebDeployPackageName].zip
于 2015-06-22T20:48:09.143 回答
1

在使用@SkyFighter 的解决方案时,我设法解决了手动定义的连接字符串的问题。现在可以使用自动参数化功能,并让连接字符串参数具有正确的范围。

幸运的是,WPP 内部有一个地方可以注入。不幸的是,我不得不使用AfterTarget / BeforeTarget而不是SomeTargetDependsOn变量来缩小新目标的位置。

这是目标本身:

<Target Name="Replace_WebConfigsToAutoParmeterizeCS_TransformScope"
        AfterTargets="PreAutoParameterizationWebConfigConnectionStrings"
        BeforeTargets="AutoParameterizationWebConfigConnectionStringsCore"
        Condition=" '$(EnableAddReplaceToUpdatePacakgePath)'=='true' ">
  <ItemGroup>
    <_WebConfigsToAutoParmeterizeCS>
      <TransformScope>$([System.String]::Copy('%(TransformScope)').Replace('$([System.IO.Path]::GetFullPath($(WPPAllFilesInSingleFolder)))', '$(PackagePath)'))</TransformScope>
    </_WebConfigsToAutoParmeterizeCS>
  </ItemGroup>
</Target>

它由与赛义德样本中相同的变量驱动,用于修复长路径。所以把这个目标放在那些已经可用的变量的任何地方。

PS 这个技巧/hack 至少需要 MSBuild v3.5,其中首次引入了元数据操作。

于 2015-04-09T09:30:40.603 回答