I just updated to Visual Studio 2017 v15.3 and Core 2.0 SDK.
I'm working with Igans Sakalauskas' Net Core Knockout project, it was built with Core 1.1 in VS 2017.
https://ignas.me/tech/net-core-knockoutjs-web-application/
I've left EnableDefaultContentItemsto the default of true and removed the Content Include statements from the .csproj file in the WebApplication1.Web project.
He is using nlog and there is a nlog.config in the root of the project. The project builds successfully but throws a file not found error when ran. It is looking for the nlog.config in the WebApplication1.Web\bin\Debug\netcoreapp1.1 folder. If I manually copy the file the project runs and all the tests pass.
What I cannot get to work is for VS to copy the nlog.config when the project builds.
If I add
<ItemGroup>
<Content Include="nlog.*" />
</ItemGroup>
to the .csproj I get the Duplicate 'Content' items ... The duplicate items were: 'nlog.config' error. https://aka.ms/sdkimplicititems
If I comment out the Contnet Include and set the EnableDefaultContentItems to false
<PropertyGroup>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
</PropertyGroup>
I get a
Suppression State Error CS5001 Program does not contain a static 'Main' method suitable for an entry point
If I then restore the `Content Inculde' statements it gives this error:
Duplicate 'Content' items ... The duplicate items were: 'list of files' error
The Default Content Items is working with .js and .cs files in the wwwroot sub-folders.
If VS throws the Duplicate Content error when I Content Include an item why does it not copy the file without the Content Include?
In VS 2017 15.3 how do you configure the copying of a file nlog.config from the project's root to a bin sub-directory?
This is nothing to do with duplicate content items.
Revert to the recommended approach to handling duplicate content errors in Visual Studio 2017; this is what you started with:
I've left EnableDefaultContentItems to the default of true and removed
the Content Include statements from the .csproj file in the
WebApplication1.Web project.
Now add this to your .csproj file:
<ItemGroup>
<Content Update="nlog.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
This tells Visual Studio to update the existing content rule (the automatically generated one) to make it copy the file into the output directory on build.
I finally managed to configure my Visual Studo C++ Project to show my Custom ProjectSchemaDefinition if I take a look at a Single Project->Property.
My Question:
Is there any way to show this in a Shared Project Property (eg external.props) ?
My current shared.targets configuration
<PropertyGroup Label="Import Settings">
<UseDefaultProjectTools>true</UseDefaultProjectTools>
<UseDefaultPropertyPageSchemas>true</UseDefaultPropertyPageSchemas>
<UseDefaultGeneralPropertyPageSchema>true</UseDefaultGeneralPropertyPageSchema>
</PropertyGroup>
<ItemGroup>
<PropertyPageSchema Include="$(SolutionDir)\props\PublishConfig.xml">
<Context>Project</Context>
</PropertyPageSchema>
<ProjectTools Include="PublishConfig" />
</ItemGroup>
I think I miss just the right Context in this definition but cannot find any reliable source at msdn where different Context Targets are correctly described.
Thank you in advance
I would like to use web deploy to publish a Visual Studio "Console" application to a folder on the target system.
I have had some luck, and have been able to produce something similar to what I need, but not quite.
I've added the following to the console .csproj:
added the following projectName.wpp.targets file
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
and I've added the following projectName.wpp.targets:
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<DeployAsIisApp>false</DeployAsIisApp>
<IncludeSetAclProviderOnDestination>false</IncludeSetAclProviderOnDestination>
</PropertyGroup>
<ItemGroup>
<FilesForPackagingFromProject Include="$(IntermediateOutputPath)$(TargetFileName).config">
<DestinationRelativePath>bin\%(RecursiveDir)%(FileName)%(Extension)</DestinationRelativePath>
<FromTarget>projectName.wpp.targets</FromTarget>
</FilesForPackagingFromProject>
</ItemGroup>
</Project>
I then edit the .SetParameters.xml file as follows:
<parameters>
<setParameter name="IIS Web Application Name" value="c:\company\project" />
</parameters>
When I then deploy using the generated .cmd file, I get all the files deployed to C:\company\project\bin.
That's not bad, but I'd like to do better. In particular, I'd like to omit the "bin" folder and put all files in the "C:\company\project" folder, and I'd like to be able to specify the ACLs
Has anybody been able to work around these problems?
Ok, so here's the way how to omit the 'bin' folder.
First of all, I'd like to emphasize that all this msdeploy-related stuff is for web apps deployment, and 'bin' folder seems for me to be almost hardcoded deeply inside. So if you want to get rid of it - you have to do some dirty things. Which I did.
We'll have to change $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets project a little bit, so it's better to change not it, but it's copy.
Steps:
1.Backup $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets(alternatively, you could install MSBuild.Microsoft.VisualStudio.Web.targets package, redirect your csproj file to Microsoft.WebApplication.targets file obtained from package and work with it).
2. In the $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplicaton.targets find the xml node which looks like <CopyPipelineFiles PipelineItems="#(FilesForPackagingFromProject)"(there are several ones of them, take the one from the line ~2570).
3. Comment the node out, replace with the custom one, so eventually it will look like:
<!--
<CopyPipelineFiles PipelineItems="#(FilesForPackagingFromProject)"
SourceDirectory="$(WebPublishPipelineProjectDirectory)"
TargetDirectory="$(WPPAllFilesInSingleFolder)"
SkipMetadataExcludeTrueItems="True"
UpdateItemSpec="True"
DeleteItemsMarkAsExcludeTrue ="True"
Condition="'#(FilesForPackagingFromProject)' != ''">
<Output TaskParameter="ResultPipelineItems" ItemName="_FilesForPackagingFromProjectTempory"/>
</CopyPipelineFiles>-->
<!-- Copying files to package folder in 'custom'(dirty) way -->
<CreateItem Include="$(OutputPath)\**\*.*">
<Output TaskParameter="Include" ItemName="YourFilesToCopy" />
</CreateItem>
<Copy SourceFiles="#(YourFilesToCopy)"
DestinationFiles="#(YourFilesToCopy->'$(WPPAllFilesInSingleFolder)\%(RecursiveDir)%(Filename)%(Extension)')" />
Then
4. Your projectName.wpp.targets don't have to have FilesForPackagingFromProject, so it will look like:
<!-- targets -->
<PropertyGroup>
<DeployAsIisApp>false</DeployAsIisApp>
<IncludeSetAclProviderOnDestination>false</IncludeSetAclProviderOnDestination>
</PropertyGroup>
<ItemGroup>
<!-- intentionally left blank -->
</ItemGroup>
</Project>
That's it. Worked for me(tm), tested. Let me be honest, I don't like this approach, but that was the only way I made it working in the needed way. It's up to you whether you'll use it in your project or not.
My opinion is not to use msdeploy here - it was not for you task.
Better to write msbuild-scripts from scratch or accept the 'bin' folder, and fight against the framework again once next customization is required.
Has anyone done this? If so, what tools/techniques/approaches did you use?
Is it possible to do with installing the SQL Business Studio Version of Visual Studio?
Thanks in advance!
Got it folks...
1) Install MSBuild Extensions
2) Created a Build.Xml file as so...
<Project ToolsVersion="3.5" DefaultTargets="Default" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\ExtensionPack\MSBuild.ExtensionPack.tasks"/>
<Target Name="Default">
<PropertyGroup>
<OutputRoot>../../../build-artifacts</OutputRoot>
</PropertyGroup>
<ItemGroup>
<SSISProjectFile Include="SSISProject.dtproj"/>
<SSISProject Include="#(SSISProjectFile)">
<OutputDirectory>$(OutputRoot)</OutputDirectory>
</SSISProject>
</ItemGroup>
<ItemGroup>
<Namespaces Include="Mynamespace">
<Prefix>DTS</Prefix>
<Uri>www.microsoft.com/SqlServer/Dts</Uri>
</Namespaces>
</ItemGroup>
<MSBuild.ExtensionPack.Xml.XmlFile
TaskAction="UpdateElement"
File="EnclarityDataImport.dtsx"
XPath="//DTS:Property[#DTS:Name='ConfigurationString']"
InnerText="$(MSBuildProjectDirectory)\EnclarityDataImport.dtsConfig"
Namespaces="#(Namespaces)"/>
<MSBuild.ExtensionPack.SqlServer.BuildDeploymentManifest InputProject="#(SSISProject)"/>
</Target>
The only trick was the last part of the build here. By default visual studio adds the absolute path to your config and connection string files for your dtsx package. Team City will use these in conjunction with MSBuild extensions to build the package so a local path will break the build because the paths to the build directories in Team City are automatically generated. So using the code above and the $(MSBuildProjectDirectory) you can twiddle the value of the path on your dtsx file so that it points to the path where your compilation is exectuing.
Like booyaa says SSIS projects don't need to be compiled, but what i have done is make the .dtconfigs configurable by the build/deployment process.
I do this so that i can run the packages on deployment in different environments. So the build will copy a template of the dtconfig file.
this contains tokens- $(Servername) $(ConnectionString)
And then i do the replacement on deployment and then execute by wrapping the dtexec in an command.
Not sure about 2012.
There is Copy to Output Directory property for files in C# projects. But in VC++ projects it is absent. I know, that I can use Build events in VC++ and write there something like
xcopy /y /d %(FullPath) $(OutDir)
Is there a way to avoid the use of CMD (and other scripting methods)? Can msbuild do something to help in this case?
Can MSBuild do something to help in this case?
Using MSVC 2012, this worked for me:
Assumed you have a file "Data/ThisIsData.txt" in your c++ Project.
Unload the project (right click --> Unload Project).
Edit project XML (right click --> Edit .vcxproj)
Now you see the projects MSBuild file as XML in your editor.
Find "ThisIsData.txt". It should look something like:
<ItemGroup>
<None Include="Data\ThisIsData.txt" />
...
</ItemGroup>
Now add an other item group like this:
<ItemGroup>
<Content Include="Data\ThisIsData.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
...
</ItemGroup>
Reload the project and build.
Your file "ThisIsData.txt" should get copied to $(OutDir)\Data\ThisIsData.txt.
Why duplicating the ItemGroup?
Well if you simply change the None include to a content include, the IDE does not seem to like it any more, and will not display it. So to keep a quick edit option for my data files, I decided to keep the duplicated entries.
In VS 2015 it is possible to give C projects the functionality that is in C#.
(Idea from building off of jochen's answer.)
Instead of adding another ItemGroup, modify the given itemgroup adding a CopyTo element. I.E, using his example, simply enhance the original entry to:
<ItemGroup>
<None Include="Data\ThisIsData.txt" />
<DeploymentContent>true</DeploymentContent>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
...
</ItemGroup>
No other ItemGroup required. By adding the CopyTo element, you add an "Included In Project" property.
In Visual Studio 2017 you can do this in the IDE. I am not sure about earlier versions.
Simply add the file as an included project file so it shows in the Solution Explorer. Then right click on the file and select the Properties menu.
Change the Content to "Yes" and change the Item Type to "Copy file"
If you look at the changes it made to the project file you can see it added this:
<ItemGroup>
<CopyFileToFolders Include="Filename.txt">
<DeploymentContent>true</DeploymentContent>
<FileType>Document</FileType>
</CopyFileToFolders>
</ItemGroup>
It depends on what version of Visual Studio you are using. Format of VC++ project file in Visual Studio 2008 is not MSBuild and so using xcopy in PostBuildStep is a good choice.
VC++ project in Visual Studio 2010 has MSBuild format. Thus, there is functionality of MSBuild Copy task.
Below is a sample:
<Copy
SourceFiles="%(FullPath)"
DestinationFolder="$(OutDir)"
/>
If the destination directory does not exist, it is created automatically
An MSDN Copy task reference is here
Following henri-socha's answer about VS2015 (and probably VS2013 and VS2012, or anything using MSBuild style projects), the ItemGroup item type is important.
Specifically <Text> items do not seem to be copied, whereas <Content> items do.
So, for a project directory Data containing a text file ThisIsData.txt, this will create a subdirectory Data under the $(OutDir) directory and copy the file ThisIsData.txt from the project into it if it's newer:
<ItemGroup>
<Content Include="Data\ThisIsData.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
This won't, although it is what the Visual Studio IDE will insert if you add the text file to your project, and set the Content property to True.
<ItemGroup>
<Text Include="Data\ThisIsData.txt">
<DeploymentContent>true</DeploymentContent>
</Text>
</ItemGroup>
So in other words you need to add the file via the IDE to make it realise the file is included in the project (which adds <Text> tag ItemGroup), and then open the project in a text editor and add the <Content> tag ItemGroup to get it to do what you want.
I'm not sure what the <DeploymentContent> tag actually does. It may be a remnant since the only MSDN reference I could find considers it archived: https://msdn.microsoft.com/en-us/library/aa712517.aspx
In visual studio 2019 after setting the file as "Include in project" you can edit the properties an select as Item Type "Copy file" (as shown in https://i.stack.imgur.com/vac2b.png)
This avoids the manual vcxproj file edition.
You can specify copying in the project file as Jeff G answered in another question:
In the *.vcxproj file, change:
<Text Include="Filename.txt" />
to:
<Content Include="Filename.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
Then in the *.vcxproj.filters file, change:
<Text Include="Filename.txt">
<Filter>Resource Files</Filter>
</Text>
to:
<Content Include="Filename.txt">
<Filter>Resource Files</Filter>
</Content>
where the <Text ...> tag is for specified text files (it'll be <Image ...> for image files etc.)
If it's a COM dll, you can add it to the root of your project, mark it as 'Content' and set copy to output directory to 'Always'. I had to do this for signature capture COM assembly.