Dynamically update .csproj during Visual Studio build - c#

We have a very complicated multi-stage build system:
Auto-generate a ton of C# from XML.
Compile C# with Visual Studio.
Post-compile non-Microsoft-native languages like Sass and JavaScript.
(...more steps for database-oriented things...)
Importantly, in the first stage, a set of short XML files are transformed into C# files. Various .csproj files are automatically updated to add any new C# files that were generated, and to remove any C# files that are no longer relevant.
This has been the way our software has been built for many, many years, and it has been a big, big win for us. More than a million lines of our code are automatically generated from only a few thousand lines of XML: Our overall design of using custom code generators definitely isn't going to change!
However, the code-generation process lives outside Visual Studio, as a manual step. We'd really like to integrate the code-generation process into the standard Visual Studio build.
Our plan was to have the code generation run as a pre-build event on an otherwise-empty .csproj file, and it would generate the next .csproj file before Visual Studio had a chance to get to it (using Dependencies to control build order).
Unfortunately, Visual Studio's build-caching logic defeats this: One .csproj apparently can't modify another .csproj file during the build, because Visual Studio caches the second .csproj file's contents.
Visual Studio complains loudly if you try, with delightful inscrutable error messages and general glitchiness.
So is there a way around this? Is there a way to have substantial C# code generation as part of a Visual Studio build?
Or are we stuck with having it as a separate, manual process outside Visual Studio?

Related

How to get visual studio debugger to completely ignore original source file location

I'm beginning the work of moving an internal class library (.net framework, C#) to a series of nuget .net standard packages, which we will also serve internally. I'm in the research phase.
And I am attempting to research using the VS (2017) debugger and working to create our conventions for where debug versions of the packages (with symbols) will be and where the release versions (without symbols) will be.
I build a small dummy .net standard package in one solution, and have used nuget add to place it in a file share. And I have successfully consumed it in a different solution.
However, when I try to step into the code in the consuming solution, somehow, visual studio is doing something smart and actually stepping me into the source at its ORIGINAL location. Which is fine in some ways of thinking about it, but I want to simulate the situation of a different developer on a different machine consuming the package and not having that original source available, such that the only way to step into packaged code would be to consume a debug version with symbols. But visual studio is foiling me by figuring out the original source location and I don't see how it is doing that.
How can I get VS to be "dumber" so I can simulate on my machine what it would be to consume packages on another machine that didn't have this package source?
Thanks in advance.
How can I get VS to be "dumber" so I can simulate on my machine what it would be to consume packages on another machine that didn't have this package source?
You can try to specify the Symbols of that .net standard project to exclude from automatic loading.
Detail:
As we know:
The Program database (.pdb) files, also called symbol files, map
identifiers and statements in your project's source code to
corresponding identifiers and instructions in compiled apps.
Symbol files also show the location of the source files, and
optionally, the server to retrieve them from.
And the default setting of symbols loading for debugging in Visual Studio is that Load all modules:
That is the reason why Visual Studio smart and actually stepping your into the source at its ORIGINAL location.
So, to resolve this issue, we need to disable Visual Studio "Load all modules", we could specify excluded modules for your .net standard project.
To accomplish this, click the link on that window, then add the name of your .net standard:
Then Visual Studio get to be "dumber", not find the ORIGINAL location.
Hope this helps.

Visual Studio 2017 outputting older build versions in bin/debug folder

When I build a C# program (this has been going on for several different solutions/projects I have been working on) in Visual Studio 2017, the new, updated code will build and run in debug mode (and run correctly).
However, the application that Visual Studio has been outputting when I build/debug them has been remaining with the original, first version of code that I saved. When I choose the options to rebuild, it will update the time stamp on the application and .pdb files, but the application will perform the way it did in earlier code versions, not the most recent code version that was running problem when I ran debug mode immediately after pressing Ctrl + F5.
These are C# Console Apps with the .NET Framework 4.6.1, if that makes any difference. I checked the output folder, and it is indeed the desired folder and the one I have been looking in... so why is the time stamp updating on the application (.exe file) that it outputs, but not the code itself? What am I missing?
When I run into strange things like this in Visual Studio, the first thing that usually works is to clean the project and rebuild. If that doesn't work, I'll close Visual Studio, re-launch, then clean and rebuild again. If that doesn't work, I would start looking into any extensions you have installed that might be getting in the way of your build process.
Further, you can look into logging the extensions activity to help troubleshoot if there are issue there. See the following article:
https://blogs.msdn.microsoft.com/visualstudio/2010/02/24/troubleshooting-extensions-with-the-activity-log/
You may have already tried this, but since it wasn't mentioned I thought I'd provide it for others in a similar situation.
Two possible reasons:
(1) Your project was not recompiled during debugging. Please enable Edit and Continue under TOOLS->Options->Debugging.
(2) Visual Studio has a concept of incremental build. If you have a solution with two or much more projects and if you change source code in only one of the two projects, the "Build" command will compile only the modified project. But the "Rebuild" command, on the other hand, it will recompile all projects in this solution.

Open Visual Studio 2008 Solution in Visual Studio 2013 without Upgrading

In short: I need to open an application originally built in Visual Studio 2008 (version 9) in Visual Studio 2013 without upgrading the project since the overall project architecture must remain the same for when I check it back into source control.
Details: I need to open a Visual Studio solution (.sln) inside Visual Studio 2013. The solution in question was originally developed in Visual Studio 2008, so when I try to open said solution in Visual Studio 2013, I am shown a prompt with the projects within the solution checkmarked, with the message:
These projects are either or supported or need project behavior impacting modifications to open in this version of Visual Studio. Projects no displayed either require no changes or will automatically be modified such that behavior is not impacted. Visual Studio will automatically make functional changes to the following projects in order to open them. You will not be able to open these projects in the version of Visual Studio in which they were originally created.*
My attempt at a fix was to just upgrade the solution and hope for the best. This is successful, but after building and attempting to run the main project, I see the following build error:
The type 'Microsoft.Web.Services3.WebServicesClientProtocol' is defined in an assembly that is not referenced. You must add a reference to assembly 'Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. *
I then tried both commenting out the references to this assembly and adding in the missing reference. Okay, so then I rebuilt the solution and attempted to run. Same error, but for a different assembly. Repeat fix, same error for different assembly. This pattern continues and continues, and at this point I realize this is unacceptable anyway, because when I make a change to this solution, I need to check it back into source control. When others open it, they may be opening it in VS2008, and therefore this “upgraded” version is inconsistent with the version the business uses. I need to open the solution originally build in VS2008 in VS 2013 (can't work around this, needs to be VS2013). If it helps, I'm using 64 bit Visual Studio 2013 Ultimate.
Any help or guidance will be greatly appreciated!
As several of the commenters have already helpfully pointed out, this is not possible. Round-tripping (i.e., opening and manipulating project files created by an older version of Visual Studio in a newer version of Visual Studio) was not supported until Visual Studio 11. The only way to open a Visual Studio 2008 project/solution in a later version of Visual Studio will be to convert it.
As far as interoperability with previous versions is concerned, you have two options:
Update the project locally (using the migration wizard provided), make any changes to the project file necessary to get it to build, and then edit the code files. Once you're satisfied with your edits, commit only the modified source files, not the project infrastructure files. Your fellow developers, stuck on VS 2008, won't notice any difference.
Update the project locally (using the migration wizard provided), make any changes to the project file necessary to get it to build, and then rename the project file (e.g., by appending a -vs2013 suffix to it). Commit this to your code repository. You will now have two project files in your root directory, one for each version of Visual Studio that your team works with. From here on, you just open the project file corresponding to the version of VS that you have installed.
I used approach #1 for a good part of last year, where I spent most of my time developing a C++ application in VS 2010 on a desktop machine, but also wanted to work on it on my notebook running VS 2013. Of course, in my case, it took a trivial amount of time for the automatic conversion to upgrade my project file after pulling from source control. I didn't have to do any tweaking thereafter to get the project to build. It sounds like your case is different, so option #2 might be a better choice.

Visual Studio Error and Output Window Contents

I was recently asked by a co-worker if it was possible to automatically output the contents of these windows into a text file automatically each time the solution is built.
I have been using Visual Studio .NET since the original release. I have not witness a way to do this, I also never had the need, so I simply could have glanced over it.
There must be a way to tell csc.exe and MSBuild to output to a file.
I forgot to mention this is a Visual Studio 2005 C# project.
In 2010 (assuming it's the same for all others) each project generates a %name%.log text file in it's own directory by default. The solution does not though, so you may need to concatenate all these files or something similar.

Working with multiple versions of Visual Studio

I'm trying to find a way of being able to use multiple versions of Visual Studio on the same set of projects. The majority of our team uses 2008, but I am trying out 2010. All projects are C#.
As I understand it Visual Studio 2010 insists on upgrading all projects, so it's not possible to leave all the solution/project files as 2008 versions. I really don't want to branch the entire source tree, so I'd like to find a way for multiple versions of the project files coexisting. Currently, I've duplicated all .sln and .csproj files so I have:
# 2008 versions
SolutionName.sln
ProjectA.csproj
ProjectB.csproj
# 2010 versions
SolutionName.vs2010.sln
ProjectA.vs2010.csproj
ProjectB.vs2010.csproj
The trouble is, despite the 2010 versioned files all having the same assembly names as their 2008 counterparts, Visual Studio (2010) believes the projects are all ProjectName.vs2010. Renaming the project in VS fails with a message saying a file of the same name already exists.
I don't think putting the 2010 version in a sub-folder would be a solution as it would screw up any relative paths in the files.
So:
Is there any way to convince VS that the project name should not be suffixed with .vs2010 (i.e. not the same name as the file)? Or
Am I approaching this the wrong way? Is there a better way of working with multiple versions of VS on the same projects?
UPDATE
My initial claim was wrong that Visual Studio was failing to find the project references because it was using the file name. The specific problem I was having was that in my build files the project references were of the form:
<ProjectReference Include="..\..\path\to\ProjectName.vs2010.csproj">
<Project>{48354450-2462-449D-8B32-EFECA39F6CD7}</Project>
<Name>ProjectName</Name>
</ProjectReference>
The project files that I copied apparently have a different ID (or whatever it is in the <Project> element. Simply removing the element from the build file has solved that particular issue:
<ProjectReference Include="..\..\path\to\ProjectName.vs2010.csproj">
<Name>ProjectName</Name>
</ProjectReference>
Having said that, the whole process of duplicating the project and solution files has actually been more effort than it's worth, so I'm not recommending this approach.
Do you often modify the projects?
You could simply work with your upgraded version of the csproj and sln files.
This way you would commit/check-in all changes to source code files except for the project files, which are not often modified anyway (except to add new files).
Then if you want to commit the changes in the project files, you'd work with an intermediate local VS2008 version of the file and line it up using your favorite diff/merge tools before eventually committing this VS2008 version. It would be some kind of local branch.
Unless you absolutely have to work with different versions of Visual Studio, those of the team still using 2008 could upgrade to Visual Studio 2010 Express. It's free for commercial use, and lacks only a few advanced features you might not need.
Have you tried opening the SolutionName.vs2010.sln in a simple text edior and changing the diplay name of the projects?
(form: Project("{$GUID}") = "$DISPLAYNAME", "PROJECTFILE", "{$OTHERGUID}"
Answering the second part of your question:
Why is it important to cover up that there are multiple versions of the project files? The reality is that there are two versions and you have to be careful to maintain both of them concerning the state of your project anyway (files are addded / renamed/ deleted; configuration options are changed).
Having two sets of projects and solution files will lead to differences between them which will break things.
Generally: Don't mix Visual Studio releases in the same project. Keeping the toolchain identical between developers will save you much trouble.
visual studio 2010 and 2008 project files (.csproj) are compatible side by side if you have both editors installed, meaning you can upgrade it, work on it in 2010, and have someone else work on it in 2008 without any issues. the only caveat is that you have to leave the target framework as .net 2.0 or 3.5 and that those who work in 2008 have to also have 2010 installed.
the only problem comes if they try to then open the project file in 2008 and they don't have 2010 installed (because I think 2010 adds some new build target that a standard 2008 won't know about). I didn't think this was a problem but I just ran into it this past week (on a web project), so it does exist in some form for some projects.
if you do go the rename route, the best way to go about that is to open the sln file in notepad, and rename the csproj references to the new names by hand (adding any new renamed folder paths), then renaming any folders outside visual studio, then renaming the file name in windows explorer, then rename the csproj in windows explorer, then open the solution in visual studio. your scm bindings may be hosed at that point though...

Categories