MSBuild error executing target WebDirectoryCreate - iis

I'm trying to use the WebDirectoryCreate task from the MSBuildCommunityTasks to create my virtual directory with MSBuild but it throws an Index was out of range error.
Here's the relevant part of my build script:
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
...other build targets working ok...
<Target Name="Deploy">
<RemoveDir Directories="$(DeploymentFolder)$(VerRevision)" ContinueOnError="true" />
<ItemGroup>
<DeploymentFiles Include="$(PublishOutputFolder)\**\*.*" />
</ItemGroup>
<Copy SourceFiles="#(DeploymentFiles)" DestinationFolder="$(DeploymentFolder)$(VerRevision)\%(RecursiveDir)" />
<WebDirectoryDelete VirtualDirectoryName="$(VirtualDirectory)$(VerRevision)" ContinueOnError="true" />
<WebDirectoryCreate VirtualDirectoryName="$(VirtualDirectory)$(VerRevision)" VirtualDirectoryPhysicalPath="$(DeploymentFolder)$(VerRevision)" />
</Target>
And here's the corresponding output:
Deleting virtual directory 'MyApp283' on 'localhost:80'.
MSBUILD : warning : The system cannot find the path specified. (Exception from HRESULT: 0x80070003) [D:\build\MyApp\Build.xml]
The previous error was converted to a warning because the task was called with ContinueOnError=true.
Build continuing because "ContinueOnError" on the task "WebDirectoryDelete" is set to "true".
Creating virtual directory named MyApp283 on localhost:
D:\build\MyApp\Build.xml(50,5): error : Index was out of range. Must be non-negative and less than the size of the collection.
D:\build\MyApp\Build.xml(50,5): error : Parameter name: index
Done Building Project "D:\build\MyApp\Build.xml" (default targets) -- FAILED.
Build FAILED.
I have checked the import is correct by adding the virtual directory manually and running the build. In this case the WebDirectoryDelete task corrcetly deletes the virtual directory but WebDirectoryCreate throws the same error.
I'm executing the build using MSBuild from a simple batch file. All tasks before this one execute just fine. OS is Windows Server 2008 R2 Enterprise Edition SP1.
Can anyone give me any clues? SO and Google threw up one single link with no answer.

Related

Cannot run PowerShell scripts in Azure Functions v2

I'm trying to write a Function App using .NET Core in Azure Functions v2. When using the Microsoft.Powershell.SDK package from Nuget (required for .NET Core PowerShell runtime) I cannot get Visual Studio to copy the System.Management.Automation library to the bin with my Function App.
This results in the following error:
System.Private.CoreLib: Exception while executing function: Function1. TestPowershellInFunction: Could not load file or assembly 'System.Management.Automation, Version=6.1.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified. System.Private.CoreLib: Could not load the specified file.
I've reproduced this in an existing Azure Function and a new Solution by simply creating a Timer function and adding the following snippet:
PowerShell shell = PowerShell.Create();
IEnumerable<PSObject> result = shell.AddScript("Write-Output 'Hello, World!'").Invoke();
foreach(PSObject line in result)
{
log.LogInformation(line.ToString());
}
This works on a new Console App with the PowerShell Nuget installed, but when added to the Function App I get the error. I do notice that System.Management.Automation doesn't get put in the bin directory with a regular Console App but I'm not sure how to interpret this. I know it's a System library but I can't use it unless the Nuget is installed, so I don't know if this is a special case. In both scenarios I'm using v6.1.1 of the PowerShell Nuget.
Is this a known bug with Functions v2? Or am I missing something?
It's a known issue that Function can't load runtime assemblies([FunctionProject]\bin\Debug\netcoreapp2.1\bin\runtimes) correctly.
The workaround is to move assemblies to output dir bin manually. Right click on your function project and Edit <FunctionProject>.csproj. Add following items to achieve our goal.
<PropertyGroup>
<SDKVersion>6.1.1</SDKVersion>
<SDKPlatform>win-x86</SDKPlatform>
</PropertyGroup>
<ItemGroup>
<None Include="
$(USERPROFILE)\.nuget\packages\system.directoryservices\4.5.0\runtimes\win\lib\netcoreapp2.0\System.DirectoryServices.dll;
$(USERPROFILE)\.nuget\packages\system.management\4.5.0\runtimes\win\lib\netcoreapp2.0\System.Management.dll;
$(USERPROFILE)\.nuget\packages\system.management.automation\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\System.Management.Automation.dll;
$(USERPROFILE)\.nuget\packages\microsoft.management.infrastructure\1.0.0\runtimes\win10-x86\lib\netstandard1.6\Microsoft.Management.Infrastructure.dll;
$(USERPROFILE)\.nuget\packages\microsoft.powershell.commands.management\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.Commands.Management.dll;
$(USERPROFILE)\.nuget\packages\microsoft.powershell.commands.utility\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.Commands.Utility.dll;
$(USERPROFILE)\.nuget\packages\microsoft.powershell.commands.diagnostics\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.Commands.Diagnostics.dll;
$(USERPROFILE)\.nuget\packages\microsoft.powershell.sdk\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.SDK.dll;
$(USERPROFILE)\.nuget\packages\microsoft.powershell.security\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.Security.dll;
$(USERPROFILE)\.nuget\packages\microsoft.powershell.coreclr.eventing\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.CoreCLR.Eventing.dll;
$(USERPROFILE)\.nuget\packages\microsoft.powershell.consolehost\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.ConsoleHost.dll;
$(USERPROFILE)\.nuget\packages\microsoft.powershell.markdownrender\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.MarkdownRender.dll;
$(USERPROFILE)\.nuget\packages\microsoft.wsman.runtime\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.WSMan.Runtime.dll;
$(USERPROFILE)\.nuget\packages\microsoft.wsman.management\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.WSMan.Management.dll;
">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<Target Name="CopyRuntimeToBin" AfterTargets="Build">
<Copy SourceFiles="
$(USERPROFILE)\.nuget\packages\system.directoryservices\4.5.0\runtimes\win\lib\netcoreapp2.0\System.DirectoryServices.dll;
$(USERPROFILE)\.nuget\packages\system.management\4.5.0\runtimes\win\lib\netcoreapp2.0\System.Management.dll;
$(USERPROFILE)\.nuget\packages\system.management.automation\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\System.Management.Automation.dll;
$(USERPROFILE)\.nuget\packages\microsoft.management.infrastructure\1.0.0\runtimes\win10-x86\lib\netstandard1.6\Microsoft.Management.Infrastructure.dll;
$(USERPROFILE)\.nuget\packages\microsoft.powershell.commands.management\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.Commands.Management.dll;
$(USERPROFILE)\.nuget\packages\microsoft.powershell.commands.utility\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.Commands.Utility.dll;
$(USERPROFILE)\.nuget\packages\microsoft.powershell.commands.diagnostics\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.Commands.Diagnostics.dll;
$(USERPROFILE)\.nuget\packages\microsoft.powershell.sdk\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.SDK.dll;
$(USERPROFILE)\.nuget\packages\microsoft.powershell.security\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.Security.dll;
$(USERPROFILE)\.nuget\packages\microsoft.powershell.coreclr.eventing\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.CoreCLR.Eventing.dll;
$(USERPROFILE)\.nuget\packages\microsoft.powershell.consolehost\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.ConsoleHost.dll;
$(USERPROFILE)\.nuget\packages\microsoft.powershell.markdownrender\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.MarkdownRender.dll;
$(USERPROFILE)\.nuget\packages\microsoft.wsman.runtime\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.WSMan.Runtime.dll;
$(USERPROFILE)\.nuget\packages\microsoft.wsman.management\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.WSMan.Management.dll;
" DestinationFolder="$(OutputPath)\bin" />
</Target>
Note that microsoft.management.infrastructure is set to win10-x86 on my side(Win10), you may need to change according to your pc platform. Assemblies are x86 as VS uses x86 Function CLi by default, we don't need to worry about it unless we need to work with x64.

Publish of ASP.Net Core project fails with "DestinationFiles" refers to 1 item(s), and "SourceFiles" refers to 2 item(s)

Publish of ASP.Net Core project fails with next error:
"DestinationFiles" refers to 1 item(s), and "SourceFiles" refers to 2 item(s).
They must have the same number of items.
I get an error when I try to publish an ASP.Net Core website to Azure. It builds and runs fine locally. The output prints this:
Task "Copy"
Task Parameter:
SourceFiles=
C:\Users\Mikael\Source\Repos\GoMap-Web\src\Web\appsettings.json
CopyToPublishDirectory=PreserveNewest
RelativePath=appsettings.json
TargetPath=appsettings.json
C:\Users\Mikael\Source\Repos\GoMap-Web\src\Web\appsettings.json
CopyToPublishDirectory=PreserveNewest
RelativePath=appsettings.json
TargetPath=appsettings.json
Task Parameter:DestinationFiles=C:\Users\Mikael\Source\Repos\GoMap-Web\src\Web\obj\Release\netcoreapp1.0\PublishTemp\PublishOutput\appsettings.json
Task Parameter:OverwriteReadOnlyFiles=False
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Publish.targets(100,5): Error MSB3094: "DestinationFiles" refers to 1 item(s), and "SourceFiles" refers to 2 item(s). They must have the same number of items.
Output Item(s): FileWrites=C:\Users\Mikael\Source\Repos\GoMap-Web\src\Web\obj\Release\netcoreapp1.0\PublishTemp\PublishOutput\appsettings.json
Done executing task "Copy" -- FAILED.
Done building target "_CopyResolvedFilesToPublishPreserveNewest" in project "Web.csproj" -- FAILED.
Done building project "Web.csproj" -- FAILED.
The Microsoft.NET.Publish.targets file (the relevant part, i belive) look like this:
============================================================
CopyFilesToPublishDirectory
Copy all build outputs, satellites and other necessary files to the publish directory.
============================================================
-->
<Target Name="CopyFilesToPublishDirectory"
DependsOnTargets="_CopyResolvedFilesToPublishPreserveNewest;
_CopyResolvedFilesToPublishAlways" />
<!--
============================================================
_CopyResolvedFilesToPublishPreserveNewest
Copy _ResolvedFileToPublishPreserveNewest items to the publish directory.
============================================================
-->
<Target Name="_CopyResolvedFilesToPublishPreserveNewest"
DependsOnTargets="_ComputeResolvedFilesToPublishTypes"
Inputs="#(_ResolvedFileToPublishPreserveNewest)"
Outputs="#(_ResolvedFileToPublishPreserveNewest->'$(PublishDir)%(RelativePath)')">
<!--
Not using SkipUnchangedFiles="true" because the application may want to change
one of these files and not have an incremental build replace it.
-->
<Copy SourceFiles = "#(_ResolvedFileToPublishPreserveNewest)"
DestinationFiles="#(_ResolvedFileToPublishPreserveNewest -> '$(PublishDir)%(RelativePath)')"
OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
Retries="$(CopyRetryCount)"
RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
UseHardlinksIfPossible="$(CreateHardLinksForPublishFilesIfPossible)"
UseSymboliclinksIfPossible="$(CreateSymbolicLinksForPublishFilesIfPossible)">
<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
</Copy>
</Target>
<!--
============================================================
_CopyResolvedFilesToPublishAlways
Copy _ResolvedFileToPublishAlways items to the publish directory.
============================================================
-->
<Target Name="_CopyResolvedFilesToPublishAlways"
DependsOnTargets="_ComputeResolvedFilesToPublishTypes">
<!--
Not using SkipUnchangedFiles="true" because the application may want to change
one of these files and not have an incremental build replace it.
-->
<Copy SourceFiles = "#(_ResolvedFileToPublishAlways)"
DestinationFiles="#(_ResolvedFileToPublishAlways -> '$(PublishDir)%(RelativePath)')"
OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
Retries="$(CopyRetryCount)"
RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
UseHardlinksIfPossible="$(CreateHardLinksForPublishFilesIfPossible)"
UseSymboliclinksIfPossible="$(CreateSymbolicLinksForPublishFilesIfPossible)">
<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
</Copy>
</Target>
I have changed the DestinationFiles="#(_ResolvedFileToPublishPreserveNewest -> '$(PublishDir)%(RelativePath)')" according to another post here but I still get the same failure, and I don't know enough about it to find any clear errors, can anyone offer some insight? If this is affected by the bug mentioned in other posts that has no workaround, what alternative ways could I try to publish the app to azure that might work better?

Ant Tomcat: Failed to create task or type "list"

I am using Spring official docs to understand the Spring Basic Application and Environment set up on Linux using Ant.
Softwares and system configurations:
OS: Linux/Ubuntu
JRE: 1.8.0_51-b16
Ant Version: 1.9.3
IDE: Luna Service Release 1 (4.4.1)
Project directory structure:
Everything goes fine till end of Section 1.3 where I can start the tomcat server and execute ant, ant deploy successfully and I have the desired output as follows:
But when I am trying to execute ant list - the build fails.
Buildfile: /home/sandeep/MyDocs/workspace/springapp/build.xml
list:
BUILD FAILED
/home/sandeep/MyDocs/workspace/springapp/build.xml:113: Problem: failed to create task or type list
Cause: The name is undefined.
Action: Check the spelling.
Action: Check that any custom tasks/types have been declared.
Action: Check that any / declarations have taken place.
Here is the list target in my build.xml:
<target name="list" description="List Tomcat applications">
<list url="${tomcat.manager.url}"
username="${tomcat.manager.username}"
password="${tomcat.manager.password}"/>
</target>
What am I doing wrong here? Here is a link to my entire build.xml.
In the article you linked to, it shows how to add the <list> task:
<taskdef name="list" classname="org.apache.catalina.ant.ListTask">
<classpath refid="catalina-ant-classpath"/>
</taskdef>
Add the above line to your build.xml.
I think task list is unknown to ant. There is no task named list defined by ant. To start tomcat I did something like --
<exec executable="${tomcat.home}/bin/tomcat5.exe" >
<arg value="start"/>
<env key="JAVA_OPTS"
value="-Xint -Xdebug -Xrunjdwp:transport=dt_socket,address=${hotswap.port},server=y,suspend=n"/>
</exec>
</target>

Adding additional content folders to Azure package

Im using Azure SDK 2.5
I have a web role in a cloud service project. I would like to add a folder in some fashion such that it is deployed in the parent directory of the approot. I havent found a way to do this which kind of makes me wonder what use is the ability to define virtual directories in csdef.
So I thought I would try adding folders via the Contents/Content xml config in the csdef. I am either fundamentally misunderstanding what this bit of config does or its hopelessly broken.
Assuming this folder structure
/
/CloudService
/SomeOtherContent
If I define the following:
<Contents>
<Content destination="frontend">
<SourceDirectory path="..\SomeOtherContent" />
</Content>
</Contents>
and build I get:
error CloudServices089: Cannot find the source directory
'C:\src\template\src\Template.CloudService\bin\Debug\..\SomeOtherContent'
Ok so its starting the bin\Debug, so I'll just make it ..\..\..\SomeOtherContent
error CloudServices089: Cannot find the source directory
'C:\src\template\src\Template.CloudService\..\..\..\SomeOtherContent'
Yes thats right, the folder at which my relative path is resolved has changed!!! Its no longer bin\Debug. Wtf!? How can this be made to work? It works if i enter a full drive qualified absolute path.
So I solved this by having MSBuild resolve the path and push it in to an environment variable which I called FrontendDir.
<Contents>
<Content destination="frontend">
<SourceDirectory path="%FrontendDir%" />
</Content>
</Contents>
and in the ccproj I added:
<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>
Its preferable to put the entire path into the env var here as you can then override it easily in your different build scenarios by overriding the value (eg. /p:FrontendDir="c:\foo")
So that works and works fairly well. I still say the behaviour I was seeing before with the relative path resolution changing folders is... broken. It just doesn't work with relative paths in any usable way.
You are seeing the same error but from different msbuild targets.
The first error (when using ..\..\) is thrown at PreValidateServiceModel which passes in the Source location and checks the path
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.
The second error is thrown at ValidateServiceFiles which passes in the Target location
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.
If you reflect on C:\Program Files\Microsoft SDKs\Azure.NET SDK\v2.9\bin\ServiceDescription.dll you can see the ProcessRoleContents method doing the validation but using the SourceFile to resolve the location.
One option is to make sure the target folder exists (even if empty) before the build starts.
It would be better if the PreValidation resolved the path and when the Target is saved, it had the full path.
I ended up editing the ccproj, and adding this
<Target Name="BeforeAddRoleContent">
<ItemGroup>
<AzureRoleContent Include="Installers\">
<RoleName>Azure</RoleName>
<Destination></Destination>
</AzureRoleContent>
</ItemGroup>
</Target>
Referencing runtime content from .ccproj (Azure SDK 2.9)

SlowCheetah Azure web role not transformed

I am using SlowCheetah 2.5.10.6 in my Visual Studio 2013 solution in which I want to create a web role package for deployment. I am using Azure Tools 2.3.
My default web.config transforms are working correctly. However, the SlowCheetah transforms do not work. Somehow this should be working: Slow Cheetah issue 5
In my output window I see the following:
1>Task "SlowCheetah.Xdt.TransformXml"
1> Transfroming source file: D:\web\Project\src\Project.Web\App_Config\OTAP\connectionStrings.config
1> Applying Transform File: App_Config\OTAP\connectionStrings.O.config
1> Output File: bin\App_Config\OTAP\connectionStrings.config
1>Done executing task "SlowCheetah.Xdt.TransformXml".
In my bin folder I see the correctly transformed file.
I also see the following line in my output:
3> Task "Message"
3> TransformedWebFiles = App_Config\OTAP\connectionStrings.config, DestinationRelativePath=App_Config\OTAP\connectionStrings.config, Exclude=False, FromTarget=CollectFilesFromContent, Category=Run, ProjectFileType=Default
But when the package is created, the original file is used
3>Target "CopyWebRoleFiles" in file "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\Windows Azure Tools\2.3\Microsoft.WindowsAzure.targets" from project "D:\web\Project\src\Project\Project.ccproj" (target "CopyRoleFiles" depends on it):
3> Task "Message"
3> CurrentRoleWebFiles=D:\web\Project\src\Project.Web\App_Config\OTAP\appSettings.config -> App_Config\OTAP\appSettings.config
3> Task "Message"
3> CurrentRoleWebFiles=D:\web\Project\src\Project.Web\App_Config\OTAP\connectionStrings.config -> App_Config\OTAP\connectionStrings.config
So my base config is used in the package and I want connectionStrings.*.config to be used.
Does anybody know what I am doing wrong here?
I fixed the problem with the following MSBuild script:
<Target Name="DeploySlowCheetahTransforms" AfterTargets="CopyWebRoleFiles" Condition="'#(WebRoleReferences)' != ''">
<PropertyGroup>
<IntermediateWebOutputPath>%(WebRoleReferences.OutputDir)</IntermediateWebOutputPath>
</PropertyGroup>
<ItemGroup>
<TransformedFiles Include="$(WebTargetDir)\**\*.config" Exclude="$(WebTargetDir)\**\*.dll.config;$(WebTargetDir)\**\web*.config" />
</ItemGroup>
<Copy SourceFiles="#(TransformedFiles)" DestinationFiles="#(TransformedFiles->'$(IntermediateWebOutputPath)\%(RecursiveDir)%(Filename)%(Extension)')" />
</Target>
This scripts needs to be added to the ccproj file. The WebRoleReferences and WebTargetDir variables are created in Microsoft.WindowsAzure.targets. This script gets all the transformed config files from the OutputPath of your csproj file and copies them to the OutputDir which is used to create the Azure WebRole package.

Resources