Repository: conan-io/conan

Issue:
[feature] Add Conan package name and version to visual studio generator prop file
<!-- What is your suggestion? Please be as specific as possible! -->

Can we get the feature to add `CONAN_PACKAGE_NAME` and `CONAN_PACKAGE_VERSION` to the visual studio generator prop file? Currently, Conan does support adding package name and version through CMake generator. The feature I am talking about is mentioned [here](https://github.com/conan-io/conan/blob/c923c692fb14dd3ad0a66bab308b4a59f6a037dc/conans/client/generators/cmake_common.py#L71-L73) for CMake generator


- [x] I've read the [CONTRIBUTING guide](https://github.com/conan-io/conan/blob/develop/.github/CONTRIBUTING.md).



Discussion:
Hi, @Hbkhan 

Can you share a little bit more about your need? I see that this `name` and `version` could only be the one from the final consumer (and there is not always a consumer, e.g. `conan install <ref> -g <generator>`)... so depending on how you use Conan, these fields will be empty and they actually take a `None` value.

Maybe with more context and knowing the scenario we can think about a better approach.

Thanks
To keep consistency, we want to have the project version defined in only one place and flow it down from there the various places that need to embed it (cmake configure_file, MSBuild WriteLinesToFile or `<PreprocessorDefinitions>`). The top-level ConanFile seemed like a good place for this to come in from, flowing out through the generator(s) and into the build. We have 

I agree that these can sometimes be `None` if there isn't one set (a conanfile.txt, or conanfile.py without `version` or `set_version(self)`).

We have some CMake projects already doing this with `project(... VERSION ${CONAN_PACKAGE_VERSION}` to bring it in via conanbuildinfo.cmake, but just tried to do similar things with a .NET core project which uses .csproj files instead, and found out that the info was not included by the "visualstudio" generator as it is by the "cmake" one. Which seemed a little surprising, so I told @Hbkhan to ask if there was a reason, or if it could be added.
Yes, this is something useful. Thinking about the next Conan version, we will promote the approach with a toolchain-like file separated from the information of the consumers. In the CMake work it is the `cmake_find_package[_multi]` generator plus the CMake toolchain we've just introduced in `1.26.0` release (it will require some refinement before it is ready for production environment). We are investigating how a toolchain-like file will look like for the `visual studio` generator, and other build_systems, I hope these _custom variables_ can be added to all of them.

In this approach, it totally makes sense to add the `name` and `version` to that toolchain-like file, that file is generated only when there is a root project and it belongs to that root project.


Resolving patch:
diff --git a/conan/tools/microsoft/toolchain.py b/conan/tools/microsoft/toolchain.py
--- a/conan/tools/microsoft/toolchain.py
+++ b/conan/tools/microsoft/toolchain.py
@@ -99,9 +99,17 @@ def _write_main_toolchain(self, config_filename, condition):
                         xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
                     <ImportGroup Label="PropertySheets" >
                     </ImportGroup>
+                    <PropertyGroup Label="ConanPackageInfo">
+                        <ConanPackageName>{}</ConanPackageName>
+                        <ConanPackageVersion>{}</ConanPackageVersion>
+                    </PropertyGroup>
                 </Project>
                 """)
 
+            conan_package_name = self._conanfile.name if self._conanfile.name else ""
+            conan_package_version = self._conanfile.version if self._conanfile.version else ""
+            content = content.format(conan_package_name, conan_package_version)
+
         dom = minidom.parseString(content)
         try:
             import_group = dom.getElementsByTagName('ImportGroup')[0]
diff --git a/conans/client/generators/visualstudio.py b/conans/client/generators/visualstudio.py
--- a/conans/client/generators/visualstudio.py
+++ b/conans/client/generators/visualstudio.py
@@ -19,6 +19,8 @@ class VisualStudioGenerator(Generator):
 </Project>'''
 
     properties_template = '''<PropertyGroup Label="ConanVariables"{condition}>
+    <ConanPackageName>{conan_package_name}</ConanPackageName>
+    <ConanPackageVersion>{conan_package_version}</ConanPackageVersion>
     <ConanCompilerFlags>{compiler_flags}</ConanCompilerFlags>
     <ConanLinkerFlags>{linker_flags}</ConanLinkerFlags>
     <ConanPreprocessorDefinitions>{definitions}</ConanPreprocessorDefinitions>
@@ -79,6 +81,8 @@ def has_valid_ext(lib):
             return ext in VALID_LIB_EXTENSIONS
 
         fields = {
+            'conan_package_name': self.conanfile.name if self.conanfile.name else "",
+            'conan_package_version': self.conanfile.version if self.conanfile.version else "",
             'condition': condition,
             'bin_dirs': "".join("%s;" % p for p in build_info.bin_paths),
             'res_dirs': "".join("%s;" % p for p in build_info.res_paths),


Test patch:
diff --git a/conans/test/functional/generators/visual_studio_test.py b/conans/test/functional/generators/visual_studio_test.py
--- a/conans/test/functional/generators/visual_studio_test.py
+++ b/conans/test/functional/generators/visual_studio_test.py
@@ -114,6 +114,9 @@ def package_info(self):
             from conans import ConanFile
 
             class Consumer(ConanFile):
+                name = "Consumer"
+                version = "0.1"
+
                 requires = "mylib/1.0@us/ch"
                 generators = "visual_studio"
                 """)
@@ -123,6 +126,8 @@ class Consumer(ConanFile):
         client.run("install conanfile_consumer.py")
 
         content = client.load("conanbuildinfo.props")
+        self.assertIn("<ConanPackageName>Consumer</ConanPackageName>", content)
+        self.assertIn("<ConanPackageVersion>0.1</ConanPackageVersion>", content)
         self.assertIn("<ConanLibraries>lib1.lib;</ConanLibraries>", content)
         self.assertIn("<ConanSystemDeps>sys1.lib;</ConanSystemDeps>", content)
         self.assertIn("<AdditionalLibraryDirectories>$(ConanLibraryDirectories)"
diff --git a/conans/test/functional/toolchain/test_basic.py b/conans/test/functional/toolchain/test_basic.py
--- a/conans/test/functional/toolchain/test_basic.py
+++ b/conans/test/functional/toolchain/test_basic.py
@@ -201,3 +201,28 @@ def toolchain(self):
         client.save({"conanfile.py": conanfile})
         client.run("install .")
         self.assertIn("The 'toolchain' attribute or method has been deprecated", client.out)
+
+    def test_toolchain_windows(self):
+        client = TestClient()
+        conanfile = textwrap.dedent("""
+            from conans import ConanFile
+            from conan.tools.microsoft import MSBuildToolchain
+            class Pkg(ConanFile):
+                name = "Pkg"
+                version = "0.1"
+                settings = "os", "compiler", "arch", "build_type"
+                generators = "msbuild"
+
+                def generate(self):
+                    tc = MSBuildToolchain(self)
+                    tc.generate()
+        """)
+
+        client.save({"conanfile.py": conanfile})
+
+        client.run('install . -s os=Windows -s compiler="Visual Studio" -s compiler.version=15'
+                   ' -s compiler.runtime=MD')
+
+        conan_toolchain_props = client.load("conantoolchain.props")
+        self.assertIn("<ConanPackageName>Pkg</ConanPackageName>", conan_toolchain_props)
+        self.assertIn("<ConanPackageVersion>0.1</ConanPackageVersion>", conan_toolchain_props)