Warunkowo użyj odniesienia 32/64 bitowego podczas budowania w Visual Studio
Mam projekt, który buduje się w 32/64-bitowych i ma odpowiednie zależności 32/64-bitowe. Chcę mieć możliwość przełączania konfiguracji i poprawnego odniesienia, ale nie wiem, jak powiedzieć Visual Studio, aby używało zależności odpowiedniej dla architektury.
Może robię to źle, ale chcę mieć możliwość przełączania się między x86 i x64 w rozwijanym menu konfiguracyjnym i mieć odnośną bibliotekę DLL odpowiednią bitness.
6 answers
Oto, co zrobiłem w poprzednim projekcie, który będzie wymagał ręcznej edycji .plik(y) csproj. Potrzebujesz również oddzielnych katalogów dla różnych binariów, najlepiej rodzeństwa siebie nawzajem i o tej samej nazwie, co platforma, na którą kierujesz.
Po dodaniu referencji jednej platformy do projektu, otwórz .csproj w edytorze tekstu. Przed pierwszym elementem {[2] } w elemencie <Project>
Dodaj następujący kod, który pomoże określić, która platforma biegasz (i budujesz) dalej.
<!-- Properties group for Determining 64bit Architecture -->
<PropertyGroup>
<CurrentPlatform>x86</CurrentPlatform>
<CurrentPlatform Condition="'$(PROCESSOR_ARCHITECTURE)'=='AMD64' or '$(PROCESSOR_ARCHITEW6432)'=='AMD64'">AMD64</CurrentPlatform>
</PropertyGroup>
Następnie, w odniesieniu do konkretnych odniesień do platformy, wprowadzasz następujące zmiany:
<ItemGroup>
<Reference Include="Leadtools, Version=16.5.0.0, Culture=neutral, PublicKeyToken=9cf889f53ea9b907, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\Lib\Leadtools\$(CurrentPlatform)\Leadtools.dll</HintPath>
</Reference>
<Reference Include="Leadtools.Codecs, Version=16.5.0.0, Culture=neutral, PublicKeyToken=9cf889f53ea9b907, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\Lib\Leadtools\$(CurrentPlatform)\Leadtools.Codecs.dll</HintPath>
</Reference>
<Reference Include="Leadtools.ImageProcessing.Core, Version=16.5.0.0, Culture=neutral, PublicKeyToken=9cf889f53ea9b907, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\Lib\Leadtools\$(CurrentPlatform)\Leadtools.ImageProcessing.Core.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data.Entity" />
<!-- Other project references -->
</ItemGroup>
Zwróć uwagę na użycie właściwości $(CurrentPlatform)
, którą zdefiniowaliśmy powyżej. Możesz zamiast tego użyć warunków, dla których zestawów zawierać dla której platformy. Możesz też:
- Zastąp
$(PROCESSOR_ARCHITEW6432)
i$(PROCESSOR_ARCHITECTURE)
$(Platform)
, aby uwzględnić tylko docelową platformę projektów - zmienić logikę określania platformy w kolejności aby być odpowiednim do aktualnej maszyny, aby nie budować / odwoływać się do 64-bitowego binarnego do wykonania na platformie 32-bitowej.
Miałem to napisane pierwotnie dla wewnętrznej Wiki w pracy, jednak zmodyfikowałem go i opublikowałem pełny proces na moim blogu , jeśli jesteś zainteresowany szczegółowymi instrukcjami krok po kroku.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-28 15:20:41
AFAIK, jeśli twój projekt wymaga referencji, które są specyficzne dla 32-bitowych lub 64-bitowych (np. COM-interop assemblies), a nie jesteś zainteresowany ręczną edycją .plik csproj, następnie będziesz musiał utworzyć oddzielne projekty 32-bitowe i 64-bitowe.
Powinienem zauważyć, że poniższe rozwiązanie nie jest testowane, ale powinno zadziałać. Jeśli chcesz ręcznie edytować .plik csproj, a następnie powinien być w stanie osiągnąć pożądany wynik z jednego projektu. The .plik csproj to tylko MSBuild skrypt, więc dla pełnego odniesienia, spójrz tutaj . Po otwarciu .plik csproj w edytorze odszukaj elementy <Reference>
. Powinieneś być w stanie podzielić te elementy na 3 różne grupy elementów : odniesienia, które nie są specyficzne dla platformy, odniesienia specyficzne dla x86 i odniesienia specyficzne dla x64.
Oto przykład, który zakłada, że projekt jest skonfigurowany z platformami docelowymi o nazwie " x86 "i"x64"
<!-- this group contains references that are not platform specific -->
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<!-- any other references that aren't platform specific -->
</ItemGroup>
<!-- x86 specific references -->
<ItemGroup Condition=" '$(Platform)' == 'x86' ">
<Reference Include="MyComAssembly.Interop">
<HintPath>..\..\lib\x86\MyComAssembly.Interop.dll</HintPath>
</Reference>
<!-- any additional x86 specific references -->
</ItemGroup>
<!-- x64 specific referneces -->
<ItemGroup Condition=" '$(Platform)' == 'x64' ">
<Reference Include="MyComAssembly.Interop">
<HintPath>..\..\lib\x64\MyComAssembly.Interop.dll</HintPath>
</Reference>
<!-- any additional x64 specific references -->
</ItemGroup>
Teraz, gdy ustawisz swój projekt / rozwiązanie build Konfiguracja aby kierować się na platformę x86 lub x64, powinna zawierać odpowiednie odniesienia w każdym przypadku. Oczywiście trzeba będzie się bawić elementami <Reference>
. Możesz nawet skonfigurować atrapy projektów, w których dodajesz odwołania do x86 i x64, a następnie po prostu skopiuj niezbędne elementy <Reference>
z tych atrap plików projektu do" prawdziwego " pliku projektu.
Edit 1
Oto link do wspólnych elementów projektu MSBuild, które przypadkowo pominąłem z oryginalnego postu: http://msdn.microsoft.com/en-us/library/bb629388.aspx
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-27 22:32:37
Możesz użyć warunku ItemGroup dla odniesień dll w pliku projektu.
Spowoduje to, że program visual studio ponownie sprawdzi stan i odniesienia za każdym razem, gdy zmienisz aktywną konfigurację.
Wystarczy dodać warunek dla każdej konfiguracji.
Przykład:
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<Reference Include="DLLName">
<HintPath>..\DLLName.dll</HintPath>
</Reference>
<ProjectReference Include="..\MyOtherProject.vcxproj">
<Project>{AAAAAA-000000-BBBB-CCCC-TTTTTTTTTT}</Project>
<Name>MyOtherProject</Name>
</ProjectReference>
</ItemGroup>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-11 14:22:07
Odwołuję się do bibliotek DLL x86, znajdujących się np. w \component \ v3_NET4, w moim projekcie. Specyficzne biblioteki DLL dla x86 / x64 znajdują się w podfolderach o nazwach " x86 "i" x64 " lub "x64".
Następnie używam wstępnie zbudowanego skryptu, który kopiuje odpowiednie biblioteki DLL (x86/x64) do wskazanego folderu, bazując na $(PlatformName).
xcopy /s /e /y "$(SolutionDir)..\component\v3_NET4\$(PlatformName)\*" "$(SolutionDir)..\component\v3_NET4"
Mi pasuje.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-14 10:09:50
Spotkałem się z tym samym problemem i spędziłem sporo czasu szukając przyzwoitego rozwiązania. Większość osób oferuje ręczną edycję plików rozwiązań Visual Studio, co jest dość żmudne,podatne na błędy i mylące podczas eksploracji tych edytowanych plików w interfejsie graficznym Visual Studio. Kiedy już się poddałem, rozwiązanie pojawiło się samo. Jest to bardzo podobne do tego, co Micke zaleca w swojej odpowiedzi powyżej.
W account managerze jak zwykle stworzyłem dwa oddzielne cele kompilacji dla platform x86 i x64. Następnie dodałem do mojego projektu odniesienie do montażu x86. W tej kwestii wierzyłem, że projekt jest skonfigurowany tylko dla x86 build i nigdy nie będzie budowany dla konfiguracji x64, chyba że dokonam ręcznej edycji go zgodnie z sugestią Hugo powyżej.
Po chwili w końcu zapomniałem o ograniczeniu i przypadkowo zacząłem budować x64. Oczywiście budowa nie powiodła się. Ale ważny był komunikat o błędzie, który otrzymałem. Komunikat o błędzie informował, że zespół o nazwie dokładnie tak, jak mój wymieniony zespół x86 jest brak w folderze przeznaczonym jako cel kompilacji x64 dla mojego rozwiązania.
Zauwaĺźywszy to, rÄ ™ cznie skopiowaĺ ' em odpowiedni montaĹź x64 do tego katalogu. Chwała! Mój x64 build cudownie powiódł się z prawidłowym montażem znalezionym i połączonym pośrednio. To było kwestia minut, aby zmodyfikować moje rozwiązanie, aby ustawić docelowy katalog kompilacji x64 w tym folderze. Po tych krokach rozwiązanie buduje się automatycznie zarówno dla x86, jak i x64 bez ręcznej edycji plików MSBuild.
To suma:
Tworzenie celów x86 i x64 w jednym projekcie]}
- Dodaj wszystkie odpowiednie odniesienia do projektu do zestawów x86
- Ustaw jeden wspólny katalog docelowy dla wszystkich zestawów x64
- jeśli masz gotowe zestawy x64, po prostu skopiuj je raz do katalogu docelowego x64
Po wykonaniu tych kroków Twoje rozwiązanie zostanie poprawnie zbudowane zarówno dla konfiguracji x86, jak i x64.
To mi pomogło na Projekt Visual Studio 2010. NET 4.0 C#. Ewidentnie jest to rodzaj nieudokumentowanego wewnętrznego zachowania Visual Studio, które może ulec zmianie w wersjach z 2012, 2013 i 2015 roku. Jeśli ktoś będzie próbował na innych wersjach, Proszę podzielić się swoimi doświadczeniami.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-04 08:33:46
Jeden. Net build z zależnościami x86/x64
Podczas gdy wszystkie inne odpowiedzi dają ci rozwiązanie do tworzenia różnych kompilacji w zależności od platformy, daję ci opcję posiadania tylko konfiguracji "AnyCPU" i tworzenia kompilacji, która działa z bibliotekami DLL x86 i x64.
Musisz napisać do tego jakiś kod hydrauliczny. Nie mogłem pracować z aplikacją.config. Jeśli ktoś inny zna sposób, aby rozwiązać go za pomocą aplikacji.config naprawdę chciałbym wiedzieć.Rozdzielczość poprawne x86/x64-DLL w czasie wykonywania
Kroki:
- użyj AnyCPU w csproj
- zdecyduj, czy odwołujesz się tylko do bibliotek DLL x86 lub x64 w swoich csprojs. Dostosuj ustawienia UnitTests do wybranych ustawień architektury. Jest to ważne przy debugowaniu / uruchamianiu testów wewnątrz VisualStudio.
- On Reference-Properties set Copy Local & Wersja specjalna do false
- pozbądź się ostrzeżeń o architekturze dodając To linia do pierwszej PropertyGroup we wszystkich plikach csproj, do których odwołujesz się do x86/x64:
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
-
Dodaj ten skrypt postbuild do swojego projektu startowego, użyj i zmodyfikuj ścieżki tego skryptu sp, który kopiuje wszystkie biblioteki DLL x86/x64 w odpowiednich podfolderach twojego build bin\x86 \ bin \ x64 \
xcopy /E /H /R /Y /I /D $(SolutionDir)\YourPathToX86Dlls $(TargetDir)\x86 xcopy /E /H /R /Y /I /D $(SolutionDir)\YourPathToX64Dlls $(TargetDir)\x64
-- > kiedy uruchomisz aplikację teraz, otrzymasz wyjątek że Zgromadzenie nie może zostać znalezione.
-
Zarejestruj AssemblyResolve zdarzenie bezpośrednio na początku punktu wejścia aplikacji
AppDomain.CurrentDomain.AssemblyResolve += TryResolveArchitectureDependency;
Z tą metodą:
/// <summary> /// Event Handler for AppDomain.CurrentDomain.AssemblyResolve /// </summary> /// <param name="sender">The app domain</param> /// <param name="resolveEventArgs">The resolve event args</param> /// <returns>The architecture dependent assembly</returns> public static Assembly TryResolveArchitectureDependency(object sender, ResolveEventArgs resolveEventArgs) { var dllName = resolveEventArgs.Name.Substring(0, resolveEventArgs.Name.IndexOf(",")); var anyCpuAssemblyPath = $".\\{dllName}.dll"; var architectureName = System.Environment.Is64BitProcess ? "x64" : "x86"; var assemblyPath = $".\\{architectureName}\\{dllName}.dll"; if (File.Exists(assemblyPath)) { return Assembly.LoadFrom(assemblyPath); } return null; }
- jeśli masz testy jednostkowe, Utwórz klasę testową z metodą, która ma AssemblyInitializeAttribute, a także zarejestruj powyższą funkcję TryResolveArchitectureDependency-Handler. (Czasami nie będzie to wykonywane, jeśli uruchomisz pojedyncze testy w visual studio, odwołania będą rozwiązywane nie z UnitTest bin. Dlatego decyzja w Kroku 2 jest ważne.)
Korzyści:
- jedna instalacja / Budowa dla obu platform
Wady: - Brak błędów podczas kompilacji, gdy biblioteki DLL x86/x64 nie pasują. - Nadal należy uruchomić test w obu trybach!
Opcjonalnie Utwórz drugi plik wykonywalny, który jest wyłączny dla architektury x64 z Corflags.exe w skrypcie postbuild
Inne warianty do wypróbowania: - Nie będziesz potrzebował obsługi zdarzenia AssemblyResolve, jeśli zapewnisz, że biblioteki DLL otrzymają skopiowane w folderze binarnym na początku (Evaluate Process architecture - > przenieś odpowiednie biblioteki DLL z x64/x86 do folderu bin i z powrotem.) - W Instalatorze Oceń architekturę i usuń pliki binarne dla niewłaściwej architektury i przenieś właściwe do folderu bin.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-03 09:54:13