问题
My solution consists of:
Client
- startup project, UI layer. Depends on: App
App
- library, application layer, assembler. Depends on: Lib1
, ...
Lib1
- library, business logic layer. Needs a specific file to work properly: ThirdParty.dll
I've added ThirdParty.dll
to the Lib1
project (Add
> Existing Item...
> Add
) and set Copy to Output Directory
property of dll file to Copy Always
. Now the dll file is copied to the Lib1
output and to the App
output, but not to the Client
output where I need it to be.
What is the right (simple? obvious?) way to copy ThirdParty.dll
to the output of Client
on each solution build?
UPD
ThirdParty.dll
is not a reference. Actually, that's another reference dependence. My question is applied to any file that needs to be in the folder of running application.
Recorded video to be sure I'm doing it right: http://youtu.be/QwS2tOIc5yQ
回答1:
Add Existing Item as Link:
I had a similar issue in VS2010
and I kinda ended up adding the file as Link
and updating its property to Copy Always
.
In your case, in CLIENT
project, add ThirdParty.dll
as Link
(Add > Existing Item > Add as Link) and set Copy to Output Directory
property of dll file to Copy Always
.
Note: It would copy the folder hierarchy from Project Node.
Just for Reference: I was actually using an open source LibGit2Sharp which required a dll (libGit2.dll) to be available in the output directory. Therefore, in the UI layer, which had added application layer containing LibGit2Sharp.dll
as reference; I had to add libGit2.dll
as a Link
+ Copy Always
. This was recommended solution.
Post Build:
The other option could be to write a post build scripts for CLIENT
To know how the Copy
on MSBuild
works, you could refer to Microsoft.Common.targets
file (should be available @ C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets in your system)
<Target
Name="CopyFilesToOutputDirectory"
DependsOnTargets="
ComputeIntermediateSatelliteAssemblies;
_CopyFilesMarkedCopyLocal;
_CopySourceItemsToOutputDirectory;
_CopyAppConfigFile;
_CopyManifestFiles;
_CheckForCompileOutputs;
_SGenCheckForOutputs">
回答2:
It's easy and it's strange that it didn't work for you. I've just checked and this works:
- Add
ThirdParty.dll
to theLib
project. - The
Build Action
should be set toContent
(the default value) !!! - Set
Copy to Output Directory
toCopy if newer
orCopy always
- Reference
Lib
fromApp
- Reference
App
fromClient
This works in Visual Studio 2012, but doesn't seem to work in Visual Studio 2010.
VS2010:
Target "AssignTargetPaths" skipped. Previously built successfully.
Target "_SplitProjectReferencesByFileExistence" in file "C:\windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets" from project "Test.ContentFiles\App\App.csproj" (target "GetCopyToOutputDirectoryItems" depends on it):
Task "ResolveNonMSBuildProjectOutput" skipped, due to false condition; ('$(BuildingInsideVisualStudio)'=='true' and '@(ProjectReferenceWithConfiguration)'!='') was evaluated as ('true'=='true' and ''!='').
Done building target "_SplitProjectReferencesByFileExistence" in project "App.csproj".
Target "GetCopyToOutputDirectoryXamlAppDefs" in file "C:\windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Xaml.targets" from project "Test.ContentFiles\App\App.csproj" (target "GetCopyToOutputDirectoryItems" depends on it):
Task "AssignTargetPath"
Done executing task "AssignTargetPath".
Done building target "GetCopyToOutputDirectoryXamlAppDefs" in project "App.csproj".
Target "GetCopyToOutputDirectoryItems" in file "C:\windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets" from project "C:\Users\Ark-kum\Documents\visual studio 2010\Projects\Test.ContentFiles\App\App.csproj" (entry point):
Task "MSBuild" skipped, due to false condition; ('@(_MSBuildProjectReferenceExistent)' != '' and '$(_GetChildProjectCopyToOutputDirectoryItems)' == 'true' and '%(_MSBuildProjectReferenceExistent.Private)' != 'false' and '$(UseCommonOutputDirectory)' != 'true') was evaluated as ('' != '' and 'true' == 'true' and '' != 'false' and 'false' != 'true').
Task "AssignTargetPath"
Done executing task "AssignTargetPath".
Done building target "GetCopyToOutputDirectoryItems" in project "App.csproj".
Done executing task "MSBuild".
Task "AssignTargetPath"
Done executing task "AssignTargetPath".
Done building target "GetCopyToOutputDirectoryItems" in project "Client.csproj".
Target "_CopyOutOfDateSourceItemsToOutputDirectory" in file "C:\windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets" from project "Test.ContentFiles\Client\Client.csproj" (target "_CopySourceItemsToOutputDirectory" depends on it):
Building target "_CopyOutOfDateSourceItemsToOutputDirectory" completely.
Output file "bin\Debug\FileList.App.txt" does not exist.
Task "Copy"
Copying file from "Test.ContentFiles\App\FileList.App.txt" to "bin\Debug\FileList.App.txt".
VS2012:
Target "GetCopyToOutputDirectoryItems" skipped. Previously built successfully.
Done executing task "MSBuild".
Task "AssignTargetPath"
Done executing task "AssignTargetPath".
Done building target "GetCopyToOutputDirectoryItems" in project "Client.csproj".
Target "_CopyOutOfDateSourceItemsToOutputDirectory" in file "C:\windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets" from project "Test.ContentFiles\Client\Client.csproj" (target "_CopySourceItemsToOutputDirectory" depends on it):
Building target "_CopyOutOfDateSourceItemsToOutputDirectory" completely.
Output file "bin\Debug\FileList.Lib.txt" does not exist.
Output file "bin\Debug\FileList.App.txt" does not exist.
Task "Copy"
Copying file from "Test.ContentFiles\Lib\FileList.Lib.txt" to "bin\Debug\FileList.Lib.txt".
Copying file from "Test.ContentFiles\App\FileList.App.txt" to "bin\Debug\FileList.App.txt".
Quote from the .target files:
============================================================
GetCopyToOutputDirectoryItems
Get all project items that may need to be transferred to the output directory.
This includes baggage items from transitively referenced projects. It would appear
that this target computes full transitive closure of content items for all referenced
projects; however that is not the case. It only collects the content items from its
immediate children and not children of children. The reason this happens is that
the ProjectReferenceWithConfiguration list that is consumed by _SplitProjectReferencesByFileExistence
is only populated in the current project and is empty in the children. The empty list
causes _MSBuildProjectReferenceExistent to be empty and terminates the recursion.
============================================================
回答3:
You could use(in visual studio) Lib1 project Properties -> Build Events -> Post-build event command line.
In the "Post-build event command line" edit box type copy commands that will copy required files to the Client output folder. In that editbox you can use various VS macros (Click "Edit Post Build" -> Macros) Like this:
copy path\to\ThirdParty.dll $(SolutionDir)Client\bin\Debug
Perhaps, you will need to "Build"->"Rebuild Solution" at first time.
来源:https://stackoverflow.com/questions/16791310/how-to-include-neccessary-files-to-the-output-of-independent-client-project