Mam cztery projekty w moim rozwiązaniu Visual Studio (wszyscy celują w .NET 3.5) - dla mojego problemu tylko te dwa są ważne:
- MyBaseProject <- ta biblioteka klas odwołuje się do pliku DLL innej firmy (elmah.dll)
- MyWebProject1 <- ten projekt aplikacji internetowej ma odniesienie do MyBaseProject
Dodałem odniesienie elmah.dll do MyBaseProject w Visual studio 2008, klikając „Dodaj odniesienie ...” → karta „Przeglądaj” → wybierając „elmah.dll”.
Właściwości odwołania Elmah są następujące:
- Aliasy - globalne
- Kopiuj lokalnie - prawda
- Kultura -
- Opis - moduły rejestrowania błędów i moduły obsługi (ELMAH) dla ASP.NET
- Typ pliku - zespół
- Ścieżka - D: \ webs \ otherfolder \ _myPath \ __ tools \ elmah \ Elmah.dll
- Rozwiązane - prawda
- Wersja środowiska wykonawczego - v2.0.50727
- Określona wersja - fałsz
- Silne imię - fałszywe
- Wersja - 1.0.11211.0
W MyWebProject1 dodałem odwołanie do projektu MyBaseProject poprzez: „Dodaj odniesienie ...” → zakładka „Projekty” → wybierając „MyBaseProject”. Właściwości tego odwołania są takie same, z wyjątkiem następujących elementów:
- Opis -
- Ścieżka - D: \ webs \ CMS \ MyBaseProject \ bin \ Debug \ MyBaseProject.dll
- Wersja - 1.0.0.0
Jeśli uruchomię kompilację w Visual Studio, plik elmah.dll zostanie skopiowany do katalogu bin mojego MyWebProject1 wraz z MyBaseProject.dll!
Jeśli jednak wyczyszczę i uruchomię MSBuild dla rozwiązania (przez D: \ webs \ CMS> C: \ WINDOWS \ Microsoft.NET \ Framework \ v3.5 \ MSBuild.exe / t: ReBuild / p: Configuration = Debug MyProject.sln ) elmah.dll brakuje w katalogu bin MyWebProject1 - chociaż sama kompilacja nie zawiera ostrzeżeń ani błędów!
Już upewniłem się, że .csproj MyBaseProject zawiera element prywatny o wartości „true” (powinien to być alias „ kopiuj lokalnie ” w 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>
(Tag prywatny nie pojawił się domyślnie w pliku xml .csproj, chociaż Visual Studio powiedział „kopiuj lokalnie” true. Zmieniłem „kopiuj lokalnie” na false - zapisałem - i ustawiłem ponownie z powrotem na true - zapisz!)
Co jest nie tak z MSBuild? Jak uzyskać odniesienie (elmah.dll) skopiowane do kosza MyWebProject1?
NIE chcę dodawać operacji kopiowania po zakończeniu budowy do polecenia po zakończeniu każdego projektu! (Wyobraź sobie, że wiele projektów zależy od MyBaseProject!)
Odpowiedzi:
Nie jestem pewien, dlaczego różni się to podczas budowania między Visual Studio i MsBuild, ale oto, co znalazłem, gdy napotkałem ten problem w MsBuild i Visual Studio.
Wyjaśnienie
W przykładowym scenariuszu powiedzmy, że mamy projekt X, zespół A i zespół B. Zespół A odwołuje się do zespołu B, więc projekt X zawiera odniesienie zarówno do A, jak i B. Ponadto projekt X zawiera kod, który odwołuje się do zespołu A (np. A. SomeFunction ()). Teraz tworzysz nowy projekt Y, który odwołuje się do projektu X.
Tak więc łańcuch zależności wygląda następująco: Y => X => A => B
Visual Studio / MSBuild stara się być inteligentny i przenosić tylko referencje do projektu Y, które wykrywa jako wymagane przez projekt X; robi to, aby uniknąć zanieczyszczenia referencyjnego w projekcie Y. Problem polega na tym, że ponieważ projekt X tak naprawdę nie zawiera kodu, który jawnie używa zestawu B (np. B.SomeFunction ()), VS / MSBuild nie wykrywa, że B jest wymagane przez X, a zatem nie kopiuje go do katalogu bin projektu Y; kopiuje tylko zespoły X i A.
Rozwiązanie
Masz dwie opcje rozwiązania tego problemu, z których każda spowoduje skopiowanie zestawu B do katalogu bin projektu Y:
Osobiście wolę opcję 2 z kilku powodów.
Oto próbka „fałszywego kodu”, który zazwyczaj dodaje się, gdy napotykam tę sytuację.
źródło
Type dummyType = typeof(AssemblyA.AnyClass);
Console.WriteLine(dummyType.FullName);
enum
z B i założyłem, że wyliczanie jest wprowadzane. Dodałem kod, aby bezpośrednio używać typu z B i to nie pomogło. Zawsze było tak również, że mój X używa typów w podklasie typu B, więc nie mogę zrozumieć, w jaki sposób kompilator uważa, że B nie jest wymagany przez X i można go zignorować. To jest szaleństwo.Po prostu sobie z tym radzę. Przejdź do właściwości swojego odwołania i zrób to:
i to wszystko.
Program Visual Studio 2010 początkowo nie umieścił:
<private>True</private>
w znaczniku referencyjnym, a ustawienie „kopiuj lokalnie” na false powoduje utworzenie znacznika. Następnie ustawi odpowiednio wartość true i false.źródło
<Private>true</Private>
ale powiedziałem, że nie miało to wpływu na MSBuild. Na koniec dodałem właśnie odniesienia NuGet do projektów niskiego poziomu.Have you tried turning it off and on again?
i działało!Jeśli nie używasz zestawu bezpośrednio w kodzie, program Visual Studio, próbując być pomocnym, wykrywa, że nie jest używany i nie dołącza go do wyniku. Nie jestem pewien, dlaczego widzisz różne zachowania między Visual Studio i MSBuild. Możesz spróbować ustawić wynik kompilacji na diagnostyczny dla obu i porównać wyniki, aby zobaczyć, gdzie się różni.
Jeśli chodzi o odniesienie do elmah.dll, jeśli nie odwołujesz się bezpośrednio do niego w kodzie, możesz dodać go jako element do projektu i ustawić Działanie kompilacji na
Content
oraz Kopiuj do katalogu wyjściowego naAlways
.źródło
Spojrzeć na:
Ten wątek forum MSBuild rozpocząłem
Znajdziesz tam moje tymczasowe rozwiązanie / obejście!
(MyBaseProject potrzebuje kodu odwołującego się do niektórych klas (cokolwiek) z pliku elmah.dll, ponieważ plik elmah.dll jest kopiowany do kosza MyWebProject1!)
źródło
Miałem ten sam problem.
Sprawdź, czy wersja ramowa projektu jest taka sama jak wersja ramowa biblioteki dll, do której się odwołujesz.
W moim przypadku mój klient został skompilowany za pomocą „Framework 4 Client”, a DLL znajdował się w „Framework 4”.
źródło
Problem, z którym się spotkałem, to posiadanie projektu zależnego od projektu bibliotecznego. Aby zbudować, wykonałem następujące kroki:
To oczywiście oznaczało, że brakowało mi plików DLL mojej biblioteki w bin, a co najważniejsze w pakiecie zip. Uważam, że działa to idealnie:
Nie mam pojęcia, dlaczego to działa ani dlaczego w ogóle nie działa. Ale nadzieja to pomaga.
źródło
Właśnie miałem ten sam problem i okazało się, że jest to spowodowane tym, że 2 projekty w tym samym rozwiązaniu odwoływały się do innej wersji biblioteki innej firmy.
Po poprawieniu wszystkich odniesień wszystko działało idealnie.
źródło
Jak wspomniał Alex Burtsev w komentarzu, wszystko, co jest używane tylko w słowniku zasobów XAML, lub w moim przypadku, wszystko, co jest używane tylko w XAML, a nie w kodzie, nie jest uważane za „używane” przez MSBuild.
Tak więc po prostu odświeżenie fałszywego odwołania do klasy / komponentu w zestawie w jakimś kodzie było wystarczające, aby przekonać MSBuild, że zestaw faktycznie jest w użyciu.
źródło
Zmiana docelowej struktury z .NET Framework 4 Client Profile na .NET Framework 4 naprawiła dla mnie ten problem.
W twoim przykładzie: ustaw docelową platformę MyWebProject1 na .NET Framework 4
źródło
Korzystając ze schematu Deadlydog,
Y => X => A => B ,
mój problem polegał na tym, że kiedy zbudowałem Y, zespoły (A i B, wszystkie 15 z nich) z X nie pojawiały się w folderze bin Y.
Rozwiązałem problem, usuwając odniesienie X z Y, zapisz, buduj, a następnie ponownie dodaj odniesienie X (odwołanie do projektu), a następnie zapisz, buduj, a A i B zaczęły pojawiać się w folderze bin Y.
źródło
Miałem ten sam problem i dll był dynamicznie ładowanym odwołaniem. Aby rozwiązać problem, dodałem „używanie” z przestrzenią nazw dll. Teraz dll jest kopiowany do folderu wyjściowego.
źródło
Wymaga to dodania
.targets
pliku do projektu i ustawienia włączenia go do sekcji zawierającej projekt.Zobacz moją odpowiedź tutaj dla procedury.
źródło
Odwoływanie się do zestawów, które nie są używane podczas kompilacji, nie jest prawidłową praktyką. Powinieneś rozszerzyć swój plik kompilacji, aby skopiował dodatkowe pliki. Albo za pomocą zdarzenia po kompilacji lub poprzez aktualizację grupy właściwości.
Niektóre przykłady można znaleźć w innym poście
źródło
Innym scenariuszem, w którym się to pokazuje, jest użycie starszego typu projektu „Witryna sieci Web” w programie Visual Studio. W przypadku tego typu projektu nie można odwoływać się do plików DLL, które znajdują się poza własną strukturą katalogów (bieżący folder i dół). W powyższej odpowiedzi powiedzmy, że twoja struktura katalogów wygląda następująco:
Gdzie ProjectX i ProjectY są katalogami nadrzędnymi / podrzędnymi, a ProjectX odwołuje się do A.dll, który z kolei odwołuje się do B.dll, a B.dll znajduje się poza strukturą katalogów, na przykład w pakiecie Nuget w katalogu głównym (Pakiety), a następnie A. biblioteka DLL zostanie dołączona, ale B.dll nie.
źródło
Miałem dzisiaj podobny problem i to z pewnością nie jest odpowiedź na twoje pytanie. Ale chciałbym poinformować wszystkich i być może dostarczyć iskry wglądu.
Mam aplikację ASP.NET. Proces kompilacji jest ustawiony na czyszczenie, a następnie kompilację.
Mam dwa skrypty Jenkins CI . Jeden do produkcji, a drugi do inscenizacji. Wdrożyłem moją aplikację na platformie i wszystko działało dobrze. Wdrożono do produkcji i brakowało pliku DLL, do którego się odwołano. Ten plik DLL znajdował się w katalogu głównym projektu. Nie ma w żadnym repozytorium NuGet. Biblioteka DLL została ustawiona na
do not copy
.Skrypt CI i aplikacja były takie same między dwoma wdrożeniami. Nadal po wyczyszczeniu i wdrożeniu w środowisku pomostowym plik DLL został zastąpiony w miejscu wdrożenia aplikacji ASP.NET (
bin/
). Nie było tak w przypadku środowiska produkcyjnego.Okazuje się, że w gałęzi testowej dodałem krok do procesu kompilacji, aby skopiować ten plik DLL do
bin
katalogu. Teraz część, która zajęła trochę czasu, aby się zorientować. Proces CI nie czyścił się sam. Biblioteka DLL została pozostawiona w katalogu roboczym i została przypadkowo spakowana z plikiem .zip ASP.NET. Oddział produkcyjny nigdy nie kopiował pliku DLL w ten sam sposób i nigdy nie wdrożył go przypadkowo.TLDR; Sprawdź i upewnij się, że wiesz, co robi Twój serwer kompilacji.
źródło
Upewnij się, że oba projekty są w tej samej wersji .net, sprawdź także kopiuj lokalną właściwość, ale powinno to być
true
ustawienie domyślneźródło
Za pomocą programu Visual Studio 2015 dodając dodatkowy parametr
w wierszu polecenia msbuild naprawiono problem.
źródło
Właśnie natrafiłem na bardzo podobny problem. Podczas kompilacji przy użyciu programu Visual Studio 2010 plik DLL został dołączony do
bin
folderu. Ale podczas kompilacji przy użyciu MSBuild plik DLL innej firmy nie został uwzględniony.Bardzo frustrujące. Sposób, w jaki to rozwiązałem, polegał na dołączeniu odwołania do pakietu NuGet do mojego projektu internetowego, mimo że nie używam go bezpośrednio tam.
źródło
Uwzględnienie wszystkich plików DLL z referencji projektu w projekcie witryny nie zawsze jest dobrym pomysłem, szczególnie gdy używasz wstrzykiwania zależności : twój projekt sieciowy chce po prostu dodać odniesienie do pliku / projektu biblioteki DLL, a nie żadnej konkretnej biblioteki DLL implementacji plik.
Ponieważ jeśli dodasz odwołanie bezpośrednio do pliku / projektu DLL implementacji, nie możesz zapobiec wywoływaniu przez programistę „nowej” konkretnej klasy pliku / projektu DLL implementacji zamiast przez interfejs. Podałeś również „hardcode” na swojej stronie, aby skorzystać z implementacji.
źródło