将其他内容文件夹添加到 Azure 包

Adding additional content folders to Azure package

我正在使用 Azure SDK 2.5 我在云服务项目中担任网络角色。我想以某种方式添加一个文件夹,以便将其部署在 approot 的父目录中。我还没有找到一种方法来做到这一点,这让我想知道在 csdef 中定义虚拟目录的能力有什么用。

所以我想我会尝试通过 csdef 中的 Contents/Content xml 配置添加文件夹。我要么从根本上误解了这个配置的作用,要么它彻底崩溃了。

假定此文件夹结构

  /
    /CloudService
    /SomeOtherContent

如果我定义如下:

<Contents>
      <Content destination="frontend">
        <SourceDirectory path="..\SomeOtherContent" />
      </Content>
    </Contents>

构建我得到:

error CloudServices089: Cannot find the source directory 'C:\src\template\src\Template.CloudService\bin\Debug\..\SomeOtherContent'

好的,它开始了 bin\Debug,所以我就让它 ..\..\..\SomeOtherContent

error CloudServices089: Cannot find the source directory 'C:\src\template\src\Template.CloudService\..\..\..\SomeOtherContent'

没错,我的相对路径解析的文件夹变了!!!它不再是 bin\Debug。卧槽!?如何让它发挥作用?如果我输入一个完整的驱动器限定绝对路径,它就会工作。

所以我通过让 MSBuild 解析路径并将其推送到我称为 FrontendDir 的环境变量来解决这个问题。

<Contents>
      <Content destination="frontend">
        <SourceDirectory path="%FrontendDir%" />
      </Content>
    </Contents>

我在 ccproj 中添加了:

<UsingTask
    TaskName="SetEnvironmentVariableTask"
    TaskFactory="CodeTaskFactory"
    AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v$(MSBuildToolsVersion).dll">

    <ParameterGroup>
      <Name ParameterType="System.String" Required="true" />
      <Value ParameterType="System.String" Required="true" />
    </ParameterGroup>

    <Task>
      <Using Namespace="System" />
      <Code Type="Fragment" Language="cs">
        <![CDATA[
          Environment.SetEnvironmentVariable(Name, Value);
        ]]>
      </Code>
    </Task>
  </UsingTask>
  <Target Name="BeforeBuild" Condition=" '$(FrontendDir)' == '' ">
    <Message Text="Setting Project Dir" Importance="high" />
    <SetEnvironmentVariableTask Name="FrontendDir" Value="$(ProjectDir)\..\Template.FrontEnd\dist" />
  </Target>

最好将整个路径放在此处的环境变量中,因为您可以通过覆盖值(例如 /p:FrontendDir="c:\foo")在不同的构建场景中轻松覆盖它

这样就可以了,而且效果还不错。我仍然说我之前看到的改变文件夹的相对路径分辨率的行为是......坏了。它只是不能以任何可用的方式使用相对路径。

您看到了相同的错误,但来自不同的 msbuild 目标。

第一个错误(使用 ..\..\ 时)在 PreValidateServiceModel 处抛出,它传入源位置并检查路径

ServiceDefinitionFile="@(SourceServiceDefinition)"
ServiceConfigurationFile="@(SourceServiceConfiguration)"

C:\src\Azure\ServiceDefinition.csdef : error CloudServices089: Cannot find the source directory 'C:\src\Azure\..\..\Installers\' in role WebHost. [C:\src\Azure\Azure.ccproj]

Done building target "PreValidateServiceModel" in project "Azure.ccproj" -- FAILED.

第二个错误在 ValidateServiceFiles 处抛出,该错误传入目标位置

ServiceDefinitionFile="@(TargetServiceDefinition)"
ServiceConfigurationFile="@(TargetServiceConfiguration)">

C:\src\Azure\bin\Release\ServiceDefinition.csdef : error CloudServices089: Cannot find the source directory 'C:\src\Azure\bin\Release\Installers\' in role WebHost. [C:\src\Azure\Azure.ccproj]

Done building target "ValidateServiceFiles" in project "Azure.ccproj" -- FAILED.

如果你反思C:\ProgramFiles\MicrosoftSDKs\Azure.NETSDK\v2.9\bin\ServiceDescription.dll你可以请参阅 ProcessRoleContents 方法进行验证,但使用 SourceFile 来解析位置。

一个选项是在构建开始之前确保目标文件夹存在(即使是空的)。

如果 PreValidation 解析了路径,并且在保存 Target 时,它具有完整路径,那就更好了。

我最终编辑了 ccproj,并添加了这个

<Target Name="BeforeAddRoleContent">
    <ItemGroup>
      <AzureRoleContent Include="Installers\">
        <RoleName>Azure</RoleName>
        <Destination></Destination>
      </AzureRoleContent>
    </ItemGroup>
</Target>