visual studio - Establecer "Copiar local" en False de forma predeterminada?
visual-studio copy-local (6)
¿Puedo configurar la opción predeterminada de "Copiar local" en Visual Studio en False? En la mayoría de las ocasiones, cuando agrego un dll como dependencia de un proyecto, quiero que la propiedad Copy Local se establezca en False. Por defecto, es Verdadero. ¿Hay alguna manera de cambiar el comportamiento predeterminado de Visual Studio? (2008)
Chocando esto porque parece que ahora hay un paquete nuget que permite exactamente esto ...
https://nuget.org/packages/CopyLocalFalse
Todavía no lo he intentado, solo espero que ayude.
Comenzando con msbuild v 15 puede copiar un solo archivo llamado Directory.Build.props en la carpeta raíz que contiene su fuente:
<ItemDefinitionGroup>
<Reference>
<Private>False</Private>
</Reference>
</ItemDefinitionGroup>
¡Nada más que hacer! Esto funciona bien con Visual Studio 2017 y también vNext Build. Puede tener que cerrar Visual Studio y volver a abrir la solución para tomar el efecto de archivo.
Con respecto a la solución publicada por @herzbube, si desea desactivar "Copiar local" para todas (o la mayoría) de las referencias en su archivo .csproj , no necesita establecer <Private>False</Private>
individualmente en cada Reference
, puede simplemente poner lo siguiente directamente en .csproj :
<ItemDefinitionGroup>
<ProjectReference>
<Private>False</Private>
</ProjectReference>
</ItemDefinitionGroup>
Esto no afecta los proyectos a los que se hace referencia con <ProjectReference>
, pero puede hacer lo mismo, en su lugar o bien, para aquellos:
<ItemDefinitionGroup>
<Reference>
<Private>False</Private>
</Reference>
<ProjectReference>
<Private>False</Private>
</ProjectReference>
</ItemDefinitionGroup>
Si desea ambos, puede fusionarlos en un solo grupo:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemDefinitionGroup>
<Reference>
<Private>False</Private>
</Reference>
</ItemDefinitionGroup>
</Project>
Asegúrese de poner estas anulaciones antes de la primera <Reference ...>
o <Reference ...>
<ProjectReference ...>
que desea afectar porque estos bloques solo se aplicarán a las referencias que aparecen debajo de ellos. Entonces, si hay unos pocos que realmente desea copiar localmente, puede simplemente anularlos individualmente (es decir, dentro de la etiqueta individual), esta vez usando True
.
Para casos más avanzados, puede cambiar el valor de anulación entre True y False varias veces en el mismo archivo .csproj. Otra técnica avanzada sería colocar estratégicamente algunas de sus referencias debajo de estos bloques, y otros arriba, para que estos últimos no se vean afectados.
Todo esto debería hacer que el XML en su .csproj sea mucho más limpio y fácil de leer. Pero aún hay más buenas noticias, así que sigue leyendo ...
En cuanto a seleccionar qué proyectos se deben marcar <Private>False</Private>
esto generalmente dependerá de la situación específica, pero hay algo fundamental que todos pueden y deben hacer para empezar. Es un paso tan básico, simple y eficaz que ofrece enormes mejoras de confiabilidad de MSBuild y aceleración en el tiempo de construcción, y con poca desventaja, que cada solución grande que utiliza la salida de C # predeterminada (es decir, local por proyecto) las ubicaciones casi siempre deberían hacer este ajuste:
En todas y cada una de las soluciones de Visual Studio que construye múltiples bibliotecas de clases C # con cualquier cantidad no trivial de interdependencias
<ProjectReference>
, y que culmina en la construcción de una aplicación más (es decir, ejecutables):
Cerca de la parte superior del archivo .csproj para cada biblioteca de clase , inserte el bloque
<ProjectReference>
que se muestra arriba.
RAZÓN: No es necesario que ningún .dll reúna ninguna de las bibliotecas a las que hace referencia en un subdirectorio propio, ya que no se ejecuta ningún ejecutable desde esa ubicación. Tal copia desenfrenada es un trabajo inútil y puede ralentizar innecesariamente tu construcción, posiblemente de manera bastante dramática.Por otro lado, no modifique el .csproj para ninguna de las aplicaciones de su solución.
RAZÓN: Los ejecutables deben tener todas las bibliotecas creadas de forma privada que necesitan en sus respectivos subdirectorios, pero la compilación para cada aplicación sola debe ser responsable de reunir cada dependencia, directamente desde su subdirectorio respectivo, en la subparte de la aplicación. directorio.
Esto funciona perfectamente porque el .csproj para una biblioteca de clases puede hacer referencia a otras bibliotecas de clases, pero el .csproj para un ejecutable generalmente nunca hace referencia a otro ejecutable. Por lo tanto, para cada biblioteca construida localmente, el único .dll en su carpeta bin
será él mismo, mientras que cada aplicación construida localmente contendrá el conjunto completo de bibliotecas construidas localmente a las que hace referencia.
Convenientemente, nada cambia para las bibliotecas a las que se hace referencia que no están compiladas por su solución, ya que generalmente utilizan <Reference>
lugar de <ProjectReference>
, y nosotros no modificamos la etiqueta anterior en absoluto. Pero note la suposición que acabo de mencionar; Si algunos de sus proyectos lo violan, es posible que deba hacer algunos ajustes.
[1.] Las mejoras de confiabilidad podrían estar relacionadas con las colisiones de archivos que pueden producirse al recopilar la misma biblioteca desde múltiples rutas disjuntas en un gráfico de dependencia, especialmente en compilaciones concurrentes.
En realidad, puedes. Necesitas un par de cosas:
- Crea
.targets
archivo.targets
que haga que la función copylocal (etiqueta<Private>
, para ser precisos) sea falsa de forma predeterminada . - Importe el destino en archivos
.csproj
. Puede agregarlo en la última línea, antes de cerrar la etiqueta</Project>
, se verá como<Import Project="../Build/yourtarget.targets" />
.
Ahora, cada proyecto con este objetivo tiene desactivada la función copylocal de forma predeterminada.
El inconveniente es que debe modificar todos y cada uno de los archivos csproj, incluidos los nuevos. Puede solucionar el problema del nuevo proyecto modificando la plantilla del proyecto VS. En lugar de Class.cs
descrito en el artículo del blog, debe modificar Class.vstemplate
(en el mismo archivo zip).
Con ese enfoque, hay un problema más: el camino en sí mismo. Si usa la ruta relativa codificada en los archivos csproj recién generados, pueden estar equivocados (a menos que tenga una estructura de proyecto plana).
Usted puede:
- Haga que VS genere una ruta relativa correcta. No estoy seguro de cómo hacerlo y si eso es posible.
- Ignore y cambie la ruta de forma manual para cada nuevo csproj (dependiendo de la cantidad de proyectos nuevos que tenga, aunque no sea ideal, que pueda ser tolerable).
- Use la variable de entorno en lugar de la ruta relativa. En ese caso, cada desarrollador necesitará el mismo conjunto de variables.
Debe haber una mejor solución para eso, pero aún no lo ha encontrado.
No usamos archivos .targets (como se sugiere en la respuesta por ya23), por lo que solo editamos el archivo de proyecto .csproj
manualmente en un editor de texto y agregamos el elemento <Private>
a la referencia, como este:
<Reference Include="[...]">
<Private>False</Private>
[...]
</Reference>
El valor del elemento <Private>
coincide con el valor de la propiedad "Copiar local". Por ejemplo, si <Private>
está configurado como Falso, entonces "Copiar local" también es falso.
No: Visual Studio usa un conjunto interno de reglas para determinar a qué configurar Copy Local.
Desde MSDN :
- Si la referencia es otro proyecto, llamado referencia de proyecto a proyecto, entonces el valor es verdadero .
- Si el ensamblado se encuentra en el caché de ensamblaje global, el valor es falso .
- Como un caso especial, el valor de la referencia de mscorlib.dll es falso .
- Si el ensamblado se encuentra en la carpeta Framework SDK, el valor es falso .
- De lo contrario, el valor es verdadero .