使用msdeploy创建包时,为iisApp提供程序指定不同的路径

20

如何制作软件包

我是这样制作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

如果我这样倾倒(package dump)包:

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个回答

19
你需要查看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"

运行此命令应生成所需的输出。

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

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

因此,步骤如下:

  • 将您的内容复制到中性的临时位置。
  • 从这里创建您的软件包。
  • 使用verb:dump查看生成的xml。
  • 再次创建软件包,并添加对软件包中想要更改的所有内容的替换规则。
  • 吃一颗头痛药 ;-)

5

我遇到了几乎相同的问题。

首要任务:

长的、机器特定的部署路径

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

如帖子所建议的,您可以在项目中的属性/发布配置文件文件夹下修改所需(可以有多个.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>

然后... 就这样了!

创建 ISS 应用程序

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

但是,当您创建一个软件包时,不管您是否创建了 parameters.xml 文件,都会为您创建一个*.SetParameters.xml文件模板。在其中,您将看到第一个参数为“ IIS Web 应用程序名称”,默认情况下为您在发布配置文件中插入的内容。您可以更改它,使其为任何您想要的内容。

记得我之前说过模板吗?我是认真的;它只是一个模板。您应该根据需要复制*.SetParameters.xml文件。这些文件是用于环境相关参数的。您可以有:

  • DEV.SetParameters.xml
  • QA.SetParameters.xml
  • Staging.SetParameters.xml
  • Production.SetParameters.xml
  • ...等等

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

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

默认情况下,由构建时间为您创建的清单并存储在archive.xml文件下的包中,将首先使用提供程序。这很好,因为这个提供程序与提供程序不同,如果目录不存在,它实际上会为您创建一个目录。至少根据TechNet的注释:
“与iisApp提供程序不同的是,如果新应用程序的物理文件夹不存在,则createApp提供程序不会在父站点的文件夹下创建物理文件夹;它只会在配置中创建对这样一个文件夹的引用。如果您想要创建物理文件夹,您必须在使用createApp之前或之后手动创建它。出于这个原因,您通常应该使用iisApp提供程序。 iisApp提供程序是更合适的选择,因为它使用createApp提供程序作为一系列步骤的初始步骤,包括在文件夹不存在的情况下创建应用程序的物理文件夹以及将内容文件复制到新应用程序的文件夹中。”
简而言之,通过第一部分完成的工作,您可能不需要做太多工作就可以在目标服务器上在部署时间创建文件夹。
如果需要覆盖该值,您可以定义自己的清单文件并从其进行部署(另一个主题)...或者您可以按照@peter_raven的建议使用MsDeploy的-Replace规则来覆盖其值。
两个方法都会非常好地运作。

稍微加分,因为这指引了我正确的方向。谢谢。 - MonkeyWrench

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

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>

它由与Sayed样本中修复长路径相同的变量驱动。因此,将此目标放置在任何已经可用这些变量的地方。
附注:此技巧/黑客需要至少MSBuild v3.5,其中首次引入了元数据操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接