msbuild cannot copy manifest because it was not found - c#

We have a c# framework (not .core) solution with several projects in it. It is build by TFS. Sometimes (not all the times) I got a build error:
error MSB3030: Could not copy the file
"c:\BuildAgent_work\27\b\Console.Admin\Product.Admin.exe.manifest"
because it was not found.
[c:\BuildAgent_work\27\s\Console.Admin\Console.Admin.csproj]
The app.manifest file is added to the project Properties folder, and I checked it exists on buildagent source folder. I checked it is not exists on the binaries folder. I don't know why it is not copied there during the build.
In fact I don't know if I need this manifest thing at all. I think I don't. This whole thing was added to the project by one of my collegaue for a reason is unknown for me. Is it required to create publish package for web projects? In this case why it is required for a console project? For what reason is it added?
The msbuild parameters (for building the solution) are the following, and the [x] Clean option is checked in the TFS build solution step.
/p:OutDir=$(Build.BinariesDirectory)
/p:GenerateProjectSpecificOutputFolder=true
/p:DeployOnBuild=true /
p:PackageAsSingleFile=true
/p:GenerateDocumentation=true
/p:DisableAllVSGeneratedMSDeployParameter=true
/t:Clean,Build,Publish
/p:RunCodeAnalysis=$(CodeAnalysis.Run);CodeAnalysisRuleSet=$(CodeAnalysis.RuleSet).ruleset;CodeAnalysisIgnoreGeneratedCode=true
/p:IncludeAppPool=true
/p:PrecompileBeforePublish=true;EnableUpdateable=false

An application manifest is an XML file that describes and identifies the shared and private side-by-side assemblies that an application should bind to at run time. These should be the same assembly versions that were used to test the application. Application manifests may also describe metadata for files that are private to the application. You can refer to this document.
So, you first need to check in csproj for any additional operations on the manifest. When the MSBuild creates the publish files it copies files base on the build definition , you can try to edit the .csproj file as bellow which copied the relevant files. app.manifest is your file path .
<ItemGroup>
<None Update="app.manifest">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

Related

How to copy project's resources folder to output directory in project with a reference to it

I have multiple projects in my solution. One of the projects has resources files (images). Then I have another project with unit tests. I'd like to have all these files available in unit tests project when the project with resources is referenced.
I've tried two solutions:
a) Apply a post-build script to the project with resources
The script copies resources directory content to the output (Debug/Release) directory as I need. But the script isn't executed when unit tests project is build (only when the project with resources is)
b) Set "Copy to Output Directory" property to value "Copy always" to all resources files
This works as I need even in project that has reference but I have to set this property manually to all the files. I wonder whether there is a way how to manage the same result but with a folder (to automatically copy all its content)
My question is: Is there any way how to automatically copy project's resources directory and its content to another project when the project with resources files is referenced?
You can check this link.
https://github.com/dotnet/project-system/issues/3203
As the link describes, if files are added to the directory during the build process, you must use a target to expand the wildcard, or it will only copy the files that existed at the start of the build.
You can use the following methods:
Open the *.vcxproj file and add the following code.
<ItemGroup>
<None Include="$(SolutionDir)config\**" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
Hope it can help you.

How do I include .deps and .runtimeconfig files as project dependencies?

Visual Studio creates two files along with the .exe for my project that are required to run the exe: a deps.json and a runtimeconfig.json. A second project in my solution has the first project as a project reference, but those two files aren't being copied to my second project's output directory. How can I tell Visual Studio that it should copy these files into the output directory of the second project, because the referenced project depends on them?
Output directory of my first project:
Foo.exe
Foo.deps.json
Foo.runtimeconfig.json
Output directory of my second project:
Bar.exe
Foo.exe
Should contain deps and runtimeconfig files, but does not
The solution I found is to manually edit my .csproj file to add the following target:
<Target Name="AddRuntimeDependenciesToContent"
Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp'"
BeforeTargets="GetCopyToOutputDirectoryItems"
DependsOnTargets="GenerateBuildDependencyFile;
GenerateBuildRuntimeConfigurationFiles">
<ItemGroup>
<ContentWithTargetPath Include="$(ProjectDepsFilePath)"
Condition="'$(GenerateDependencyFile)' == 'true'"
CopyToOutputDirectory="PreserveNewest"
TargetPath="$(ProjectDepsFileName)" />
<ContentWithTargetPath Include="$(ProjectRuntimeConfigFilePath)"
Condition="'$(GenerateRuntimeConfigurationFiles)' == 'true'"
CopyToOutputDirectory="PreserveNewest"
TargetPath="$(ProjectRuntimeConfigFileName)" />
</ItemGroup>
</Target>
This solution came from https://github.com/dotnet/sdk/issues/1675#issuecomment-658779827.
There were other somewhat similar solutions posted in that thread, but this is the only one that worked for me. The others would either not consistently copy the files to my second project, or cause the first project to fail to build due to attempting to access a file that didn't yet exist. The key difference with this one is the inclusion of the correct "BeforeTargets" property (and possibly also "DependsOnTargets"), controlling at which point in the build process the files are included.

WPF Clickonce publish with Microsoft.Net.Sdk

I can successfully build a WPF application with the new csproj format using the Sdk="Microsoft.Net.Sdk".
However, it is a bit of a challenge to publish the said app. The option is definitely not available from the IDE. But what I find a bit puzzling is that the Publish target doesn't seem to be available when you call msbuild directly.
These are some of the top-level properties I set:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net461</TargetFramework>
<LanguageTargets>$(MSBuildExtensionsPath)\$(VisualStudioVersion)\Bin\Microsoft.CSharp.targets</LanguageTargets>
<OutputType>WinExe</OutputType>
<PlatformTarget>x86</PlatformTarget>
<Prefer32Bit>false</Prefer32Bit>
<!--<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>-->
</PropertyGroup></Project>
I also set the typical ones associated with the ClickOnce eg PublishUrl, etc. What can I do to get at/expose the Publish target the same way the LanguageTarget above enables "CoreBuild" for the other legacy C# build tasks outside Console, Web and plain libraries.
Further Thoughts:
So, it turns out that on further inspection, there is actually a Publish target. But it does a simple folder/xcopy deployment to a subfolder called Publish rather than creating an app.publish folder and doing the ClickOnce thing.
How does one work around this?
You can manually publish ClickOnce using the Mage.exe (command line) or MageUI.exe (gui) tools. It's not very convenient but it does seem to work if you get everything right. I'll outline what worked for me using MageUI.exe.
Choose the correct version of the utility for the .NET version you're using from:
C:\Program Files (x86)\Microsoft SDKs\Windows\
First publish your application files to a folder. Normally this would be something like:
\\server\share\MyApplication\Application Files\MyApplication_1_0_0_25\
NOTE: I had issues with the space in Application Files, where it would be converted to %20, but I don't think UNC paths support that value. I had to remove the space and renamed the folder to ApplicationFiles. (This will probably break previously published versions though.)
Then use MageUI.exe to create a new application manifest:
On the Name page, give it a name, version, and choose a processor architecture (x86).
On the Files page, enter the directory you published the files to, and then hit populate. It should load all the program files into the DataGridView below.
On the Permissions Required page, I was not able to get it working with anything less than FullTrust. Without FullTrust, when the application was run, nothing happened.
Save the manifest file as MyApplication.exe.manifest to the application folder. (You will be able to sign the manifest when you save it.)
Now create a new Deployment manifest:
On the Name page, enter the same name and version and choose the right processor architecture.
On the Description page, enter Publisher and Product.
On the Deployment Options page, I chose Online Only. I did not include a Start Location.
On the Application Reference page, choose Select Manifest and browse to the application manifest file you previously created.
Save the deployment manifest as \\server\share\MyApplication\MyApplication.application; (you can sign it when you save.)
NOTE: A glitch here seems to be that it will have inferred the wrong relative path when you select the application manifest file. After you've saved the deployment manifest the first time, go select the application manifest file again, and it will now infer the correct relative path. Then hit save again and you should be ok.
There are a lot of things that can go wrong and a lot of ways that the procedure can differ, but these are the steps that worked for me.
(Another thing I had to do during these steps was clear my ClickOnce Application Cache, by deleting the contents of c:\users\username\AppData\Local\Apps\2.0\. But that was probably just because of all the mistakes I made. I would only do this if you get stuck.)
Microsoft is finally adding ClickOnce functionality to SDK Style Winforms and WPF projects in .NET 5.
I was able to put ClickOnce in a WPF net48 project with new SDK style as before of moving to the new SDK.
It was necessary just to put this block in the end of my .csproj file:
<PropertyGroup>
<PublishProtocol>ClickOnce</PublishProtocol>
</PropertyGroup>
<Import Sdk="Microsoft.NET.Sdk.WindowsDesktop" Project="Sdk.props" />
<Import Sdk="Microsoft.NET.Sdk.WindowsDesktop" Project="Sdk.targets" />
<Target Name="ComputeAndCopyFilesToPublishDirectory" />
It does the following:
set SDK to not skip the import of Microsoft.NET.ClickOnce.targets. That is achieved by setting <PublishProtocol>ClickOnce</PublishProtocol>
set SDK to avoid bin/debug/**/* files to be copied to publish directory.
That is achieved by skipping the "ComputeAndCopyFilesToPublishDirectory" target execution. To do so, we've overriden it to an empty implementation.

How to build all projects in one single folder?

Is there a way to build solution into a single folder? I have several projects in this solution and each access a config file that should be in the current directory. I just move each project's build files into one and it still works, however, it looks so unorganized and messy. I just want to know it there are other ways on how to do it.
You can set output directory in the settings of every project in solution (if we are about Visual Studio). Menu: Project -> properties -> Build -> Output path. For example, I use ..\Build\ to build projects into Build directory of solution root.
This MSDN article explains how to do it in a nice, DRY way:
https://blogs.msdn.microsoft.com/kirillosenkov/2015/04/04/using-a-common-intermediate-and-output-directory-for-your-solution/
It allows you to specify those directories only once, and use those settings in multiple projects.
Steps:
Create a single common.props file in solution, that will specify and overwrite output and intermediate paths for a project to a common directory (like "Solution/bin").
Here is a sample *.props file that I found linked in the article:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SolutionDir>$(MSBuildThisFileDirectory)</SolutionDir>
<Configuration Condition="$(Configuration) == ''">Debug</Configuration>
<OutputPath>$(SolutionDir)\bin\$(Configuration)\</OutputPath>
<OutDir>$(OutputPath)</OutDir>
<OutDir>$(OutputPath)</OutDir>
<IntermediateOutputPath>
$(SolutionDir)\obj\$(Configuration)\$(MSBuildProjectName)\
</IntermediateOutputPath>
<UseCommonOutputDirectory>False</UseCommonOutputDirectory>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
</Project>
Include this file into every *.csproj that you want to set the common output dirs for, by adding this line (the actual path may differ): <Import Project="..\Common.props" />
You can change projects "Output path", by default it's bin directory of given project.
Right click on each project, select Properties from context menu, then select Build tab.
Ont the bottom in Output section change Output path:. Set same path for each project.
I agree with comments under your question, you should not change it. Instead you may create post build action (PS script) that will copy all files from project's bin directories to one designated by you.
Update:
Set this script as Post Build command (Project's properties->Build Events tab->Post build event command line):
xcopy "$(TargetDir)*" "$(SolutionDir)Build" /s /i /Y
For each project:
Go into the project properties, in the "Build" tab.
Choose "All configurations", "all platforms", just in-case.
In the output folder write "..\bin\" (or any path which is uniform for all of them - not in the current project directory). Alternatively, to organize DLLs in sub-folders you can write "..\bin\Sub-project-directory" in the output path. Then you should add an App.config file for the EXE project with a probing to all DLLs so they can be found and loaded on runtime.
Note that if we're talking about building multiple executables into the same output directory, you can also add them as project references to the main (startup) project. They will be automatically copied to the main project output directory everytime you build it.
(note: this applies to .NET Core projects in VS 2017 or VS 2019. I'm not sure if it would work for .NET Framework projects)

ensuring c# project dependencies are copied to output directory in Visual Studio and TFS

I am working on a project which has many dependencies which are developed on a separate team from me. We use TFS 2010. Many of my applications depend on libraries and xml files which are under active development, so I want to keep them up to date. I also don't want to create separate copies of the dll's and xml files for each application/project, but rather source them from their respective locations within the same source control repository. This should be possible using a relative path.
I tried putting the following in my .csproj file
<ItemGroup>
<Dependencies Include="..\..\Driver\Driver.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Dependencies>
</ItemGroup>
this doesn't work, either on my workstation or on the build server, however, the files show up as dependencies in the Solution Explorer, and it allows me to change the copy to output property and shows the full path the to files, which is valid.
Another thing I tried was just running xcopy as a pre-build event, which works on my local machine but does NOT copy the files to the output/TFS drop folder, so it isn't picking it up as a dependency.
Try using the Private Element instead, set to True.
<ItemGroup>
<Dependencies Include="..\..\Driver\Driver.dll">
<Private>True</Private>
</Dependencies>
</ItemGroup>
See http://msdn.microsoft.com/en-us/library/bb629388.aspx

Categories