我在visual studio 2017
中有一个发布配置文件我正在尝试从另一个项目中复制文件。转到简单的相对目录时没有问题。但是,在源中进行双递归时会出现问题,这使得确定所需目录变得更加困难。
源目录:$(MSBuildThisFileDirectory)..\..\..\..Foundation\**\App_Config\**\*
为我提供相关文件。
使用<DestinationRelativePath />
%(RecursiveDir)%(Filename)%(Extension)
部署到:\**\App_Config\**\*
。
不是我的愿望:\App_Config\**\*
我错过了<DestinationRelativePath>
无法部署到我想要的位置的技巧。我哪里错了?或者这不可能吗?
<PropertyGroup>
<PipelineCollectFilesPhaseDependsOn>
GetFoundationConfigFiles;
GetProjectConfigFiles;
$(PipelineCollectFilesPhaseDependsOn);
</PipelineCollectFilesPhaseDependsOn>
</PropertyGroup>
<Target Name="GetFoundationConfigFiles">
<Message Text="Inside of GetFoundationConfigFiles" Importance="high"/>
<ItemGroup>
<_CustomFiles Include="$(MSBuildThisFileDirectory)..\..\..\..\Foundation\**\App_Config\**\*" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>App_Config\Include\%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
<Target Name="GetProjectConfigFiles">
<Message Text="Inside of GetProjectConfigFiles" Importance="high"/>
<ItemGroup>
<_CustomFiles1 Include="$(MSBuildThisFileDirectory)..\..\..\..\Feature\**\App_Config\**\*" />
<FilesForPackagingFromProject Include="%(_CustomFiles1.Identity)">
<DestinationRelativePath>%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
答案 0 :(得分:1)
决定执行Powershell是最好的选择。我没有进行Web部署,而是在Visual Studio 2017中切换到文件系统发布。
使用发布配置文件我执行powershell脚本,传递两个参数。
最棒的是我可以登记我的.pubxml并使用非托管文件的.pubxml.user来定义2)。这允许每个开发人员在本地使用相同的发布配置文件。
如果有人知道如何在发布配置文件中使用自定义变量,那么当前调用命令时,仅限于发布我们的发布配置文件。
发布个人资料.pubxml
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<PublishProvider>FileSystem</PublishProvider>
<LastUsedBuildConfiguration>Debug</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<DeleteExistingFiles>False</DeleteExistingFiles>
<PipelineDependsOn>
CopyAssets;
$(PipelineDependsOn);
</PipelineDependsOn>
</PropertyGroup>
<Target Name="CopyAssets">
<Message Text="Inside of CopyAssets" Importance="high"/>
<Exec Command="%WINDIR%\System32\WindowsPowerShell\v1.0\powershell.exe -File "$(SolutionDir)Foundation\Scripts\Powershell\CopyAssets.ps1" $(SolutionDir) $(publishUrl)"/>
</Target>
</Project>
发布个人资料.pubxml.user
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<TimeStampOfAssociatedLegacyPublishXmlFile />
<_NewBackgroundProfile>False</_NewBackgroundProfile>
<_PublishTargetUrl>C:\inetpub\wwwroot\mywebapp</_PublishTargetUrl>
</PropertyGroup>
</Project>
<强> CopyAssets.ps1 强>
#
# CopyAssets.ps1
#
[CmdletBinding()]
Param(
[Parameter(Mandatory=$True)]
[string]$solutionDirectory,
[Parameter(Mandatory=$True)]
[string]$copyTo
)
#
# Copy Assets Initializations
#
# Absolute path to copy files to and create folders in
$absolutePath = @($copyTo + "/App_Config/Include")
# Set paths we will be copy files from
$featureDirectory = Join-Path $solutionDirectory "/Feature/*/App_Config/Include"
$foundationDirectory = Join-Path $solutionDirectory "/Foundation/*/App_Config/Include"
function Create-Files {
Param ([string]$currentPath, [string]$pathTo)
Write-Host "Attempting to create files..."
# Copy files from root include folder
$files = Get-ChildItem -Path $currentPath | Where-Object {$_.PSIsContainer -eq $false}
foreach ($file in $files)
{
Write-Host "Attempting to copy file:"$file "to"$path
New-Item -ItemType File -Path $pathTo -Name $file.Name -Force
}
}
# Logic to create new directories and copy files over.
function Copy-Assets {
Param ([string]$directoryBase)
$path = $absolutePath
Write-Host "Directory copying from:" $directoryBase
Write-Host "Creating files found in include folder"
# Path hack to copy files from directoryBase
$directoryBaseHack = Join-Path $directoryBase "\*"
Create-Files -currentPath $directoryBaseHack -pathTo $path
Write-Host "Getting sub directories to copy from"
$directories = Get-ChildItem -Path $directoryBase -Recurse | Where-Object {$_.PSIsContainer -eq $true}
Write-Host "Iterating through directories"
foreach ($directory in $directories)
{
Write-Host "Checking if directory"$directory.Name "is part of absolute path."
if($absolutePath -match $directory.Name)
{
# checking if directory already exists
Write-Host "Directory is part of absolute path, confirming if path exists"
$alreadyExists = Test-Path $absolutePath
if(!$alreadyExists)
{
Write-Host "Absolute path doesn't exist creating..."
New-Item -ItemType Directory -Path $absolutePath -Force
Write-Host "All directories in path for Absolute Path created:"$absolutePath
}
Write-Host "Directory for"$directory.Name "already exists as it is part of the Absolute Path:" $absolutePath
}else{
Write-Host "Joining path with absolute path"
$path = Join-Path $absolutePath $directory.Name
Write-Host "Joined path:"$path
Write-Host "Does joined path exist:"$path
$alreadyExists = Test-Path $path
if(!$alreadyExists)
{
Write-Host "Joined path doesn't exist creating..."
New-Item -ItemType Directory -Path $path -Force
Write-Host "Created new directory:" $path
}
Write-Host "Directory for"$path "already exists."
}
Write-Host "Creating files found in:" $directory
Create-Files -currentPath $directory -pathTo $path
}
}
Write-Host "Starting Copying Foundation Files"
Copy-Assets -directoryBase $foundationDirectory
Write-Host "Starting Copying Feature Files"
Copy-Assets -directoryBase $featureDirectory
答案 1 :(得分:0)
我错过了我在胜利部署到我想要的位置的技巧。我哪里错了?或者这不可能吗?
在内部双递归中使用过滤器和合并似乎是不可能的。
众所周知,\**\*.*
有助于从所有文件夹中获取文件。 RecursiveDir
有助于将所有文件放在相应的文件夹中。当您使用**\App_Config\**
从所有父文件夹和子文件夹中获取文件时,RecursiveDir
将通过双重递归将所有文件放在相应的文件夹(父文件夹和子文件夹)中。我们无法在递归过程中插入过滤器和合并。我们可以做的是将所有这些文件发布到一个文件夹:
<Target Name="GetProjectConfigFiles">
<Message Text="Inside of GetProjectConfigFiles" Importance="high"/>
<ItemGroup>
<_CustomFiles1 Include="$(MSBuildThisFileDirectory)..\..\..\..\Feature\**\App_Config\**\*" />
<FilesForPackagingFromProject Include="%(_CustomFiles1.Identity)">
<DestinationRelativePath>App_Config%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
不确定这个结果是否符合您的要求,如果您想获取没有父文件夹的所有文件,看起来应该在获取所有文件时指定父文件夹:
<Target Name="GetFoundationConfigFiles">
<Message Text="Inside of GetFoundationConfigFiles" Importance="high"/>
<ItemGroup>
<_CustomFiles Include="$(MSBuildThisFileDirectory)..\..\..\..\Foundation\Test1\App_Config\**\*" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>App_Config%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>