Kompatybilność wsteczna .NET 4.0 - poziom źródłowy i binarny

0

Wiadomym jest, że .NET 3.5 jest kompatybilny na poziomie źródłowym i binarnym z .NET 2.0. Zauważyłem, że .NET 4.0 jest kompatybilny z .NET 3.5 tylko na poziomie źródłowym, a nie jest na poziomie binarnym. Objawia się tym, że w Windows Server 2012, jak próbuję uruchomić aplikację skompilowaną w .NET 3.5, to wymusza instalację wersji 3.5 pomimo istnienia 4.0. Jak wczytam kod źródłowy do Visual Studio 2012, we właściwościach ustawię wersję .NET 4.0 i skompiluję, to na serwerze uruchamia się bez problemu. Jest to dowód na to, że .NET 4.0 zawiera wszystko to, co zawierały wcześniejsze wersje do 2.0 włącznie, więc równoległe istnienie .NET 3.5 i .NET 4.0 w systemie nie ma sensu, wszystko będzie zdublowane, poza tym nie po to jest fabrycznie zainstalowany .NET, żeby trzeba było instalować .NET osobno.

Zakładam, że na serwerze nie mam uprawnień administracyjnych, ale mogę wprowadzać dowolne pliki i uruchamiać dowolne programy.

Jeżeli mam kod źródłowy programu i kompilator kompilujący do .NET 4.0, to nie ma problemu. Co w przypadku, gdy nie mam kodu, lub nawet ani kodu ani VS2012?

Wydaje mi się, że da się przekonwertować plik EXE nie mając kodu źródłowego. Może tylko w nagłówku wystarczy coś zmienić, albo po prostu przekonwertować każdy rozkaz MSIL na odpowiednik z .NET 4.0. Pomijam fakt, że nowsza wersja kompilatora Visual Studio lepiej optymalizuje kod MSIL przy kompilacji kodu źródłowego. Czy istnieje jakiś sprawdzony program lub sposób, że wczytuję plik EXE i zapisuje plik EXE kompatybilny z .NET 4.0?

Jak ustawić projekt w Visual Studio 2012, żeby można było go skompilować pod .NET 3.5 i uruchamiać tam, gdzie nie ma .NET 4.0, ale jednocześnie ten sam EXE uruchamiać na systemie zawierającym wyłącznie .NET 4.0 bez żadnych zmian, ani dwóch identycznych EXE różniących się wersją .NET, ani doinstalowywania .NET 3.5?

0
andrzejlisek napisał(a):

Jest to dowód na to, że .NET 4.0 zawiera wszystko to, co zawierały wcześniejsze wersje do 2.0 włącznie, więc równoległe istnienie .NET 3.5 i .NET 4.0 w systemie nie ma sensu, wszystko będzie zdublowane, poza tym nie po to jest fabrycznie zainstalowany .NET, żeby trzeba było instalować .NET osobno.

Sam sobie przeczysz. Ma to jak najbardziej sens, bo kod skompilowany w 3.5 nie uruchomi się na Frameworku 4.0. Jeśli chcesz mieć kompatybilność ze starymi programami, to musisz też mieć stary framework. Proste.

Czy istnieje jakiś sprawdzony program lub sposób, że wczytuję plik EXE i zapisuje plik EXE kompatybilny z .NET 4.0?

Zdekompiluj i skompiluj ponownie.

Jak ustawić projekt w Visual Studio 2012, żeby można było go skompilować pod .NET 3.5 i uruchamiać tam, gdzie nie ma .NET 4.0, ale jednocześnie ten sam EXE uruchamiać na systemie zawierającym wyłącznie .NET 4.0 bez żadnych zmian, ani dwóch identycznych EXE różniących się wersją .NET, ani doinstalowywania .NET 3.5?

A to taki wielki problem skompilować program w dwóch wersjach i obie rozpowszechniać? :|

0
somekind napisał(a):
andrzejlisek napisał(a):

Jest to dowód na to, że .NET 4.0 zawiera wszystko to, co zawierały wcześniejsze wersje do 2.0 włącznie, więc równoległe istnienie .NET 3.5 i .NET 4.0 w systemie nie ma sensu, wszystko będzie zdublowane, poza tym nie po to jest fabrycznie zainstalowany .NET, żeby trzeba było instalować .NET osobno.

Sam sobie przeczysz. Ma to jak najbardziej sens, bo kod skompilowany w 3.5 nie uruchomi się na Frameworku 4.0. Jeśli chcesz mieć kompatybilność ze starymi programami, to musisz też mieć stary framework. Proste.

To w takim razie .NET 4.0 jest czy nie jest wstecznie kompatybilny? Idąc tym tokiem rozumowania, kod skompilowany na 2.0 nie uruchamiałby się na 3.5, a uruchamia się bez najmniejszego problemu.

Grafika https://upload.wikimedia.org/wikipedia/commons/thumb/d/d3/DotNet.svg/800px-DotNet.svg.png sugeruje, że każda nowa wersja licząc od 2.0 to jest nadbudowa starej, co znaczy, że .NET 4.0 jest wstecznie kompatybilny ze wszystkimi wersjami do 2.0. Inną sprawą jest wersja 1.1, która jest już dawno zapomniana i nikt z niej nie korzysta.

somekind napisał(a):

Czy istnieje jakiś sprawdzony program lub sposób, że wczytuję plik EXE i zapisuje plik EXE kompatybilny z .NET 4.0?

Zdekompiluj i skompiluj ponownie.

somekind napisał(a):

Jak ustawić projekt w Visual Studio 2012, żeby można było go skompilować pod .NET 3.5 i uruchamiać tam, gdzie nie ma .NET 4.0, ale jednocześnie ten sam EXE uruchamiać na systemie zawierającym wyłącznie .NET 4.0 bez żadnych zmian, ani dwóch identycznych EXE różniących się wersją .NET, ani doinstalowywania .NET 3.5?

A to taki wielki problem skompilować program w dwóch wersjach i obie rozpowszechniać? :|

To żaden problem pod warunkiem, że to ja jestem autorem programu oraz dysponuję kompilatorem Visual Studio, wtedy mogę zrobić 5 wersji programu, jak będę chciał. Problem jest wtedy, gdy exe pochodzi z obcego źródła, jedynie ewentualna dekompilacja i kompilacja może załatwić sprawę.

2

.NET generalnie jest wstecznie kompatybilny oraz częściowo kompatybilny w przód (i nie mówię tutaj o żadnych rekompilacjach).

Faktycznie domyślnie jest tak, że .NET preferuje uruchomienie aplikacji na wersji frameworka którą targetuje aplikacja i domyślnie skończy się to błędem jeżeli nie ma jej w systemie. Żeby zmusić uruchomienie aplikacji na nowocześniejszym .NET trzeba dać o tym znać za pomocą <supportedRuntime> w .config.

https://msdn.microsoft.com/en-us/library/ff602939(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/jj152935(v=vs.110).aspx

3

Jest to dowód na to

To że ci wyskakiwało okienko do instalacji 3.5 to jeszcze nie żaden dowód.

3.5 jest całkowicie zgodny z 2.0 SP1, bo jest to ta sama maszyna wirtualna. 3.5 to tylko zestaw dodatkowych bibliotek z których program może korzystać (i wtedy to się nazywa 3.5) albo nie korzystać (i wtedy to się nazywa 2.0 SP1). Jest jeszcze pośrednia wersja 3.0, na tej samej zasadzie co 3.5.

EXE skompilowany pod 3.5 ale nie używający żadnej klasy ani funkcji której nie ma pod 2.0, ruszy pod 2.0, bo kompilowanie pod 3.5 albo pod 3.0 a używanie tylko elementów występujących pod 2.0 to to samo co kompilowanie pod 2.0.

4.0 wprowadza nową wersję maszyny wirtualnej. Od tej pory kolejne wersje zastępują poprzednie, czyli instalacja 4.5 albo 4.6 powoduje zastąpienie 4.0 i nie da się mieć jednocześnie zainstalowanej wersji 4.0 i 4.5.
I tu jest ta sama sytuacja co wcześniej: program skompilowany pod 4.5 a używający tylko elementów z 4.0 będzie działać pod 4.0.

A teraz kwestia rzekomej niekompatybilności binarnej między 3.5 a 4.0.
Otóż ta kompatybilność jest. Prawie. Można w pliku konfiguracyjnym wymusić uruchomienie exeka skompilowanego dla 2.0/3.0/3.5 pod 4.0 albo nowszym.
„Powinien” działać, ale zgodność nie jest stuprocentowa, bo Microsoft naprawia (jednak czasem) różne bugi, co może zmienić działanie starszych aplikacji.

0
andrzejlisek napisał(a):

Grafika https://upload.wikimedia.org/wikipedia/commons/thumb/d/d3/DotNet.svg/800px-DotNet.svg.png sugeruje, że każda nowa wersja licząc od 2.0 to jest nadbudowa starej, co znaczy, że .NET 4.0 jest wstecznie kompatybilny ze wszystkimi wersjami do 2.0. Inną sprawą jest wersja 1.1, która jest już dawno zapomniana i nikt z niej nie korzysta.

Ta grafika niczego takiego nie sugeruje, jedynie pokazuje co dochodziło w poszczególnych wersjach frameworka.
.NET 4.0 przyniósł zmiany w swoich bibliotekach (choćby w mscorlib), to jest nowa wersja .NET, a nie nadbudowka do 2.0, jak było w przypadku 3.0 i 3.5.

0 użytkowników online, w tym zalogowanych: 0, gości: 0