example c# .net msbuild visual-studio-2015

c# summary example



¿Existe una forma simple de hacer que Visual Studio 2015 use una versión de herramientas específica? (4)

Al construir un proyecto o solución utilizando una versión específica de msbuild , puedo seleccionar una cadena de herramientas .net anterior utilizando el /toolsversion o /tv :

"C:/Program Files (x86)/MSBuild/14.0/bin/msbuild" /tv:12.0 amazing.sln

Esto solo funciona para todas las versiones de msbuild , y la versión de csc.exe etc. se ha elegido correctamente en función de lo anterior:

> "C:/Program Files (x86)/MSBuild/14.0/bin/msbuild" /tv:4.0 amazing.sln ... CoreCompile: C:/Windows/Microsoft.NET/Framework/v4.0.30319/Csc.exe ... ... > "C:/Program Files (x86)/MSBuild/14.0/bin/msbuild" /tv:12.0 amazing.sln ... CoreCompile: C:/Program Files (x86)/MSBuild/12.0/bin/Csc.exe ... ...

Si no especifico /tv , entonces, dependiendo de la versión de msbuild que esté utilizando y una serie de variables de entorno, puedo obtener cualquiera de:

  • The ToolsVersion especificado en el elemento de nivel superior en el archivo de proyecto
  • La versión ToolsVersion correspondiente a la versión de msbuild.exe que estoy usando
  • Un valor de msbuild.exe.config
  • Un valor del registro

(Consulte las diferentes versiones de la página de configuración de Overriding ToolsVersion en MSDN ).

Entonces, para tener compilaciones que tengan resultados consistentes en el servidor de compilación y en mi equipo local, uso /tv cuando msbuild.exe (de hecho, esto se aplica en un script de psake , que también asegura que usa la versión correspondiente) de msbuild.exe ).

Sin embargo, no puedo usar el /tv cuando compilo con Visual Studio. En cambio, Visual Studio 2013 y versiones posteriores utilizarán la cadena de herramientas .net que se incluye con esa versión de Visual Studio a menos que :

  • La variable de entorno MSBUILDLEGACYDEFAULTTOOLSVERSION está configurada y ...
  • ... todos los archivos del proyecto tienen el atributo ToolsVersion configurado en la versión que quiero usar.

Esto es tan barroco que no puedo creer que alguien lo esté haciendo realmente. Mis preguntas son así:

  • ¿ Alguien está haciendo lo de MSBUILDLEGACYDEFAULTTOOLSVERSION ?
  • Si no es así, ¿hay alguna otra manera de hacer que Visual Studio use un ToolsVersion específico para usar la versión de Visual Studio que se incluye con ToolsVersion? Algo que podría almacenarse en el control de la versión (por lo tanto, en un proyecto o en algún otro archivo de configuración) sería ideal.

Y por último:

  • ¿Debería importarme? Dado que cada versión sucesiva del compilador de C # debería ser capaz de manejar la entrada de las versiones anteriores, y puedo establecer el marco de trabajo de .net y el nivel de lenguaje C # en el archivo de proyecto, ¿es esto suficiente para garantizar compilaciones repetibles?

(Mi prejuicio es que me debería importar, ya que:

  • Quiero que las compilaciones en el IDE y en el servidor de compilación sean las mismas (por supuesto)
  • Quiero poder usar VS2015 (y futuras versiones) porque es un IDE mejor que las versiones anteriores, pero no quiero estar obligado a usar la nueva herramienta hasta que decida hacerlo.

Tal vez quiero demasiado ...)

Para obtener un ejemplo concreto del problema, consulte mi msbuild-vs-vs2015-toolsversion en github.

Algunos antecedentes: pregunto esto porque recientemente tuvimos un error de compilación de CI cuando uno de mis colegas presentó un código de C # 6.0 que compiló bien con Roslyn en su copia de Visual Studio 2015, pero falló en CI porque eso usa la versión anterior del .net toolchain (habían usado una propiedad automática sin setter, lo cual está bien en Roslyn pero no en versiones anteriores). Vamos a actualizar la versión de CI a Roslyn, pero quería ver si podíamos evitar que sucediera algo así en el futuro.


Lo que se ve en Visual Studio (las herramientas, etc.) y el código detrás de ellos no son lo que se incluye en los datos compilados, sino que son meramente una representación visual / legible. Al compilarlos como una versión anterior de VS, está haciendo el ejecutable de ese versión.

Tenga en cuenta que si compila como una versión .NET anterior, posiblemente perderá funcionalidad, como la funcionalidad asincrónica.


Lo resolví escribiendo una extensión de Visual Studio que establece temporalmente la variable de entorno MSBUILDDEFAULTTOOLSVERSION para la duración de una compilación; el valor que se utilizará se lee de un archivo .toolsversion en el mismo directorio que el archivo .sln . El script psake lee el mismo archivo .toolsversion y pasa el valor al .toolsversion /tv .

El código para la extensión se puede encontrar aquí: https://github.com/guyboltonking/set-toolsversion-extension . Lamentablemente, no estoy trabajando con C ++, o de hecho con Visual Studio, por el momento, por lo que no puedo proporcionar ningún soporte para ello (pero puedo decir que lo usé sin problemas durante varios meses).

Felicitaciones a @efaruk por recordarme la existencia de MSBUILDDEFAULTTOOLSVERSION .

Editar: Gracias a @ mbadawi23, ahora es posible usar la extensión con VS2015 y VS2017.


Nota: Siempre puede crear un archivo msbuild para que su proyecto no pueda usarlo o cambiar su proyecto por sí mismo y usted puede decidir la versión de su herramienta condicionalmente ( https://msdn.microsoft.com/en-us/library/7z253716.aspx ) ( .csproj es también un script estructurado de msbuild con diferentes extensiones y también será compatible con VS).

Saludos...

Editar:

https://msdn.microsoft.com/en-us/library/bb383985.aspx

estableciendo la propiedad $(ProjectToolsVersion) en un proyecto dentro de una solución. Esto le permite crear un proyecto en una solución con una versión del conjunto de herramientas que difiere de la de los otros proyectos.

Entonces, creo que tienes tu respuesta;)


Para forzar una versión específica de C # en Visual Studio 2015, puede acceder a las propiedades del proyecto -> Crear -> Avanzado -> Versión del idioma.

Si configura esto en 5, el compilador se quejará de las características de C # 6 con: La característica ''...'' no está disponible en C # 5. Utilice la versión de idioma 6 o superior.

Alternativly ReSharper también tiene algunas herramientas para esto.