Tenho quatro projetos na minha solução do Visual Studio (todos direcionados ao .NET 3.5) - para o meu problema, apenas esses dois são importantes:
- MyBaseProject <- esta biblioteca de classes faz referência a um arquivo DLL de terceiros (elmah.dll)
- MyWebProject1 <- este projeto de aplicativo da web tem uma referência ao MyBaseProject
Adicionei a referência elmah.dll ao MyBaseProject no Visual studio 2008 clicando em "Adicionar referência ..." → guia "Procurar" → selecionando a opção "elmah.dll".
As propriedades da referência Elmah são as seguintes:
- Aliases - global
- Copiar local - verdadeiro
- Cultura -
- Descrição - Módulos e manipuladores de log de erros (ELMAH) para ASP.NET
- Tipo de arquivo - montagem
- Caminho - D: \ webs \ otherfolder \ _myPath \ __ tools \ elmah \ Elmah.dll
- Resolvido - Verdadeiro
- Versão em tempo de execução - v2.0.50727
- Versão especificada - false
- Nome forte - falso
- Versão - 1.0.11211.0
No MyWebProject1 , adicionei a referência ao Projeto MyBaseProject por: "Adicionar referência ..." → guia "Projetos" → selecionando o "MyBaseProject". As propriedades desta referência são as mesmas, exceto os seguintes membros:
- Descrição -
- Caminho - D: \ webs \ CMS \ MyBaseProject \ bin \ Debug \ MyBaseProject.dll
- Versão - 1.0.0.0
Se eu executar a compilação no Visual Studio, o arquivo elmah.dll será copiado para o diretório bin do MyWebProject1 , junto com o MyBaseProject.dll!
No entanto, se eu limpar e executar o MSBuild para a solução (via D: \ webs \ CMS> C: \ WINDOWS \ Microsoft.NET \ Framework \ v3.5 \ MSBuild.exe / t: ReBuild / p: Configuration = Debug MyProject.sln ) o elmah.dll está ausente no diretório bin do MyWebProject1 - embora a compilação em si não contenha nenhum aviso ou erro!
Eu já verifiquei que o .csproj do MyBaseProject contém o elemento privado com o valor "true" (que deve ser um alias para " copy local " no Visual Studio):
<Reference Include="Elmah, Version=1.0.11211.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\mypath\__tools\elmah\Elmah.dll</HintPath>
**<Private>true</Private>**
</Reference>
(A marca particular não apareceu no xml do .csproj por padrão, embora o Visual Studio tenha dito "copiar local" como true. Eu mudei "copy local" para false - salvo - e configurei novamente como true - save!)
O que há de errado com o MSBuild? Como obtenho a referência (elmah.dll) copiada para a lixeira do MyWebProject1?
NÃO quero adicionar uma ação de cópia do postbuild ao comando postbuild de cada projeto! (Imagine que muitos projetos dependem do MyBaseProject!)
Respostas:
Não sei por que é diferente ao criar entre o Visual Studio e o MsBuild, mas aqui está o que encontrei quando encontrei esse problema no MsBuild e no Visual Studio.
Explicação
Para um cenário de exemplo, digamos que temos o projeto X, o conjunto A e o conjunto B. O conjunto A faz referência ao conjunto B, portanto, o projeto X inclui uma referência a A e B. Além disso, o projeto X inclui o código que faz referência ao conjunto A (por exemplo, A. AlgumaFunção ()). Agora, você cria um novo projeto Y que faz referência ao projeto X.
Portanto, a cadeia de dependência fica assim: Y => X => A => B
O Visual Studio / MSBuild tenta ser inteligente e somente traz referências ao projeto Y que ele detecta como exigido pelo projeto X; isso é feito para evitar a poluição de referência no projeto Y. O problema é que, como o projeto X não contém realmente nenhum código que use explicitamente o assembly B (por exemplo, B.SomeFunction ()), o VS / MSBuild não detecta que B é necessário por X e, portanto, não o copia no diretório bin do projeto Y; copia apenas os conjuntos X e A.
Solução
Você tem duas opções para resolver esse problema, as quais resultarão na cópia do conjunto B para o diretório bin do projeto Y:
Pessoalmente, prefiro a opção 2 por alguns motivos.
Aqui está um exemplo do "código fictício" que eu normalmente adiciono quando encontro essa situação.
fonte
Type dummyType = typeof(AssemblyA.AnyClass);
Console.WriteLine(dummyType.FullName);
enum
de B e presumi que o enum estava sendo embutido. Adicionei código para usar diretamente um tipo de B e isso não ajudou. Também sempre foi o caso do meu X usar tipos em A que subclasse tipos em B, então não consigo entender como o compilador pensa que B não é exigido por X e pode ser ignorado. Isso é maluco.Eu apenas lido com isso assim. Vá para as propriedades da sua referência e faça o seguinte:
e é isso.
O Visual Studio 2010 não coloca inicialmente:
<private>True</private>
na marca de referência e a configuração "copy local" como false faz com que ela crie a marca. Depois disso, ele será definido como verdadeiro e falso de acordo.fonte
<Private>true</Private>
mas parecia não ter efeito no MSBuild. No final, acabei de adicionar referências ao NuGet a projetos de nível inferior.Have you tried turning it off and on again?
, e funcionou!Se você não estiver usando o assembly diretamente no código, o Visual Studio, enquanto tenta ser útil, detecta que ele não é usado e não o inclui na saída. Não sei por que você está vendo um comportamento diferente entre o Visual Studio e o MSBuild. Você pode tentar definir a saída de construção como diagnóstico para ambos e comparar os resultados, ver onde eles divergem.
Quanto à sua referência elmah.dll, se você não a estiver referenciando diretamente no código, poderá adicioná-lo como um item ao seu projeto e definir a Ação de Construção como
Content
e o Diretório Copiar para Saída comoAlways
.fonte
Dê uma olhada em:
Este tópico do fórum do MSBuild que eu comecei
Você encontrará minha solução temporária / solução alternativa lá!
(O MyBaseProject precisa de algum código que faça referência a algumas classes (o que seja) do elmah.dll para que o elmah.dll seja copiado na lixeira do MyWebProject1!)
fonte
Eu tive o mesmo problema.
Verifique se a versão da estrutura do seu projeto é a mesma da versão da DLL que você colocou em referência.
No meu caso, meu cliente foi compilado usando o "Framework 4 Client" e a DLL estava no "Framework 4".
fonte
O problema que eu estava enfrentando era que eu tinha um projeto que depende de um projeto de biblioteca. Para construir, eu estava seguindo estas etapas:
Isso, é claro, significava que estava faltando os arquivos DLL da minha biblioteca na lixeira e o mais importante no arquivo zip do pacote. Eu achei que isso funciona perfeitamente:
Não tenho ideia do porquê desse trabalho ou por que não funcionou. Mas espero que ajude.
fonte
Eu só tive exatamente o mesmo problema e acabou sendo causado pelo fato de dois projetos na mesma solução referenciarem uma versão diferente da biblioteca de terceiros.
Depois de corrigir todas as referências, tudo funcionou perfeitamente.
fonte
Como Alex Burtsev mencionou em um comentário, qualquer coisa que seja usada apenas em um dicionário de recursos XAML, ou no meu caso, qualquer coisa que seja usada apenas em XAML e não no código por trás, não é considerada 'em uso' pelo MSBuild.
Portanto, simplesmente atualizar uma referência fictícia para uma classe / componente no assembly em algum código por trás foi suficiente para convencer o MSBuild de que o assembly estava realmente em uso.
fonte
Alterar a estrutura de destino do .NET Framework 4 Client Profile para o .NET Framework 4 corrigiu esse problema para mim.
Portanto, no seu exemplo: defina a estrutura de destino no MyWebProject1 como .NET Framework 4
fonte
Usando o esquema de deadlydog,
Y => X => A => B ,
meu problema era que quando construí Y, os conjuntos (A e B, todos os 15) de X não estavam aparecendo na pasta bin de Y.
Resolvi isso removendo a referência X de Y, salve, construa e adicione novamente a referência X (uma referência de projeto) e salve, construa e A e B começaram a aparecer na pasta bin de Y.
fonte
Eu tive o mesmo problema e a dll era uma referência carregada dinamicamente. Para resolver o problema, adicionei um "using" com o namespace da dll. Agora a dll é copiada na pasta de saída.
fonte
Isso requer adicionar um
.targets
arquivo ao seu projeto e configurá-lo para ser incluído na seção de inclusões do projeto.Veja minha resposta aqui para o procedimento.
fonte
Fazer referência a assemblies que não são usados durante a compilação não é a prática correta. Você deve aumentar seu arquivo de construção para copiar os arquivos adicionais. Usando um evento pós-compilação ou atualizando o grupo de propriedades.
Alguns exemplos podem ser encontrados em outro post
fonte
Outro cenário em que isso aparece é se você estiver usando o tipo de projeto "Site" mais antigo no Visual Studio. Para esse tipo de projeto, não é possível referenciar .dlls que estão fora de sua própria estrutura de diretórios (pasta atual e inativa). Portanto, na resposta acima, digamos que sua estrutura de diretórios fique assim:
Onde ProjectX e ProjectY são diretórios pai / filho, e ProjectX faz referência a A.dll, que por sua vez faz referência a B.dll e B.dll está fora da estrutura de diretórios, como em um pacote Nuget na raiz (Pacotes) e, em seguida, A. DLL será incluída, mas B.dll não.
fonte
Eu tive um problema semelhante hoje, e essa certamente não é a resposta para sua pergunta. Mas gostaria de informar a todos e, possivelmente, fornecer uma centelha de insight.
Eu tenho um aplicativo ASP.NET. O processo de compilação está definido para limpar e compilar.
Eu tenho dois scripts de Jenkins CI . Um para produção e outro para preparação. Implantei meu aplicativo no teste e tudo funcionou bem. Implantado na produção e estava faltando um arquivo DLL que foi referenciado. Este arquivo DLL estava apenas na raiz do projeto. Não está em nenhum repositório NuGet. A DLL foi definida como
do not copy
.O script do IC e o aplicativo eram os mesmos entre as duas implantações. Ainda após a limpeza e implantação no ambiente de armazenamento temporário, o arquivo DLL foi substituído no local de implantação do aplicativo ASP.NET (
bin/
). Este não foi o caso do ambiente de produção.Acontece que em uma ramificação de teste, eu adicionei uma etapa ao processo de compilação para copiar esse arquivo DLL para o
bin
diretório. Agora, a parte que demorou um pouco para descobrir. O processo do IC não estava se limpando. A DLL foi deixada no diretório de trabalho e estava sendo empacotada acidentalmente com o arquivo .zip do ASP.NET. O ramo de produção nunca teve o arquivo DLL copiado da mesma maneira e nunca foi implantado acidentalmente.TLDR; Verifique e saiba o que seu servidor de compilação está fazendo.
fonte
Verifique se os dois projetos estão na mesma versão .net também verifique a propriedade local da cópia, mas isso deve ser
true
o padrãofonte
Usando o Visual Studio 2015, adicionando o parâmetro adicional
para a linha de comando msbuild corrigiu o problema.
fonte
Acabei de encontrar um problema muito semelhante. Ao compilar usando o Visual Studio 2010, o arquivo DLL foi incluído no
bin
pasta. Mas ao compilar usando o MSBuild, o arquivo DLL de terceiros não foi incluído.Muito frustrante. A maneira que resolvi foi incluir a referência do NuGet ao pacote no meu projeto da web, mesmo que eu não a esteja usando diretamente lá.
fonte
Incluir todos os arquivos DLL referenciados das suas projectreferences no projeto Website nem sempre é uma boa ideia, especialmente quando você está usando injeção de dependência : seu projeto da Web só deseja adicionar uma referência ao arquivo / projeto DLL da interface, e não a qualquer DLL de implementação concreta Arquivo.
Como se você adicionar uma referência diretamente a um arquivo / projeto DLL de implementação, não poderá impedir que seu desenvolvedor chame um "novo" em classes concretas do arquivo / projeto DLL de implementação, em vez de através da interface. Você também declarou um "código fixo" em seu site para usar a implementação.
fonte