Redirecionando todos os projetos em uma solução para .NET 4.5.2

96

Eu tenho uma solução em Visual Studio 2012 com 170 projetos C # nele. Preciso redirecionar todos os projetos do .NET Framework 4.0 para 4.5.2.

Prefiro deixar o Visual Studio lidar com isso acessando as propriedades de cada projeto, alterando a estrutura de destino e permitindo que o Visual Studio faça as alterações necessárias nos arquivos .csproj.

Percebi que essas mudanças incluem a adição de algumas novas tags XML ao .csproj, dependendo de alguns atributos do projeto atual.

Como posso redirecionar em lote todos os 170 projetos C # sem apenas usar uma ferramenta de substituição de texto para substituir o número da versão de destino? Eu quero que o Visual Studio faça todas as modificações e adições de tag necessárias e a substituição sozinha não permitirá que isso aconteça.

Kyle V.
fonte
Não conheço nenhuma maneira de fazer isso automaticamente .. Acho que sua melhor aposta seria um gravador de macro do Windows padrão, que você usa comandos de teclado .. Mas, eu executaria um de cada vez em vez de tentar agrupá-los juntos, uma vez que pode ser difícil identificar quando o VS termina seu trabalho em todos os casos.
Erik Funkenbusch
1
Não, você não deveria estar fazendo isso. Especialmente não 4.5.2, não tem novos tipos úteis e é improvável que seja coberto por futuros pacotes de multi-direcionamento. Assim como 4.0x não era. Faça isso um projeto de cada vez e apenas os que dela necessitam. Aqueles em que você realmente deseja adicionar um novo assembly de referência e modificar o código para usá-los. Se você deseja ignorar este conselho, provavelmente o faz, então use Editar> Localizar e substituir> Substituir em arquivos para substituir o elemento TargetFrameworkVersion nos arquivos * .csproj. Certifique-se de que seu controle de origem seja sólido.
Hans Passant
1
@HansPassant Sua solução de Localizar / Substituir é exatamente o que eu não queria fazer de acordo com minha pergunta. Preciso de uma solução mais robusta.
Kyle V.
@GrantWinney Eu / sei / não funcionará porque já tentei Localizar / Substituir e se você usar esse método, as alterações adicionais .csproj que o Visual Studio teria feito de outra forma não são implementadas.
Kyle V.
1
@GrantWinney a extensão Target Framework Migrator faz exatamente o que eu queria. Se você puder criar uma resposta, marcarei como correta. Obrigado!
Kyle V.

Respostas:

84

A documentação do MSDN " Guia de migração para o .NET Framework 4.5 " e " Como configurar um aplicativo para oferecer suporte ao .NET Framework 4 ou 4.5 " discute apenas a modificação de projetos. Não há detalhes sobre como aplicar alterações em toda a solução de uma vez, nem vi uma função no VS que ofereça suporte a isso.

No entanto, há uma extensão (bem avaliada) chamada Target Framework Migrator disponível na galeria do Visual Studio, que oferece suporte à atualização para 4.5.2 (bem como às versões mais recentes **) e parece que fará exatamente o que você deseja. O código-fonte está disponível no GitHub , se você estiver interessado.

Observe que a falta desse recurso pode ser intencional (e não apenas uma omissão). Estou apenas supondo, mas talvez a MS descubra que apenas os projetos que precisam dos novos Frameworks serão atualizados. FWIW, se você acabar atualizando alguns projetos que são compartilhados com outras soluções, essas soluções podem falhar na construção até que sejam atualizadas também.

Dito isso, se você está em uma pequena loja com apenas uma (ou algumas) soluções e deseja atualizar tudo de uma vez, talvez a ferramenta acima funcione para você.


Não houve nenhum desenvolvimento nisso por anos e, aparentemente, o desenvolvedor não tem planos de passar o bastão para mais ninguém.

Se você não conseguir fazê-lo funcionar com uma versão mais recente do .NET Framework, verifique os PRs e problemas existentes para obter as correções, mas talvez seja necessário aplicá-los você mesmo. Por exemplo, alguém postou uma correção para .NET Framework v 4.7.1 . Esperançosamente, eles irão se fundir, mas eu não prenderia minha respiração.

Se alguém mais está vendo o mesmo erro que Anas (nos comentários), aqui está um problema do GitHub de algumas semanas atrás e outro problema possivelmente relacionado de 2017. Considere marcá-los com um polegar e adicionar mais detalhes se você estiver tendo o mesmo problema .

vivat pisces
fonte
7
A ferramenta "migrador de estrutura de destino" está falhando na última atualização 15.5.5 do VS 2017, "Parâmetro inválido"
Anas Ghanem
1
Trabalhou para mim, hoje, com VS2017 15,7 para Framework 4.7
Tod
Duvido muito que a MS omitisse intencionalmente recursos para benefício dos usuários ... muito mais provavelmente é apenas outra coisa em que eles não pensaram ou não precisaram de suporte ... repasse para a comunidade ..
PJUK
1
@Grant Eu adicionei um comentário ao problema existente. Na verdade, eu fiz o trabalho com uma pesquisa find / sed e substituir nos arquivos de projeto e configuração.
JB. Com a Monica.
2
O desenvolvedor passou o bastão em dezembro de 2019, você pode editar sua (boa) resposta novamente :)
Ludovic Feltz
12

Para uma solução .NET Framework, um simples " Substituir nos arquivos " funcionou para mim:

por exemplo : Do .NET Framework 4.5.2 ao .NET Framework 4.7.2

Nos arquivos package.config , substitua todos

targetFramework="net452" 

para

targetFramework="net472" 

Em arquivos * .csproj , substitua todos

<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion> 

para

<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
webpat
fonte
1
No VS 2019, "substituir tudo" não funciona muito bem. Você tem que usar repetidamente "localizar o próximo". Este é meu último projeto de desenvolvimento baseado na Microsoft. Estou mudando para o MacOSX, onde há consistência e um nível decente de controle de qualidade realizado em seus produtos.
ATL_DEV
1
Alterar o targetFramework em packages.config não reinstala o pacote para aquele framework, então você ainda pode acabar com a versão errada. Você teria que reinstalar o pacote ou pelo menos deletar a pasta de seus pacotes e restaurar a versão correta do pacote. O problema é com aquele modelo de packages.config antigo, sem reinstalar, suas referências de dll para o pacote terão como alvo a dll errada no subdiretório errado do pacote.
Triynko
3
Nossa, acabei voltando a essa pergunta depois das férias e também vi a necessidade de comentar essa mesma resposta, haha. Acrescentarei que os arquivos * .csproj e packages.config não são as únicas coisas que fazem referência à estrutura de destino. Também há referências em arquivos web.config em várias seções. Por exemplo, em system.web, as tags de compilação e httpRuntime têm um atributo targetFramework que precisa ser atualizado. Portanto, este processo manual de 'localizar e substituir' parece uma ideia realmente terrível que pode deixar seus projetos em estado inconsistente e corrompido.
Triynko
9

Como o Target Framework Migrator está quebrado, lancei minha própria pesquisa / substituição (usando git bash, funciona bem no Windows); Basicamente, ele muda o v4.6.x para v4.7.2 , então ele converte de volta os arquivos usando o infame CRLF do DOS:

find . \( -iname '*.csproj' -o -iname '*.vcxproj' -o -iname 'app.config' \) \
 -exec grep -Z -l 'v4\.6\..' \{} \; | xargs -0 sed -i 's/v4\.6\../v4.7.2/'  
find . \( -iname '*.csproj' -o -iname '*.vcxproj' -o -iname 'app.config' \) \
 -exec grep -Z -l 'v4\.7\..' \{} \; | xargs -0 unix2dos
JB. Com a Monica.
fonte
4
Eu encontrei isso, e então Update-Package -ReInstallfaço maravilhas. Obrigado!
askrich
1
Isso funcionou perfeitamente bem para mim. Obrigado por esta solução
Maryam
Para obter uma versão PowerShell, consulte stackoverflow.com/a/2837891/463425
tkerwood
7

Eu mesmo desenvolvi uma ferramenta simples para migrar as versões de framework de destino para uma solução inteira, porque a Target Framework Migrator Extension não oferece suporte ao Visual Studio 2017. Baixe a ferramenta do meu repositório GitHub https://github.com/Xpitfire/TargetFrameworkMigrator

Eu sei que este não é o melhor caminho a seguir, mas funcionou para mim e talvez também ajude outra pessoa.

Marius-Constantin Dinu
fonte
Agora com certeza.
Jay Croghan,
3

O Target Framework Migrator é muito útil. Por padrão, ele vem até a v4.7. No entanto, é fácil adicionar suporte para v4.7.1, v4.7.2 e v4.8.

Encontre o arquivo Frameworks.xml na pasta C: \ Users {nome de usuário} \ AppData \ Local \ Microsoft \ VisualStudio \ e edite adicionando estas versões de framework:

<Framework Id="262152" Name=".NETFramework,Version=v4.8"/>
<Framework Id="262663" Name=".NETFramework,Version=v4.7.2"/>
<Framework Id="262407" Name=".NETFramework,Version=v4.7.1"/>

Depois de reiniciar o Visual Studio, você verá novas versões.

Doğa Benli
fonte
3
Há uma bifurcação com uma versão compatível com VS2019 que já foi atualizada em github.com/Ian1971/TargetFrameworkMigrator/releases
ScottS
Muito obrigado! Esta foi uma solução muito agradável e fácil!
fusão
2
public void ChangeFramework() {

  //Add Reference to envdte (Assemblies\Extensions\envDTE)
  string SolutionFile = @"C:\MyProject\MyProject.sln";
  string ProjectName = "MyProject";

  //------------------------------------------------------------------------
  //Find the Program ID from the registry for VisualStudio.DTE
  //Look it up In Registry: Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Classes
  System.Type oType = System.Type.GetTypeFromProgID("VisualStudio.DTE", true);
  EnvDTE.DTE dte = (EnvDTE.DTE)Activator.CreateInstance(oType, true);

  //------------------------------------------------------------------------
  //Open your Solution
  dte.Solution.Open(SolutionFile);

  //------------------------------------------------------------------------
  //Now In your solution go through what is listed in dte.Solution.Projects 
  //and find the one that match what you want to change target for
  int iItemsCount = dte.Solution.Projects.Count;
  string sCurrent = "";

  for (int i = 1; i <= iItemsCount; i++) {

    sCurrent = dte.Solution.Projects.Item(i).Name;

    if (dte.Solution.Projects.Item(i).Name == ProjectName) {
      //Once you find your project, Change the Framework
      EnvDTE.Project oProject = dte.Solution.Projects.Item(i);
      oProject.Properties.Item("TargetFrameworkMoniker").Value = ".NETFramework,Version = v4.6.2";
    }
  }

  //------------------------------------------------------------------------
  //Close your Solution
  dte.Solution.Close();
}
MaxR
fonte