How to make successive version of a project in Microsoft Visual Studio 2010 - visual-studio-2010

Maybe I just can't figure out the right keywords to get an answer out of Google, but here goes.
Say I have a Project I'm working on named "Project." For it's first version, I have it stored in the folder "Project_Version1", and have the name of it's solution, project, build exe, etc as "Project_Version1".
Now I want to make the next version of the Project, and call it "Project_Version2". To do this currently, I copy the original folder, and rename it to "Project_Version2", and I want to rename all of the other internal stuff to that as well. Currently, I have to do that with a combination of changing the names in windows explorer, and some of the various properties pages in my solution.
There has to be a better way to do this. How does somebody make a second version of their project, and store it's files separately from the first version? Is there a way to also rename appropriate files that contain version numbers?

Indeed, there is a better way to do this, it is called version control.
If you check your source into TFS (or git or any other SCM software) all versions will be tracked over time.
If you then need to maintain multiple versions simultaneously (e.g. for a customer base where customers slowly migrate to the bleeding edge and patches are required to fix critical issues in older, supported versions) you can keep these versions as branches and selectively merge changes.
If you do decide source control is a good fit for managing your versions (It brings a lot of other benefits as well), consider reading some posts such as this git tutorial or why use version control.
If you REALLY can't use source control, for some reason, I suggest trying to reference as much as you can using language constructs which can be easily changed (e.g. with C# and a reasonable IDE, a quick refactor, or with other languages some rigorous de-duplication of version-specific data).
Ideally you would have just one definition of the version for your code along with a version definition in the project files (which could be set as a build variable to change quickly).
In this case you would copy the project, change the code version and the version variable for the project and, assuming good use of relative paths etc. (no hardcoded versions!), a quick rename of a couple of variables should get you going.
Ideally, the bulk of of the file-names would not reference the version. The only thing referencing the version should probably be the containing directory, the project/solution files and a few isolated references in your code.

You can do some pretty neat tricks with MSBuild. Let's say, for instance, that this is your project.
Program.cs:
namespace MyCustomBuild
{
class Program
{
static void Main(string[] args)
{
System.Console.WriteLine("Hello World");
}
}
}
Create your MSBuild file as shown. build.msbuild:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<MajorVersion>1</MajorVersion>
<MinorVersion>0</MinorVersion>
</PropertyGroup>
<Target Name="Default">
<CombinePath BasePath="$(MSBuildProjectDirectory)"
Paths="Program.$(MajorVersion).$(MinorVersion)">
<Output TaskParameter="CombinedPaths" PropertyName="OutputDir"/>
</CombinePath>
<MakeDir Directories="$(OutputDir)"/>
<Csc Sources="program.cs"
OutputAssembly="$(OutputDir)\Program.$(MajorVersion).$(MinorVersion).exe"/>
</Target>
</Project>
After running msbuild build.msbuild, this is the result:
Ways to make what I posted even better:
Use the MSBuild Extension Pack AssemblyInfo. This will allow you to change the version info if you have it defined inside an AssemblyInfo.cs file. Or you can look into the GenerateApplicationManifest Task, which can set assembly versions, but as of right now the file version of the executable will always be 1.0.0.0
Implement some sort of autoincrement system like this one
You can copy all your source files into the versioned directory using the Copy Task
It's a lot to take in, especially if you aren't familiar with MSBuild, but it's a powerful program that allows customization that Visual Studio can't even imagine! Note that a solution file (.sln) is a MSBuild file, even though it's not xml.
Hopefully this is what you are looking for. I do also recommend that you use an official version control, as others have mentioned, but you seemed to have a specific task you wanted automated, which is MSBuild's forte.

Ideally, versioning your project should be done within a source control system since Visual Studio in and of itself is just an IDE.
In the situation of not using a source control system, unfortunately I'm not aware of a better solution than what you are doing currently.

Related

Building related projects on Visual Studio

I am a Visual Studio noob. My background is more Unix-related and mostly used to building things via scons or make. I don't even have much Eclipse experience.
Anyway, I am frustrated how it seems very difficult to move files between projects in VS. (I am running Visual Studio 2013). For example, suppose I have a ProjectXRel (release) and I want a ProjectXDev (development). I want them both to be runnable, and the dev version might have just a few editing changes that differ it from the rel version.
The intuitive thought is to just copy the files from ProjectXRel to create ProjectXDev, but VS seems to fight me on that (it wants to rename all the namespaces to the title of the project).
Also, some of the files, like .cs files derived from .dbml via OR designer, seem uncopyable, and rely on one replicating the process of using the utility to having valid files. I'm used to a project being defined by its files, but that's not really the case in VS. Instead it seems defined by process steps used to create and organize the files.
Also, do serious developers just use command line calls and powershell? That's seems harder, but at least you know what the %#$$# is going on.....
So, the basic question is, how does one replicate an existing project to produce a similar one for development purposes? (I know source control such as git could help with that, but that's not an option for this situation.)
Thanks!
You should be using the same project for both Development and Release.
The things that are different between Development and Release should be stored in a config file (web.config or app.config, depending on what type of project).
You should then be using Configuration Transformations to transform that .config file into Development or Release.
In Visual Studio, right click on the project and click Add New Item, select "Application Configuration File".
In this file you can put connection strings or key/value pair settings in the AppSettings element (MSDN Link).
Once you have your basic settings defined, you can then right click on the config file and click Add Transformation. This will add transformations for each of the Project Configurations you have. (by default Debug and Release).
It will look like this:
Now you can build deployment packages.
Or install Slowchetah and then when you press F5 to debug it will run the selected project configuration with the configuration transformation applied.

MSTest: A sensible way to deploy items from a common directory?

I have lost a few hairs when trying to deal with DeploymentItem recently.
We have a few common directories for native dll's, and many tests depends on these.
For C++ projects, we use propertypages, where these paths are defined. These can even be imported in a C# project aswell, with some manual editing (as they are MSBuild files). Still I can't figure out how to utilize them in tests.
Unfortunately, the DeploymentItemAttribute can't use the properties in the sheet, but it can utilize environment variables. I was hoping to avoid forcing everybody to define global environment variables...
I have seen various suggestions around the net, but haven't really found a simple solution.
Anybody have good approach to this ?
Anders' answer is a good solution, but in my case:
I don't like the idea of keeping binaries within the source tree
Many dlls dont have specific versions, and they are updated on regular
basis.
I somehow ended up with this solution:
First, I included the global VC++ property page into the test project. This must be done manually by adding this directive under the <Project> tag on top of the .csproj:
<Import Project="$(UserProfile)\AppData\Local\Microsoft\MSBuild\v4.0\Microsoft.Cpp.Win32.user.props" />
I now got access to the properties/macros that defines the dll paths in my C++ environment.
I then
added a new subfolder in the test-project, say "NativeDlls"
added the needed dlls as links into the NativeDlls folder
the links are absolute, but can be replaced with macros from the
property sheet included above:
<Content Include="$(MyLibLocation)\GDAL18BIN\gdal18.dll">
<Link>NativeDlls\mylib.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
The dlls is then ready to deploy:
[TestMethod]
[DeploymentItem(#"NativeDlls")]
public void TestSomeStuff()
{
}
And, as Anders mentions: The remaining work is to set debug/release and 32/64 conditions.
If these are external dependencies used only by this project (not shared between source trees) then I suggest moving them into the source control. Dependencies should be versioned together with the source. The rationale being that you should be able to check out a revision of the source tree (any revision in the history), and it should build. If you have binary dependencies that are not under source control, you will have problems knowing which version of the dependency you need when you build a specific version of the source.
If you can move the dependencies into the source tree (e.g. $svnroot/trunk/dependencies) then you can use test deployment with only relative paths. It will work under TeamCity as well as on any developer machine.
If you cannot version your dependencies or you must have them outside the repository for some other reason, then you can use an environment variable that the test deployment can use. See This msdn post for an example
EDIT: moved a comment about managing binary dependencies here
For csprojs I just have a dll-reference in the projects to the dll:s in the lib directory under the source tree (i.e. reference to ..\lib\log4net.dll). If you want to reference separate libs for separate builds, e.g. different for x86/64 or Debug/Release, then VS doesn't support it but MsBuild and the csproj file does, so you can add conditional references but you have to edit the csproj by hand to include for example the x86 dependency only if platform is x86 and so on.

Anhksvn + Visual Studio - working with linked files

I could use some advice.
I'm in the process of adopting subversion, and I'm trying to put some existing Visual Studio 2010 projects into a repository. I have the current version of AhnkSvn.
The projects I have are organised as;
VS2010_projects\Project_A
VS2010_projects\Project_B
VS2010_projects\Project_C
VS2010_projects\Common_code
Where Project_A, Project_B and Project_C may all refer to one or more files in "Common_Code"
In visual studio, these files will have been added using "add as link".
There is no actual project in "Common_code" just a collection of useful code files, which we're likely to re-use in different projects.
(If we have a module or class which is re-used in various projects, then we often keep a single master copy in 'common-code', and link to it.)
Visual Studio has no problem with this.
When I add any of the actual projects to subversion, all of their own files are added just fine, but the linked files are ignored.
(And as a consequence, if I then get a working copy of those files, then it's just the project files which get handled, I won't get a copy of the linked files.)
If I right click on any of the linked files, I the only subversion options I get are to refresh their status or to select the working folder.
I was wondering what the correct way to handle this situation was ?
Any advice would be much appreciated
Thanks !
Robert
if I understand your question correctly then I think SVN is acting in the desired way. A linked file is merely a reference to another file. That reference exists only in the .csproj file which is checked in. It would not make sense to have two copies of the same file in source control, and it could lead to versioning issues. The first time you checkout your repository doing a build on your projects should copy the files from Common_code to the places that they're linked.
As an aside we've had alot of random issues with .csproj linked files and SVN, and so try to avoid linked files where possible. A better way to re-use files across projects is obviously just to embed them in a library and then reference that library. This should work fine with the exception of certain files like Javascript/CSS.
Also you may want to check out SVN externals, a workmate mentioned this can be used to share common libraries between multiple projects, although as a disclaimer I haven't tried this myself and can't comment on the merits or drawbacks of the approach.
Thanks for the advice, I actually did something similar to your suggestion.
I didn't want to make a full blown library, but I did make up a dummy project, and put my shared files into that.
Then I added the dummy project to the repository.
AhnkSvn now seems to be satisfied that the linked files are under subversion control, and seems to handle them just fine.
(I haven't added any reference to the dummy project to my existing projects - they just use the linked files as before - but now AhnkSvn shows me their status, and allows me to get the latest version, and commit changes.)
I can see the case for having a proper library - but that would have meant modifying a large body of existing projects. This approach lets me get up and running with Subversion without requiring those changes first.

Visual Studio 2008, MSBuild: "replacement" projects

My solution has a library project which needs a special environment to be built (lots of external libraries and tools)... but it is not vital to our application. We'd like to avoid installing these tools when not necessary (most of our developers work on other parts of code).
We have created another project which has the same API, but has an empty implementation and is compilable without those external tools. I'd like to be able to easily switch between those projects and still get all the references in other projects correct.
I don't know VS/MSBuild very well, but willing to learn whatever is necessary. Is it possible? I am looking for ideas... We're using Subversion, and solutions involving some hacks inside VCS are also welcome.
It sounds as if your library project is one that can be separated from your primary solution, taking the tool baggage with it. Doing that, you could build the speciality solution separately, an link the compiled assembly from the main solution.
Create another build-configuration for your project.
So you will have at least 2 build-configurations e.g. Debug_SpecialNeeds and Debug.
For discussion, I'll assume you have a project directory containing your solution file, a "RealLibrary\RealLibrary.csproj" project file (your "real" library, with the dependencies), and a "MockLibrary\MockLibrary.csproj" file (your "mock" library, with the empty implementations).
If I understand correctly, you want to easily "swap" the MockLibrary for the RealLibrary in your solution, and vice-versa.
The easiest/hackiest way to do this, assuming your solution (and dependent projects) are configured to look for the "RealLibrary.csproj" project, is to rename the "RealLibrary" directory (it doesn't matter to what), and rename the "MockLibrary" directory to "RealLibrary" and rename "MockLibrary.csproj" to "RealLibrary.csproj". This will effectively "trick" your solution and dependent projects into loading the "mock library" even though they are referencing the "real library".
A slightly more complex (and perhaps cleaner) solution is to actually modify your "sln" and "csproj" files to reference "MockLibrary.csproj" instead of "RealLibrary.csproj". In the "sln" file, you'll need to change the path to the project in the section near the top:
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RealLibrary", "RealLibrary\RealLibrary.csproj", "{E1714F9A-E1D9-4132-A561-AE2B4919391C}"
EndProject
You need to change that path "RealLibrary\RealLibrary.csproj" to "MockLibrary\MockLibrary.csproj". If you're going for completeness, you can change the name as well (or perhaps just use a generic name like "Library" for the name).
Likewise, in the dependent csproj files, you'll need to find all instances of the "ProjectReference" node where you reference "RealLibrary.csproj" and modify the path. These sections look like this:
<ProjectReference Include="..\RealLibrary\RealLibrary.csproj">
<Project>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Project>
<Name>RealLibrary</Name>
</ProjectReference>
You could relatively easily write some scripts to perform this swap. However, I think there's a deeper problem here that can be addressed more directly. I'll post that as a separate answer, but I wanted you to have the actual answer you were looking for first.
The deeper problem I see here is that your library "needs a special environment to be built", specifically because it depends on "lots of external libraries and tools". I would suggest that you NOT go down the path of creating the mock library, but instead focus on getting the library to build correctly without a special environment. You can achieve this by including all of those dependencies in source control along with your project, and reference those dependencies via relative paths inside your working copy. In my build environments, I try to avoid static environmental dependencies as much as possible (ideally limiting it just to the .NET framework itself).
To get the dependencies into source control, you can either check them directly into the project itself, or you can check them into a different location and then "reference" them in your project via svn:external definitions. In my environment, I have a separate "bin" repository used just for these kind of third party library dependencies, and then many dependent projects can pull them in via externals.
If you can eliminate your library's build-time environmental dependencies, your build will be much more robust and it will be much easier for developers to work with the project.

Visual Studio msbuild

I have a question regarding the commandline options of msbuild. I am
currently using msbuild to build projects using the existing solution
files. These solution files have references to external dll which have
different paths on each machine. I am currently writing a build script
and passing the specific path to the project file via the /p: switch of
msbuild.
My current build line is:
msbuild test.sln /p:ReferencePath="c:\abc" /p:ReferencePath="c:\rca"
What i have noticed that Reference Path now contains only c:\rca and
not c:\abc. this is causing problems for me since, the external dlls
lie in two different directorys. I am allowed to keep multiple
reference paths via visual studio, but not via the commandline.
Is there any known way by which i can do this
I believe you can use this /p:ReferencePath="c:\abc;c:\rca"
At least that is what that link is hinting at, they are using %3B to encode the ";" within the build file.
Although the correct syntax for providing more the one reference path is listed above, I would suggest solving the root cause which in my opinion is the different locations of your referenced assembly. I would suggest you put all thirdparty dependencies, apart from the framework assemblies in your source code repository for the following reasons:
Relatitve paths are consistent across computers
The source code is always in sink with the correct version of your thirdparty assembly (if you for instance need to build an old version of your software 2 years from now).
Upgrading your thirdparty assembly is as easy as upgrading on one machine and then committing your changes to the repository. (In a previous project we even went as far as checking in the entire java runtime environment and were quite happy with the given setup.)
Try seperating your pathes with a semi-colon (;)
Like this:
c:\abc;c:\rca
You may be better off by synchronizing your libraries across machines. I have found that Visual Studio makes this easy. Simply add a solution folder, and add your libraries there. Then, in each project, reference the libraries from this common place. This way, each developer has them in the same place.
This will remove one of variables you have when trying to script out builds.
The command line options for setting the reference path will work just fine (assuming you escape the semi colon, it seems both %3B and ; will work). However, when the argument was passed in from nant (and I needed multiple paths), creating a 'Visual Studio Project User Options file' seemed to work better.
I just emit (echo) a file to the file system with the following format:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ReferencePath>
C:\abc;c:\rca
</ReferencePath>
</PropertyGroup>
I give the *.user file an appropriate name (given a project file MyProject.csproj, my user file would be MyProject.csproj.user)

Resources