Spis treści:

Kategoria:PowerShellWindows


Oracle 32-bit i 64-bit na jednym serwerze

Dwie wersje bibliotek - x86 i x64 - na jednym komputerze

Źródło problemu

Przejście procesorów z architektury 32-biowej na 64-botową niesie za sobą szereg konsekwencji. To co w głównej mierze decyduje o braku możliwości pogodzenia bibliotek 32-bitowych i 64-bitowych to rozmiar wskaźnika i możliwości adresowania poszczególnych obszarów pamięci. 32-bitowy wskaźnik nie jest w stanie zaadresować 64-bitowej przestrzeni adresowej, 64-bitowy wskaźnik może wskazywać adres niemożliwy do osiągnięcia przez wskaźnik 32-bitowy.

Tryby kompilacji .NET

Kompilator .NET pozwala wygenerować pliki wykonywalne (ang. PE, zob. format Portable Executable) oraz biblioteki w trzech podstawowych trybach:

  • x86 - pliki z kodem wykonywalnym przeznaczonym dla architektury 32-bitowej,
  • x64 - pliki z kodem wykonywalnym przeznaczonym dla architektury 64-bitowej,
  • AnyCPU - pliki z kodem zarządzanym, niezależnym od architektury, język pośredni (ang. CIL, Common Intermediate Language).

O ile dwa pierwsze tryby mają jasno określoną strukturę, o tyle ten ostatni tryb w przypadku wywołania funkcji natywnych (Win API, COM, itp.) musi samodzielnie obsłużyć różnice w adresacji.

Kombinacje bitowości i ich zgodność

Platforma .NET podczas wczytywania bibliotek zależnych sprawdza, czy istnieje zgodność wersji w następujący sposób:

System 32-bitowy

  • Any CPU uruchamiane jest jako proces 32-bitowy, może wczytywać zależności Any CPU oraz 32-bitowe. Generuje wyjątek BadImageFormatException podczas wczytywania zależności 64-bitowej.
  • x86 uruchamiane jest jako proces 32-bitowy, może wczytywać zależności Any CPU oraz 32-bitowe. Generuje wyjątek BadImageFormatException podczas wczytywania zależności 64-bitowej.
  • x64 Zawsze generuje wyjątek BadImageFormatException.

System 64-bitowy

  • Any CPU uruchamiane jest jako proces 64-bitowy, może wczytywać zależności Any CPU oraz 64-bitowe. Generuje wyjątek BadImageFormatException podczas wczytywania zależności 32-bitowej.
  • x86 uruchamiane jest jako proces 32-bitowy, może wczytywać zależności Any CPU oraz 32-bitowe. Generuje wyjątek BadImageFormatException podczas wczytywania zależności 64-bitowej.
  • x64 uruchamiane jest jako proces 64-bitowy, może wczytywać zależności Any CPU oraz 64-bitowe. Generuje wyjątek BadImageFormatException podczas wczytywania zależności 32-bitowej.

Zależność poza trybem zarządzanym z niezgodnośią bitów

O ile aplikacja w całości pisana w trybie zarządzanym (platforma .NET) działa bezproblemowo w trybie ANY CPU w obu architekturach sprzętowych, o tyle korzystanie z komponentów zewnętrznych wymaga ostrożności. Np. w przypadku sterownika Oracle (Oracle Client) niezgodność bitów może powodować komunikat podobny do poniższego:

Attempt to load Oracle client libraries threw BadImageFormatException. This problem will occur when running in 64 bit mode with the 32 bit Oracle client components installed.

Możliwość uruchamiania dwóch wersji na jednym fizycznym komputerze

Instalując sterownik 32-bitowy Oracle pozwalamy na działanie aplikacji tylko w trybie 32-bitowym. Instalując sterownik 64-bitowy pozwalamy na pracę tylko w trybie 64-bitowym. Co zrobić gdybyśmy zechcieli testować i uruchamiać aplikacje w dwóch różnych trybach? Można zastosować dokładnie ten sam mechanizm, który jest stosowany przez Windows.

Gdy 64-bitowy system Windows zamierza uruchomić aplikację 32 bitową musi jej zapewnić środowisko 32-bitowe. Robi to wykorzystując mechanizm przekierowań. Dawniej, w czasach Windows 32-bitowego wszystkie pliki systemowe zlokalizowane były w katalogu %windir%/System32. Gdy pojawiła się wersja 64-bitowa, należało zapewnić możliwość uruchamiania istniejących już aplikacji i niezmienność działania bibliotek. Katalog %windir%/System32 musiał więc pozostać. Wrzucono do niego jednak nie wersje 32-bitowe lecz ich 64-bitowe odpowiedniki. To co dawniej znajdowało się w %windir%/System32 wylądowało teraz w katalogu %windir%\SysWOW64.

W tym momencie dochodzimy do najważniejszego elementu całego mechanizmu. Gdy system Windows wykryje w swoim API odwołania do katalogu %windir%/System32 i wykryje, że aplikacja (a dokładniej, że działający i wywołujący funckję proces) jest 32-bitowy, w sposób niezauważalny przekierowuje do katalogu %windir%\SysWOW64.

Upraszaczając - 64-bitowy proces wczytuje biblioteki z %windir%/System32, 32-bitowy z %windir%/SysWOW64.

Dwie wersje Oracle (x86, x64)

Mechanizm podobny do wyżej opisanego można zastosować w przypadku sterowników Oracle. Należy w tym celu wykonać kilka kroków.

Instalacje dwóch wersji Oracle Client (x86/x64)

Należy pobrać i zainstalować dwie wersje klienta Oracle. Dla porządku niech będzie to w katalogu C:\OraClient\ i podkatalogach jasno wskazujących wersje. Poniżej pokazano strukturę katalogów:

C:
  OraClient
    32Bit         <-tutaj jest sterownik 32 bitowy
    64Bit         <-tutaj jest sterownik 64 bitowy

Do tej pory jest to tylko struktura katalogów z bibliotekami i nie ma tu żadnej wiedzy tajemnej.

Tworzenie miękkich dowiązań w katalogu systemowym

O dowiązaniach twardych i miękkich pisałem już między innymi tutaj: Zmniejszenie rozmiaru katalogu Windows. Tam wykorzystana był program junction. Tutaj, tylko wspomniany w tamtym artykule mklink. Nie wchodząc w szczegóły należy uruchomić konsolę z prawami administratora i wykonać następujące polecenia:

mklink /D %windir%\System32\OraClient C:\OraClient\64Bit
mklink /D %windir%\SysWOW64\OraClient C:\OraClient\32Bit

Opcjonalnie, w PowerShell, również z prawami administratora:

cmd /c mklink "$env:windir\System32\OraClient" 'C:\OraClient\64Bit'
cmd /c mklink "$env:windir\SysWOW64\OraClient" 'C:\OraClient\32Bit'
Miękkie dowiązanie w katalogu systemowym

W katalogu %windir%\System32 oraz %windir%\SysWOW64 powinny sie pojawić miękkie dowiązania (wskazanie na katalog właściwy dla bitowości procesu).

Ustawienie ścieżki systemowej dla Oracle

Ostatni etap to ustawienie katalogu dla Oracle. W tym celu należy przejść do właściwości systemu, na zakładkę Zaawansowane, wybrać Zmienne środowiskowe... i dodać do zmiennej PATH wartość C:\Windows\system32\OraClient.

Ustawienie zmiennej środowiskowej PATH

Kategoria:PowerShellWindows

, 2018-06-28

Komentarze:

Ssaku (2019-02-11 10:07:10)
Bardzo dobre wyjaśnienie i obejście problemu
Gall anonim  (2019-02-13 11:28:48)
Wszystko działa zgodnie z opisem. Dzięki za rozwiązanie mojego problemu!
Dodaj komentarz
Wyślij
Ostatnie komentarze
Dzieki za rozjasnienie zagadnienia upsert. wlasnie sie ucze programowania :).
Co się stanie gdy spróbuję wyszukać:
SELECT * FROM NV_Airport WHERE Code='SVO'
SELECT * FROM V_Airport WHERE Code=N'SVO'
(odwrotnie są te N-ki)
Będzie konwersja czy nie znajdzie żadnego rekordu?