I have a solution with the following structure:
> SolutionA
> ProjectA
> FolderA
> FileA
> FileB
> FolderB
> ProjectB
> FolderC
> FileC
I have a developer who wants to play with some testing scenarios and who only needs to be exposed to FileA and FileC. What I would like to do is the following:
> SolutionA
> ProjectA
> FolderA
> FileA
> FileB
> FolderB
> ProjectB
> FolderC
> FileC
> SandboxProject
> FolderA [link]
> FileA [link]
> FolderC [link]
> FileC [link]
> FolderSandbox
> FileSandbox
I'd like to add SandboxProject to achieve the following:
Provide the developer access to source-controlled files without exposing him to things he doesn't need to know about - these files aren't independent enough to be in their own projects, but he doesn't need to know about other siblings. This is both a security (sensitive files) and dev UX concern (don't show more than necessary).
Provide an easy way to play with the consumers of the linked files (for example - a linked file might be plugin.js but he will make his own Index.cshtml to consume/test it. His changes to plugin.js will be seen in the original project as it's just a link to a source-controlled file. Changes to Index.cshtml won't impact other projects because it's source-controlled within SandboxProject only.
Does Visual Studio / VSTS support this kind of "linking" and isolation? If so, what steps should be taken to achieve it? Can I use Add as link for this purpose?
No, it is not supported.
Regarding Add as link, the target files must be downloaded to a machine (can be in a shared folder), also these files need to be accessible. So, I don’t think it meets your requirements.
The better way is that, you can package necessary files/project and publish to VSTS/TFS feed, then developers can add these packages reference.
Note: With this way, the changes to package files won’t affect the source files. But since the developer don’t know about the things of the source files, the changes in “linked” files shouldn’t affect the source files.
More information about vsts/tfs feed, you can refer to: Package Management in Team Services and TFS.
Related
Suppose we have a project A with output directory bin/ and a project B with output directory test/bin/. Project A needs to have a certain configuration file copied to its output directory. Currently, this is being done by adding a pre-build event that looks like
COPY /Y "$(ProjectDir)..\config.ini" "$(TargetDir)"
Project B has A as dependency. When project B builds, the binary resulting from A is correctly copied to the output directory of B, but the config file isn't!
How can we achieve that all files that A needs to have are also copied to the output directory of B?
What you want is a Link File. I've used these before to ensure that connection.config files are copied to multiple projects.
I created a sample solution that mimics your described scenario as seen below. The ConsoleApplication1 references the ClassLibrary1 project. In the solution, I created a solution folder config and added the shared config that needs to be copied.
In order to have a single file that is copied across multiple projects, you must create a single file, and then add it as a link to the projects that need it. This can be done by right clicking on the project, and choosing Add -> Existing Item.... You will see a dialog as show below and you want to choose the Add as Link option from the dropdown instead of just Add.
Finally, edit the properties for the linked file to copy it to the output directory.
I have a C# Visual Studio solution with about 15 projects. When I build the solution I want all DLL and EXE files for each project to go to a common folder (called Deploy).
The way I was thinking about doing it was, for each project's Post-build Event Command Line section put the following commands:
IF NOT EXIST $(SolutionDir)Deploy (
'If directory does not exist, create it
MKDIR $(SolutionDir)Deploy
) ELSE (
'Delete directory to make sure it's "clean"
RMDIR /F /S /Q $(SolutionDir)Deploy
MKDIR $(SolutionDir)Deploy
)
'Copy executable and required DLLs to Deploy directory
COPY /Y $(TargetPath) $(SolutionDir)Deploy
COPY /Y $(TargetDir)*.dll $(SolutionDir)Deploy
The problem with doing it this way, however, is I have 15 projects and would have put this in each individual project's post build event section and also, every time I add a new project, I would have to remember to do the same for it.
I checked the solution file properties and did not see a way to set a solution-wide post build event to copy all the files so I did a few Google searches.
One page said to use a C++ Makefile project. I added this type of project to my solution and clicked on the project properties page and found that there is a section under Configuration Properties->NMake with the following:
Build Command Line
Rebuild All Command Line
Clean Command Line
Using the Makefile project's Command Line option poses a similar problem to above. Many different commands to copy each of my 15 project's output files such as:
COPY /Y $(SolutionDir)Project1\bin\$(ConfigurationName)\*.exe $(SolutionDir)Deploy
COPY /Y $(SolutionDir)Project2\bin\$(ConfigurationName)\*.exe $(SolutionDir)Deploy
...
COPY /Y $(SolutionDir)Project15\bin\$(ConfigurationName)\*.exe $(SolutionDir)Deploy
There is another apparent problem with doing it this way. As you can see I took advantage of the $(SolutionDir) and $(ConfigurationName) macros but I had to hard-code each project name.
I didn't see any macros like $(AllProjects), $(AllProjectDirs), etc.
Also, it appears that command line commands for Makefile projects are for building, not post-build events, so I gave up on this idea altogether.
I then tried using a Visual Studio Installer project. After adding the project to my solution I right-clicked the project and saw that there was an Add->Project Output... option. This brought up a dialog allowing me to add one of my other project's Primary Output. I repeated this for each of my other projects and rebuilt.
What resulted was an .MSI file in the output folder. I then opened installer project properties and changed the Package files option to As loose uncompressed files and rebuilt. The output folder now contained all my project's EXE and DLL files!
Most people would be satisfied at this point and move on but I am the kind of person who likes to find the best way to do things.
There was one thing I didn't like about using the installer project option, the fact that, besides copying the files from all my projects, it also created an MSI file (which I don't need) and I didn't see any option tell it not to create one.
Can anyone recommend a another/better way to accomplish my goal of copying all project output files to a single folder?
Thank you.
P.S. I was thinking I could just make a batch file to search and copy all the EXE and DLL files to the Deploy folder but I would have to run the batch file outside of the Visual Studio IDE and also hard-code the configuration folder (Debug or Deploy).
Can't you just change the Output Directory of the C++ projects? See How to: Change the Build Output Directory.
On the menu bar, choose Project, Properties.
Expand the Configuration Properties node, and choose General.
Change the Output Directory value to the new output directory.
If you want both options, you can also create multiple configurations for your VS projects and solutions, similar to the standard "Debug" and "Release" ones. Create a new configuration from one of the existing ones, then change the output directory and save. Now you can just switch the configuration at the solution level to build into another directory. See this link for detailed steps:
How to: Create and Edit Configurations
I have a solution of about 50 projects.
I have most of those projects (the non-test ones) setup to output to a single folder.
I have heard that "copy local" can slow down build times (for project references), because it has to copy the file to everywhere it is referenced.
But if every project is copying to the same location is Visual Studio smart enough to see that the file is already there and not copy it again?
So, here is an example:
SolutionA
|
+---ProjectA (Output set to C:\MyProj)
|
+---ProjectB (Output set to C:\MyProj)
| References ProjectA
|
+---ProjectC (Output set to C:\MyProj)
| References ProjectB
|
+---ProjectD (Output set to C:\MyProj)
References ProjectA
In a normal solution, copy local would control the copy of the reference to the bin\Debug folder for each of these projects.
But I have updated the "Output" section of the Project Properties so that they all drop to C:\MyProj instead of bin\Debug.
If I do not set Copy Local to false for references, will ProjectA.dll be copied to C:\MyProj four times? Or is Visual Studio smart enough to only do it once?
I think what you are asking is "does it take any time to copy a file onto itself?" As you might expect, it doesn't. You can see this by using Reflector or ILSpy on the Microsoft.Build.Tasks assembly, the Copy class performs the copy. Its DoCopyIfNecessary() method contains this line of code:
if (string.Compare(sourceFileState.Name, destinationFileState.Name, StringComparison.OrdinalIgnoreCase) != 0)
{
flag = this.DoCopyWithRetries(sourceFileState, destinationFileState, copyFile);
}
Or in other words, it skips the copy if the source and destination file are the same. Necessarily so, File.Copy() won't be happy.
Copy Local copies to the bin directory. Usually Visual Studio will empty this directory on a Clean command. If you don't set Copy Local, you run the risk of not having all your references in the bin folder(s).
You can copy them to the bin folder in another way I suppose; but you'd have to do that manually if you ever run Clean...
As far as I know, VS isn't smart enough to see that each project has the same bin directory, so it would copy four times (test and verify though). In the above scenario you could have only one project with Copy Local and avoid this. But, you'll need at least one with Copy Local otherwise you'll have situations where your bin directories won't have the file otherwise.
I'm using the TortoiseSVN client and Eclipse. When I attempt to commit an Eclipse project, TortoiseSVN displays a .settings directory in the file list and says that it is un-versioned. The `.settings' directory seems to be where Eclipse keeps all of its settings for a project.
Is there a way to exclude this directory so that it is completely ignored by TortoiseSVN for this and any other Eclipse projects?
Since you want to ignore this folder globally, you should use…a global ignore!
Take a look at the file
%APPDATA%\Subversion\config
and uncomment the global-ignores line and add .settings to it.
Sample
Sample full path for the file config:
C:\Documents and Settings\pmn\Application Data\Subversion\config
Sample new content of the global-ignores line:
global-ignores = *.o *.lo *.la *.al .libs *.so *.so.[0-9]* *.a *.pyc *.pyo *.rej *~ #*# .#* .*.swp .DS_Store .settings
You can exclude directories like this by right clicking on them in Windows and going to TortoiseSVN/"Delete and add to ignore list" and then specifying it in the sub-menu:
This is really easy to do, I have to do it quite often.
You can specify resources to ignore under Window -> Preferences -> Team -> Ignored resources.
If you're using Eclipse you might want to try out subClipse, it's a free subversion plugin for eclipse and it will allow you to exclude the .setings folder. See this link.
However, are you sure you don't want these to be comitted? Since your project is build in Eclipse, one could say that the setings are a part of your project.
Personally I like to commit these files as they allow me to keep the same settings for every project on every location and for every developer.
How can I make a project file (VS 2008) that just has some data files in and has no built output?
I can make an empty project and add my data files to it (which get copied to the output folder
), but it produces an EmptyProject.dll after I do a build. I want just my data files in the output directory and not some empty DLL or EXE.
I want the data files to be the only thing in this project as the project will be shared in a couple of solutions.
Our application is C#. All of our normal code projects are C#.
The data files are schemas (XSD). I want these schemas to be in the output folder, but I don't want them included with an existing project. I would like a project named "Schemas" that has nothing in except the XSD files and does nothing except copy the XSD files to the output folder. I would like this in a project file so that the same schemas project can be referenced in multiple solutions.
I don't know of a way to suppress the creation of the .dll file. BUT... here's an easy workaround. In the project properties, Build Events tab, write a Post-build event command line that will delete the file. Something like:
del path\filename.dll
Expanding on Scott's answer:
Create a new project of type Empty project
In Properties->Application, change Output type to Class Library
In Properties->Build->Advanced, change Debug Info to None
In Properties->Build Events, set the Post-build event command line to del $(TargetPath)
That way, the project creates only a DLL, which gets deleted. At the same time, the "copy to output directory" settings on your data files is respected.
Possibly another way is editing the csproj file by replacing this:
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
with this:
<Target Name="Build" />
<Target Name="Rebuild" />
Then builds don't create anything. It worked for me.
Same general idea should work for any xxproj file. Just replace the <Import Project...> tags with the <Target...> tags.
I'd be interested in knowing if this causes any issues or doesn't work for anyone.
What do you need a project for if you're not building it?
You can use solution folders to "store" files...
Why not just disable building this project for all configurations (use the Configuration Manager) - that way it won't build.
Great stuff. Expanding on Scott > Daniel's answer:
Safe to remove all References and Properties (AssemblyInfo.cs)
If it is a node/grunt/gulp project then you can invoke it in your Build Events > *Post-build event command line * eg: gulp build or gulp clean
Perhaps you can add removal or obj and bin output folders to your node/grunt/gulp clean scripts mitigating the need for del $(TargetPath)