Just starting with VS2022 and the new .csproj format.
In the old format every project had something like this:
Properties\AssemblyInfo.cs
[assembly: Guid("e8151094-eb82-46bd-9809-523d4a4fcfb8")]
I can't figure out where that is stored in the new format. The project obviously has a guid because it is used by the sln file:
{my_solution_name}.sln
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "{my_project_name}", "{my_project_path}", "{1C64FF26-B077-494E-93F2-380D675B668D}"
I have seen a couple articles that suggest there could be <ProjectGuid></ProjectGuid> in the .csproj file, but it isn't there by default when you create a new project, so where it is hiding?
Additional background:
we have an internal tool that basically constructs a large multi-project solution template for when we start a new app. It generates new guids for each of the sub-projects and writes new AssemblyInfo.cs files, then it builds the .sln with all the reference lines. I don't see a clear way to do that with the new .csproj format.
In the new project system the ProjectGuid is no longer required for projects itself and is used in solution file (and is "stored" there).
Related
I remember when VS templates only included x86 targets and you had to add an x64 target manually. Now it generates both. Now I would like the reverse; x64 target generated and add x86 if needed. It's easy to delete the x86 configuration, but hey, I am a human so I'm lazy.
To me, the whole XML template tree is a bowl of spagetti. An answer to this question may help it become clearer.
I solved it by creating a new template and then modifying its .vcxproj file. Here are the steps to create a console app with x64 platform only.
Create a new console project.
Export it as a template. I called it console_64.
Go to "C:\Users<user>\Documents\Visual Studio 2019\My Exported Templates". Here you will find the template zip file, in my case, console_64.zip.
Extract the .vcxproj file.
In the project file, delete all XML nodes that refer to Win32. These will be <ProjectConfiguration>, <PropertyGroup>, <ItemDefinitionGroup> and <ImportGroup> nodes.
Save the file and update the zip overwriting the existing .vcxproj file in there.
Start a new VS session and voila! I now have a template, console_64, that creates a console solution with only the x64 target.
It will only save me a handful of mouse clicks per year yet I'd still like to know how to do it globally.
I have a Visual C++ 10 (VS2010) .vcxproj project file and I want to copy it and use the copy in the same solution file as the original project.
I understand that I need to generate a new ProjectGuid in the new .vcxproj file, but I don't know what edits I would need to make to the .vcxproj.filters file.
In the .vcxproj.filters file, I see that there are many UniqueIdentifier elements which have GUIDs for values. I assume that I would need to re-generate all of these in the new .vcxproj.filters, but Visual Studio didn't report any errors and didn't seem to have any problems with having the same GUIDs in two different .vcxproj.filters files in the same solution file.
Does anyone know if it is safe to have duplicate UniqueIdentifiers across different .vcxproj.filters files in the same solution file? Does anyone know what these UniqueIdentifiers are for?
Is there an easier way of making a duplicate of a .vcxproj / .vcxproj.filters pair without having to regenerate every single GUID used in the .vcxproj.filters file?
I have read this post thoroughly: How does Visual Studio's source control integration work with Perforce? and found it very informative. However, I have a specific issue that is blocking my use of Perforce in VS.
For the most part, I have no complaints about the plug-in (I'm still using the P4VSCC plug-in because the new plug-in requires conversion by the entire team which can't happen at this time). Once I understood the idiosyncracies, I've had only one problem working with the plug-in.
Our solutions contains many projects that are built into a single deployment package. As such, each assembly is versioned the same. To accomodate this, and other common aspects, we have defined a common "SharedVersionInfo.cs" file which contains the AssemblyVersion and AssemblyFileVersion attributes typically found in the AssemblyInfo.cs file. This file is stored in an Assets folder beneath the solution folder and added to each project's Properties folder as a linked file. This works great from a version management perspective as we only have to change the version in one place and all assemblies are updated. However, Perforce has a problem with this when a new developer first opens the solution or when a new project is added. The only remedy we have currently is to remove all of the linked files (there are 3 per project in this solution), bind the project to source control, then re-add the linked files.
This isn't such a big deal when we add a new project but the solution contains 80 projects (and counting), so this isn't a viable remedy for a new developer!
My understanding is that the problem has to do with where VS thinks the binding root for each project is. After some research, I was led to find where the MSSCCPRJ.SCC files are for the projects. I found there are numerous SCC files scattered throughout the solution structure. So...
First question: Why are there multiple MSSCCPRJ.SCC files in my solution structure?
We also have several shared/common projects that we use in our solutions. This leads to the following folder structure:
/Source
/CommonTools
/ProjectA
ProjectA.csproj
/ProjectB
ProjectB.csproj
/MySolution
/Assets
SharedVersionInfo.cs
/Project1
Project1.csproj
/Project2
Project2.csproj
:
/ProjectZ
ProjectZ.csproj
MySolution.sln
Where both ProjectA and ProjectB are part of MySolution.sln
Second Question: How can I setup the bindings so the /Source folder is considered the root? This would ensure that all projects included in the solution are under the same binding root. Perforce considers this folder to be the root, how do I get VS and the plug-in to do the same?
Since no one else has offered up a solution, I thought I'd follow-up with my own findings for anyone else that comes across the thread.
First, I still have no idea why Visual Studio creates multiple MSSCCPRJ.SCC files but these are the key to establishing the "binding root" for a solution. It is critical that this file exist at the highest level necessary so that ALL of the projects in the solution are in sub-folders relative to the location of this file. In my example above, the MSSCCPRJ.SCC needed to be located in the /Source folder. Having it in the /MySolution folder caused the original problem when adding projects from /CommonTools into the solution.
That said, resolving the issue was no easy task. I had to manually edit the .sln and all of the .csproj files in Notepad. What I found was that some of the .csproj files had the following elements identifying the source control settings:
<SccProjectName>SAK</SccProjectName>
<SccLocalPath>SAK</SccLocalPath>
<SccAuxPath>SAK</SccAuxPath>
<SccProvider>SAK</SccProvider>
I don't know what SAK stands for, but my understanding is this tells Visual Studio to use the binding information contained in the .sln file.
I had to change these to:
<SccProjectName>Perforce Project</SccProjectName>
<SccLocalPath>..\..</SccLocalPath>
<SccAuxPath />
<SccProvider>MSSCCI:Perforce SCM</SccProvider>
where the SccLocalPath value is the relative path from the .csproj file to the MSSCCPRJ.SCC file.
I also had to change the SccLocalPathX and SccProjectFilePathRelativizedFromConnectionX statements for each project in the .sln file. The SccLocalPathX value should be the relative path from the .sln file to the MSSCCPRJ.SCC file - a dot (.) if in the same folder. SccProjectFilePathRelativizedFromConnectionX should be the relative path from the binding root to the .csproj file.
I wish I could say that having that in place, I never had to repeat these steps. Unfortunately, I still have to go in and make corrections every time I added a new project to the solution. Visual Studio still wants to use SAK for the elements in the .csproj file and sometimes the values in the .sln file aren't quite right.
But, at least I know what to look for and what needs to be done to achieve my goals. If anyone else has a better solution or a way to configure VS and/or Perforce so these settings are created correctly up-front, I'll gladly give credit.
Hope that helps...
I am using a text editor to manually edit my *.sln file. I am confused about the following lines:
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test2008", "Tools\Test2008\Test2008\Test2008.csproj", "{00B5EBB2-FDA5-4B23-BDC5-27E9F82E7C69}"
ProjectSection(ProjectDependencies) = postProject
{82B9BEC0-C9CC-4423-B54F-61E3C4AF53D8} = {82B9BEC0-C9CC-4423-B54F-61E3C4AF53D8}
EndProjectSection
EndProject
What's the point of this
{82B9BEC0-C9CC-4423-B54F-61E3C4AF53D8} = {82B9BEC0-C9CC-4423-B54F-61E3C4AF53D8}
statement? It looks totally superfluous.
The {82B9BEC0-C9CC-4423-B54F-61E3C4AF53D8} = {82B9BEC0-C9CC-4423-B54F-61E3C4AF53D8} line indicates that the Test2008 project has a declared dependency (set up via the Project Dependencies dialog in VStudio) on the project with the unique identifier 82B9BEC0-C9CC-4423-B54F-61E3C4AF53D8. You should be able to find a project with that same identifier in the same .sln file.
As for why the odd syntax of the line, I have no insider knowledge of the .sln file format. However, based on observation of other ProjectSection extracts in .sln files, I would have to guess that the .sln parser used by Visual Studio historically assumed that the ProjectSection lines will be in a key = value format, with key uniqueness enforced within any given section. I would also guess that the folks who implemented the project dependency functionality decided that, rather than mucking with the parser, it would be simpler to use projectId = projectId for their section lines since the keys are meaningless to them, but they are guaranteed to be unique if only one dependency from project A to project B is otherwise enforced.
It seems that this redundant syntax is one of the quirks required by MSBuild to recognize a project's dependency:
It appears that Visual Studio keeps
the dependencies in two ways, only one
of which is read by MSBuild. I see
that because I still can specify
dependencies in GUI, copy solution to
other machine and build it with VS in
correct order.
-Victor Sergienko
As for why this "superfluous equation statement" is required, it seems that assigning a project's guid to its own guid is a workaround for an issue with MSBuild 4.0 that causes MSBuild to not recognize or respond to certain project dependencies listed in a solution (.sln) file, or to build the dependencies out of order.
The screwed up "{x}={x}" syntax you're asking about is a variation of the standard MSBuild syntax for referencing a project (i.e. the example #Sergio's answer).
Apparently, embedding the dependency declaration in a ProjectSection block in conjunction with a self-named dependency GUID causes MSBuild to change the build order of the depended-upon project, but doesn't actually add another reference to it.
There's a discussion on Microsoft Connect wherein this workaround is discussed. In it, Dan from Microsoft suggests a cleaner workaround for this MSBuild glitch in his 2nd post on the page, and also mentions the fix you're asking about:
However, you can create a project reference that only [affects] the build order without [actually] adding [any runtime] reference. [Modify the dependent .csproj or .vbproj to] look like this; note the metadata element:
<ProjectReference Include="... foo.csproj">
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
[...] That fixes the ordering, as now LibraryProject will wait on CodeGeneratingProject, but its build will otherwise not be affected. I can tidy up by removing the dependency in the solution file as well - removing these lines, which are now unnecessary:
ProjectSection(ProjectDependencies) = postProject
{B79CE0B0-565B-4BC5-8D28-8463A05F0EDC} = {B79CE0B0-565B-4BC5-8D28-8463A05F0EDC}
EndProjectSection
and it still works fine.
From MSDN:
This statement contains the unique
project GUID and the project type
GUID. This information is used by the
environment to find the project file
or files belonging to the solution,
and the VSPackage required for each
project.
The project GUID is passed to
IVsProjectFactory to load the specific
VSPackage related to the project, then
the project is loaded by the
VSPackage. In this case, the VSPackage
that is loaded for this project is
Visual Basic.
For example:
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}")
= "Project1", "Project1.vbproj", "{8CDD8387-B905-44A8-B5D5-07BB50E05BEA}"
EndProject
Lines after ProjectSection(ProjectDependencies) = postProject
specifies dependency list - which project depends on which. (Can be seen in Solution > Properties > Project Dependencies).
If you want to "decrypt" more what is happening inside, take a look at following project:
https://sourceforge.net/p/syncproj/code/HEAD/tree/
Here is .sln parser, you can check Solution.cs, search for "ProjectDependencies".
key is always same as value, this is some sort of file format issue.
My team is creating some standard VS solution templates. We have a well-defined project structure, resources, etc. that we need to use every time we start a new project and this is the perfect solution. The basics work nicely.
However, as well as defining folder structure (etc.) it would be nice to be able to import a number of projects from VSS/TFS. We have a number of shared assemblies that will be used by all projects and it would be awesome to add a reference to these projects when creating a new project via our template. Can anyone tell me if this is possible and, if so, how it can be achieved?
I think there are 3 types of items you might want to templatize (is that a word?).
New Solution
New Project added to a solution
New item added to a project
I'm not sure whether its possible to add existing projects to the solution that is created when a project template is run. http://msdn.microsoft.com/en-us/library/ms185308.aspx shows how to create multiple project templates. You may have to either manually add them to the solution or create a script that modifies the .sln file to do that part.
Adding an assembly reference to either a project or item template is easily doable. The project template is pretty simple since you just need to modify your .vstemplate file for the project template(s). See http://msdn.microsoft.com/en-us/library/ms171405.aspx for reference.
Adding a new assembly reference when you add a new item from a template is a bit harder but can also be done. See http://msdn.microsoft.com/en-us/library/ms185290.aspx for more.
Have fun!