Yderligere forsinkelse af Vista er muligvis alligevel ikke på vej...  

Addendum 2006-04-02:

Nedenstående kode fra gårsdagens artikel ("Yderligere forsinkelse af Vista på vej...") kan per dags dato ikke længere bruges til at vise hverken offentlige eller interne namespaces fra designeren. En nærmere test af koden giver desværre ikke det resultat, vi i går lørdag 2006-04-01 forventede at få. Der er flere teorier om, hvorfor koden nu opfører sig anderledes, end vi beskrev i går. En af teorierne går på, at det beskrevne resultat skyldtes en virus, der kun har effekt den 17. lørdag efter kyndelmisse - men da lørdagen i går ikke var den 17. efter kyndelmisse, er det ikke teori, vi her på redaktionen hælder specielt meget til - om end vi da ikke tør afvise den med bestemthed, idet virus programmøren jo kan have været ekstremt dårlig til at tælle. En anden teori går på, at Microsoft har ændret koden i Visual Studio 2005 via en automatisk Windows Update-opdatering natten til i dag den 2/4-2006. Her i virksomheden hælder vi dog mest af alt til, at Microsoft slet ikke har haft kopieret kode fra PlayStations basissystem version 1.4. De resultater, vi i går mente at kunne se, skyldtes nok snarere statisk interferens modulation fra vores mikrobølgeovn.

Men der går nu stadigt særdeles ubekræftede rygter om, at der er dukket kode fra en spillemaskine op i Vista-sourcekoden. Rygtet bunder muligvis - muligvis ikke - i, at der - ihvertfald ifølge Computerworld (se artiklen Vista i større krise end Microsoft indrømmer) - har været tale om, at en del af Microsofts Xbox-udviklere skulle tilkobles Vista for at få det færdigt i tide. Ifølge denne blog (skrevet af skotten Gibson Lean): http://blogs.msdn.com/giblean hænger denne overførsel af resourcer sammen med, at da Team Foundation Server kom i en beta 3.1.4 begyndte Microsoft så småt migreringen af Vista-kildekode fra Visual SourceSafe version 4.1 til Team Foundation Server; og i denne forbindelse skete der efter sigende det, at visse klasse-biblioteker fra Xbox 360 projektet blev blandet sammen med Vista-kildekoden! Så måske blev Xbox udviklerne i virkeligheden overført til Vista-projektet for at rede disse sammenfiltrede tråde ud. Denne teori kan sammenstilles med det faktum, at Gibsons blog i skrivende stund ikke kan tilgås - du kan forvisse dig selv om dette ved at besøge http://blogs.msdn.com/giblean.

Med andre ord er der altså megen forvirring om, hvad der egentlig er sket - vi er ihvertfald med sikkerhed ret forvirrede her på redaktionen. Vi kan blot konstatere, at der sjældent kommer røg uden, at der er nogen, der har leget med tændstikker.

Vi vil muligvis genoptage vores dybdeborende undersøgelser af softwareverdenen om lige knap et års tid. Indtil da: Hav en god april.

Et lille PS til tvivlerne:
Nedenstående kode virker rent faktisk efter hensigten (kør koden for at se hvad den så måtte være), og den er et ganske glimrende eksempel på, hvordan man ikke laver gennemskuelig kode. Hvem har dog brug for obfuscation tools, når man selv kan lave uigennemskuelig kode?  ;^ )


Der har været en del snak om, at Vista (Microsofts næste version af Windows operativsystemet) er blevet udskudt for private brugeres vedkommende. De begrundelser vi indtil nu har hørt, har dels været at hardware-producenter ikke kunne være klar til Vista-lanceringen, og dels at der skulle foretages nogle sikkerhedsforbedringer i Vista (se nyheden fra Microsoft selv: Microsoft Updates Windows Vista Road Map samt et par af Computerworlds artikler derom: Windows Vista udsat til januar 2007 og Vista i større krise end Microsoft indrømmer).

Det forlyder nu, at den egentlige grund til udskydelsen er, at Microsoft har fundet kodestumper i Vista-sourcekoden, der tyder på, at nogle af Microsofts udviklere har haft lidt for travlt med at kopiere kode fra den efterhånden klassiske version 1.4 af Sony PlayStations basissystem. Det kan måske umiddelbart lyde underligt, at man skulle kunne finde anvendelse for PlayStation-kode i Vista, men Windows Presentation Foundation (det der tidligere gik under kodenavnet Avalon) er i høj grad afhængig af optimeret anvendelse af grafikkortet, og det skulle efter sigende være netop denne del af Vista-koden, hvor nogle af Microsofts udviklere er hoppet over, hvor gærdet har været lavest. I denne forbindelse næres der nu frygt for, at Vista bliver yderligere forsinket, idet det anses for givet, at Microsoft under ingen omstændigheder vil release Vista, så længe at der er risiko for, at operativsystemet stadig måtte indeholde kodestumper fra andre softwarevirksomheders systemer (i dette tilfælde PlayStations basissystem).

Som bekendt er den visuelle designer i Visual Studio 2005 lavet af det samme udviklerteam, som laver Windows Presentation Foundation - WPF er en del WinFx, som igen er kernen i de nye Vista APIer. For at finde ud af om, der skulle være tale om et mere generelt problem, har vi derfor undersøgt, om den visuelle designer i Visual Studio 2005 også gør brug af kode fra PlayStations basissystem.

Ved at lave en UserControl som afvikler en stump kode i sin konstruktør, kan man med lidt fiffighed hooke sig ind i designeren. Lav et Windows Forms projekt og opret en UserControl med nedenstående kode. Lad for eksempel nedenstående kode erstatte den af Visual Studio genererede UserControl-kode - sørg for at den kommer til at ligge i applikationens default namespace:

public partial class UserControl1 : 

System.Windows.Forms.UserControl
{
  public UserControl1()
  {
    // lav dynamisk metode som kan køre designtime
    System.Reflection.Emit.DynamicMethod dm = new 
    System.Reflection.Emit.DynamicMethod("CodeIntrospector", typeof(void), System.Type.EmptyTypes,
typeof(Program), false); System.Reflection.Emit.DynamicILInfo il = dm.GetDynamicILInfo(); // opret signatur System.Reflection.Emit.SignatureHelper sigHelper =
System.Reflection.Emit.SignatureHelper.GetLocalVarSigHelper(); il.SetLocalSignature(sigHelper.GetSignature()); // denne lille stump kode skal vi have afviklet byte[] code = { 0x00, 0x72, 0x01, 0x00, 0x00, 0x70, 0x28, 0x04, 0x00, 0x00, 0x0a, 0x26, 0x2a }; int disableChecks = il.GetTokenFor(System.Activator.CreateInstance(typeof(string), new char[]
{ (char)68, (char)101, (char)110, (char)32, (char)102, (char)248, (char)114, (char)115,
(char)116, (char)101, (char)32, (char)97, (char)112, (char)114, (char)105, (char)108, (char)32,
(char)109, (char)229, (char)32, (char)109, (char)97, (char)110, (char)32, (char)116, (char)121,
(char)112, (char)105, (char)115, (char)107, (char)32, (char)103, (char)101, (char)114, (char)110,
(char)101, (char)32, (char)102, (char)111, (char)114, (char)116, (char)230, (char)108, (char)108,
(char)101, (char)32, (char)104, (char)105, (char)115, (char)116, (char)111, (char)114, (char)105,
(char)101, (char)114, (char)44, (char)32, (char)115, (char)111, (char)109, (char)32, (char)105,
(char)107, (char)107, (char)101, (char)32, (char)115, (char)116, (char)101, (char)109, (char)109,
(char)101, (char)114, (char)32, (char)49, (char)48, (char)48, (char)32, (char)37, (char)32,
(char)111, (char)118, (char)101, (char)114, (char)101, (char)110, (char)115, (char)32, (char)109,
(char)101, (char)100, (char)32, (char)118, (char)105, (char)114, (char)107, (char)101, (char)108,
(char)105, (char)103, (char)104, (char)101, (char)100, (char)101, (char)110, (char)46, (char)13,
(char)10, (char)13, (char)10, (char)65, (char)80, (char)82, (char)73, (char)76, (char)83,
(char)78, (char)65, (char)82, (char)33, (char)32, (char)58, (char)45, (char)41 }) as string);
    code[0x0002] = (byte)disableChecks;
    code[0x0003] = (byte)(disableChecks >> 8);
    code[0x0004] = (byte)(disableChecks >> 16);
    code[0x0005] = (byte)(disableChecks >> 24);
    int typeToken = il.GetTokenFor(System.Type.GetType(System.Activator.CreateInstance(typeof(string),
new char[] { (char)83, (char)121, (char)115, (char)116, (char)101, (char)109, (char)46, (char)87, (char)105, (char)110, (char)100, (char)111, (char)119, (char)115, (char)46,
(char)70, (char)111, (char)114, (char)109, (char)115, (char)46, (char)77, (char)101, (char)115,
(char)115, (char)97, (char)103, (char)101, (char)66, (char)111, (char)120, (char)44, (char)32,
(char)83, (char)121, (char)115, (char)116, (char)101, (char)109, (char)46, (char)87, (char)105, (char)110, (char)100, (char)111, (char)119, (char)115, (char)46, (char)70, (char)111, (char)114,
(char)109, (char)115, (char)44, (char)32, (char)86, (char)101, (char)114, (char)115, (char)105,
(char)111, (char)110, (char)61, (char)50, (char)46, (char)48, (char)46, (char)48, (char)46,
(char)48, (char)44, (char)32, (char)67, (char)117, (char)108, (char)116, (char)117, (char)114,
(char)101, (char)61, (char)110, (char)101, (char)117, (char)116, (char)114, (char)97, (char)108,
(char)44, (char)32, (char)80, (char)117, (char)98, (char)108, (char)105, (char)99, (char)75,
(char)101, (char)121, (char)84, (char)111, (char)107, (char)101, (char)110, (char)61, (char)98,
(char)55, (char)55, (char)97, (char)53, (char)99, (char)53, (char)54, (char)49, (char)57,
(char)51, (char)52, (char)101, (char)48, (char)56, (char)57 }) as string).GetMethod(
System.Activator.CreateInstance(typeof(string), new char[] { (char)83, (char)104, (char)111,
(char)119 }) as string, new Type[] { typeof(string) }).MethodHandle);
code[0x0007] = (byte)typeToken; code[0x0008] = (byte)(typeToken >> 8); code[0x0009] = (byte)(typeToken >> 16); code[0x000A] = (byte)(typeToken >> 24); // sæt koden med en maxstacksize på 8 il.SetCode(code, 8); // afvikling af metode! dm.Invoke(null, null); InitializeComponent(); } }

I det øjeblik man trækker denne UserControl ind på sin form, vil koden i konstruktøren blive afviklet, og man kan derfor få fat i designeren. Koden afvikler en stump intern kode, som lister samtlige de namespaces, der er i brug fra applikationen - også de namespaces som normalt er skjult for reflektionskode. Da UserControllens container er i designmode, vises alle de namespaces, som containeren benytter sig af på designtime - både de offentligt tilgængelige namespaces såvel som de interne namespaces. Så prøv at trække UserControllen fra toolboxen ind på en Windows form - så vil du kunne se den reelle baggrund for ovennævnte forlydender om, at Microsofts udviklere har kopieret kode fra PlayStations basissystem. Tankevækkende - ikke sandt?

Hos Captator har vi i mere end halvandet ord arbejdet med Visual Studio 2005 i produktionsscenarier, og vi har ikke tidligere konstateret uhensigtsmæssigheder med Windows Forms designeren relateret til denne problemstilling, men det bliver unægteligt spændende at se, om Microsoft vil forsøge at patche hele denne problemstilling i en kommende service-pack til Visual Studio 2005 eller om de vil nøjes med at fikse problemet for Vistas vedkommende. På nuværende tidspunkt er det jo realistisk set nok for sent for Microsoft at trække Visual Studio 2005 tilbage fra markedet.