Die seltsame Liebe eines Entwicklers, oder: Wie ich lernte, mir keine Sorgen mehr zu machen, und Windows lieben lernte
· Go Komura · Windows, Windows-Entwicklung, Abwärtskompatibilität, COM, ActiveX, QA, Philosophie
1. Zuerst das Fazit
Wenn man Windows-Anwendungen entwickelt, gibt es viel, worüber man sich Sorgen machen kann.
Wird sie auf diesem PC überhaupt starten? Läuft sie auch in einer Umgebung ohne Administratorrechte? Bricht sie an der Grenze zwischen 32-Bit und 64-Bit zusammen? Japanische Pfade, lange Pfade, Netzlaufwerke, alte DLLs, COM-Komponenten, ActiveX, Drucker, serielle Kommunikation, Antivirensoftware, Windows Update.
Fängt man erst an, darüber nachzudenken, nehmen die Sorgen kein Ende.
Doch irgendwann begann ich, es anders zu sehen.
Vielleicht ist das gar kein Makel, sondern der Beweis dafür, dass Windows über Jahrzehnte hinweg reale Geschäftsprozesse getragen hat.
Windows ist keine makellose Utopie. Aber es trägt die Software, die Geräte, die Arbeitsabläufe und die eingespielten Gewohnheiten der Menschen, die dort seit Jahrzehnten im Einsatz sind.
Genau dieses Chaos macht Windows interessant – und macht es für einen Entwickler lohnenswert, sich damit auseinanderzusetzen.
2. Windows-Anwendungsentwicklung bringt viele Sorgen mit sich
Bei der Entwicklung von Windows-Anwendungen reicht es nicht, dass „der Code korrekt ist”.
Er läuft in der lokalen Umgebung. Er läuft auf dem Rechner des Entwicklers. Er läuft sogar auf der Test-VM.
Trotzdem ist keineswegs garantiert, dass er auch auf dem Rechner des Kunden läuft.
Zum Beispiel passiert Folgendes:
- Eine DLL wird nicht gefunden
- Die Visual-C++-Laufzeitumgebung ist nicht installiert
- Die Version des .NET Framework passt nicht
- Das Laden einer 32-Bit-DLL aus einem 64-Bit-Prozess schlägt fehl
- Die COM-Registrierung ist beschädigt
- Die 32-Bit- und die 64-Bit-Version von
regsvr32.exewerden verwechselt - Code, der von einem festen aktuellen Verzeichnis ausgeht, bricht unter dem Aufgabenplaner
- Ein Schreibversuch unterhalb von
Program Filesführt zu einem Berechtigungsfehler AppData\RoamingundAppData\Localwerden vertauscht- Es stürzt bei japanischen Benutzernamen oder japanischen Ordnernamen ab
- Dateien lassen sich bei langen Pfaden nicht öffnen
- Es läuft auf einem zugeordneten Netzlaufwerk, aber nicht über einen UNC-Pfad
- Die Darstellung zerbricht in Umgebungen mit hoher DPI
- Bei mehreren Monitoren verschieben sich die Koordinatenberechnungen
- Je nach Druckertreiber sieht das Druckergebnis anders aus
- USB-Geräte, Kameras, Messgeräte und serielle Kommunikation werden je nach Umgebung nicht erkannt
- Antivirensoftware blockiert einen Teil der Verarbeitung
- Nach einem Windows Update ändert sich das Verhalten
Reiht man das so auf, wird einem fast schwindlig.
Probleme, die bei einer Webanwendung zwischen Browser und Server eingeschlossen bleiben, breiten sich bei einer Windows-Anwendung über den gesamten PC aus. Dateisystem, Registrierung, Benutzerprofile, Drucker, Geräte, Netzwerk, Sicherheitsrichtlinien, Installationsprogramme, Laufzeitumgebungen.
Die Anwendung läuft weniger „auf dem Betriebssystem”, als dass sie mitten in eine reale Arbeitsumgebung hineingestellt wird.
Deshalb ist die Entwicklung von Windows-Anwendungen schwierig. Sie deshalb einfach als „Windows taugt nichts” abzutun, greift meiner Meinung nach zu kurz.
Was hier zutage tritt, ist die Komplexität der realen Welt.
3. Windows ist das Betriebssystem der Praxis
Windows ist kein Betriebssystem, das nur für die neueste Technik existiert.
Fabriken, Krankenhäuser, Behörden, Schulen, Labore, Sendeanstalten, Prüfgeräte, Empfangsterminals, Terminals für Formulardruck, Lager, Geschäfte, Buchhaltung, Lohnabrechnung, Bestandsverwaltung. An solchen Orten laufen bis heute unzählige Windows-PCs.
Dort gibt es nicht nur die neuesten Webdienste.
Es gibt Excel-Makros. Es gibt Access. Es gibt alte VB-Anwendungen. Es gibt Geschäftsanwendungen auf Basis des .NET Framework. Es gibt residente Anwendungen, die in C++ geschrieben sind. Es gibt COM-Komponenten. Es gibt ActiveX. Es gibt ODBC-Verbindungen. Es gibt Druckertreiber. Es gibt Barcode-Scanner. Es gibt Messgeräte mit serieller Kommunikation. Es gibt vom Hersteller bereitgestellte SDKs.
Und das alles existiert nicht isoliert für sich.
Menschen bedienen die Geräte, drucken Formulare, tauschen USB-Geräte aus, legen CSV-Dateien in Freigabeordnern ab; nachts laufen Batch-Jobs, und am nächsten Morgen beginnt die Arbeit von Neuem. All das läuft innerhalb dieses zusammenhängenden Ablaufs.
Windows ist nicht bloß eine Grundlage zum Starten von Anwendungen. Es ist eine Plattform, die die tägliche Arbeit vor Ort, bestehende Bestände, Peripheriegeräte und selbst die Gewohnheiten der Menschen mit aufnimmt.
Deshalb wirkt es manchmal alt. Manchmal ist es kompliziert. Manchmal fragt man sich, warum es das eine oder andere überhaupt noch gibt.
Aber das bedeutet auch, dass hier nichts Altes achtlos weggeworfen wurde.
4. Abwärtskompatibilität als eine Form von Liebe
Wollte man ein Betriebssystem nur schön aussehen lassen, wäre es einfacher, alte Mechanismen einfach zu kappen.
Alte APIs löschen. Alte Laufzeitumgebungen löschen. Alte Einstellungsdialoge löschen. Alte Anwendungen als etwas behandeln, das eben nicht mehr läuft.
Täte man das, würde das Design vielleicht klarer. Die Dokumentation würde vielleicht kürzer. Die Entwickler würden sich vielleicht ein wenig leichter fühlen.
Aber im Hintergrund gäbe es Geschäftsanwendungen, die nicht mehr funktionieren. Es gäbe Geräte, die stillstehen. Es gäbe Betriebe, die in Schwierigkeiten geraten.
Windows’ Abwärtskompatibilität ist technisch gesehen lästig.
Es gibt WOW64, damit 32-Bit-Anwendungen unter 64-Bit-Windows laufen.
Registrierung und DLLs können sich für 32-Bit- und 64-Bit-Code unterschiedlich darstellen.
Es gibt die – auf den ersten Blick verwirrende – Struktur, bei der C:\Windows\System32 die 64-Bit-Seite und C:\Windows\SysWOW64 die 32-Bit-Seite ist.
Auch COM ist lästig. Es reicht nicht, die DLL einfach abzulegen; oft ist eine Registrierung nötig. Erfolgt die Registrierung pro Benutzer oder pro Maschine? Handelt es sich um 32-Bit- oder um 64-Bit-COM? Sind Administratorrechte erforderlich?
Beim .NET Framework ist es genauso.
Heute gibt es die Möglichkeit, ein modernes .NET wie .NET 8 oder .NET 9 zu verwenden.
Doch in der Praxis laufen noch immer Anwendungen auf Basis von .NET Framework 4.x.
Das ist nicht einfach nur veraltet – es bedeutet, dass diese Version über viele Jahre hinweg reale Geschäftsprozesse getragen hat.
Abwärtskompatibilität ist kein Konzept, das nur schön ist. Sie ist vielmehr eine schwere Verantwortung.
Alte Dinge am Laufen zu halten bedeutet, technische Schulden zu tragen. Gleichzeitig ist es aber auch eine Form von Aufrichtigkeit: den Betrieb der Nutzer nicht zum Stillstand zu bringen.
Genau darin, glaube ich, liegt das Liebenswerte an Windows.
5. Windows ist ein Betriebssystem wie geologische Schichten
In Windows haben sich die Technologien der jeweiligen Epochen wie geologische Schichten übereinandergelagert.
Win32. COM. ActiveX. Windows Forms. WPF. .NET Framework. UWP. WinUI. Windows App SDK. MSIX. PowerShell. Windows Terminal. WSL.
Jede davon hatte ihre Zeit des Erscheinens, ihre Stärken und die Praxisorte, an denen sie eingesetzt wurde.
Betrachtet man nur das Neue, mag das Alte wie ein Hindernis wirken. Doch bei der Entwicklung von Windows-Anwendungen gibt es häufig Situationen, in denen man die älteren Schichten nicht ignorieren kann.
Baut man zum Beispiel eine WPF-Anwendung, kann man beim Drucken trotzdem mit GDI- und Druckertreiberproblemen in Berührung kommen. Schreibt man in C#, stößt man bei einem Hersteller-SDK, das eine native DLL ist, auf P/Invoke- und Bitbreiten-Probleme. Baut man neue Bildschirme, muss man mitunter bestehende COM-Komponenten oder die Excel-Anbindung erhalten.
Windows ist kein durchgeplanter, perfekt geharkter Garten. Es ähnelt eher einer riesigen Stadt, die immer wieder erweitert und umgebaut wurde.
Es gibt breite Boulevards. Es gibt unterirdische Gänge. Es gibt alte Gassen. Es gibt neue Hochhäuser.
Man verliert sich leicht darin. Aber tief in diesen Gassen läuft bis heute wichtige Arbeit.
Was ein Entwickler braucht, ist nicht das Urteil „alt bedeutet überflüssig”. Es ist die Fähigkeit zu erkennen, welche Schicht welcher Technologie welches Geschäft trägt.
6. Aus der Umständlichkeit ein Design machen
Im Titel steht „aufzuhören, sich Sorgen zu machen”.
Doch aufzuhören, sich Sorgen zu machen, bedeutet nicht, nachlässig zu werden. Es bedeutet auch nicht, Probleme einfach zu übersehen.
Aufzuhören, sich Sorgen zu machen, bedeutet, die Sorge in ein Design zu verwandeln.
Ist man zum Beispiel unsicher, ob die Anwendung startet, macht man aus der Startprüfung einen Smoke-Test.
Start-Process .\MyApp.exe
Und dabei nicht nur den Start prüfen, sondern auch Zustände ohne Konfigurationsdatei, ohne Protokollordner, mit Standardbenutzerrechten, ohne Netzwerkverbindung, ohne eingerichteten Drucker, bei hoher DPI, mit langen Pfaden und mit japanischen Pfaden ausprobieren.
Ist man sich bei DLLs unsicher, überprüft man die Abhängigkeiten. Wird die Visual-C++-Laufzeitumgebung benötigt, entscheidet man, ob sie ins Installationsprogramm aufgenommen oder explizit als Voraussetzung dokumentiert wird. Verwendet man native DLLs, lässt man die Beziehung zwischen x86, x64 und AnyCPU nicht im Unklaren.
Ist man sich bei COM unsicher, hält man die Registrierungsschritte in einer Anleitung fest und reproduziert sie von Grund auf auf einem Test-PC.
# Beispiel: Registrierung einer 64-Bit-COM-DLL
C:\Windows\System32\regsvr32.exe .\SomeComponent64.dll
# Beispiel: Registrierung einer 32-Bit-COM-DLL
C:\Windows\SysWOW64\regsvr32.exe .\SomeComponent32.dll
Ist man sich bei Berechtigungen unsicher, vermeidet man Designs, die nur mit Administratorrechten funktionieren.
Benutzerbezogene Einstellungen legt man in AppData ab, maschinenweite Einstellungen in ProgramData.
Designs, die Protokolle unterhalb von Program Files schreiben, vermeidet man.
Ist man sich bei Pfaden unsicher, nimmt man japanische Zeichen, Leerzeichen, lange Ordnernamen und UNC-Pfade in die Tests auf.
New-Item -ItemType Directory -Path "C:\テスト 用\とても長いフォルダー名\さらに深いフォルダー" -Force
Ist man sich bei DPI unsicher, prüft man bei 100 %, 125 %, 150 % und 200 %. Bei mehreren Monitoren prüft man, ob beim Wechsel zwischen Displays mit unterschiedlicher Skalierung nichts zusammenbricht. Da WinForms, WPF und WinUI die DPI-Unterstützung jeweils unterschiedlich handhaben, prüft man je nach UI-Technologie gesondert.
Ist man sich bei Speicher und Handles unsicher, verwendet man Application Verifier, WinDbg, ProcDump, Process Explorer und Ähnliches. Ist man sich bei Abstürzen unsicher, hält man Ereignisprotokolle, Dumps und Anwendungsprotokolle fest.
Get-EventLog -LogName Application -Newest 20
Oder, in neueren Umgebungen, prüft man das Ereignisprotokoll so:
Get-WinEvent -LogName Application -MaxEvents 20
Ist man sich bei Fehlern unsicher, die sich vor Ort nicht reproduzieren lassen, erhöht man die Granularität der Protokollierung. „Es ist ein Fehler aufgetreten” reicht nicht. Welche Datei sollte geöffnet werden? Welches Gerät wurde gesucht? Unter welchem Benutzer wurde ausgeführt? In welchen Pfad sollte geschrieben werden? Welche DLL konnte nicht geladen werden?
Die Sorge in etwas Beobachtbares verwandeln.
Das ist bei der Entwicklung von Windows-Anwendungen ausgesprochen wichtig.
7. „Es läuft auf dem PC des Kunden” ist das eigentliche Ziel
Dass etwas in der Entwicklungsumgebung läuft, ist wichtig. Dass die Tests in der CI durchlaufen, ist wichtig. Dass es auf einer sauberen VM läuft, ist wichtig.
Doch bei einer Windows-Anwendung stellt sich am Ende immer die Frage: „Läuft es auf dem PC des Kunden?”
Auf diesem PC ist bereits etwas installiert. Vielleicht ist ein alter Druckertreiber installiert. Vielleicht ist eine firmeneigene Sicherheitssoftware installiert. Vielleicht sind Netzlaufwerke zugeordnet. Vielleicht hat der Benutzer keine Administratorrechte. Vielleicht gibt es Gründe, warum Windows Update nicht sofort eingespielt werden kann. Vielleicht gibt es keinen Internetzugang.
Deshalb ist auch die Art der Verteilung wichtig.
Reicht es, einfach eine EXE zu übergeben? Sollte es eine MSI sein? ClickOnce? MSIX? Lässt sich das über winget verteilen? Kommt es in ein internes Verteilungssystem? Wird ein Offline-Installationsprogramm benötigt? Ist eine Codesignatur erforderlich? Blockieren SmartScreen oder Antivirensoftware die Anwendung?
Erst wenn man nicht nur die Anwendung selbst, sondern auch Installation, Aktualisierung, Deinstallation, Protokollerfassung und Wiederherstellungsverfahren einbezieht, kommt man dem Zustand „vor Ort einsetzbar” wirklich nahe.
Bei der Entwicklung von Windows-Anwendungen ist die Software mit der Auslieferung nicht fertig. Sie muss in der Umgebung des Kunden heute wie morgen starten.
8. Warum ich Windows trotzdem liebe
Windows hat seine lästigen Seiten. Das ist eine Tatsache.
DLLs. COM. Die Registrierung. UAC. DPI. Drucker. Laufzeitumgebungen. 32-Bit / 64-Bit. Netzlaufwerke. Lange Pfade. Japanischsprachige Umgebungen. Sicherheitssoftware. Windows Update.
Zählt man die lästigen Dinge auf, hört es nicht mehr auf.
Doch ein Großteil dieser Umständlichkeit kommt daher, dass Windows über sehr lange Zeit reale Geschäftsprozesse getragen hat.
Es wirft alte Bestände nicht weg und nimmt trotzdem neue Technik auf; es besitzt eine grafische Oberfläche ebenso wie eine Kommandozeile; es trägt lokale Anwendungen wie das Web, Peripheriegeräte wie Arbeitsplatzterminals, private wie geschäftliche PCs gleichermaßen.
Das ist keine schöne, einheitliche Philosophie.
Aber es ist stark.
Und als Entwickler lohnt es sich, sich dem zu stellen.
Software zu bauen, die zuverlässig auf Windows läuft, ist nicht bloß eine Frage des Aufrufens von APIs. Es bedeutet, die Zwänge der Praxis zu lesen, bestehende Bestände zu verstehen, verwundbare Stellen zu finden, zu testen, zu beobachten und dort zu korrigieren, wo es nötig ist.
Das ist unspektakulär. Aber es hat Wert.
9. Fazit
Bei der Entwicklung von Windows-Anwendungen gehen die Sorgen nie aus.
Doch viele dieser Sorgen sind auch das Ergebnis davon, dass Windows als Betriebssystem über sehr lange Zeit reale Geschäftsprozesse, reale Einsatzorte, reale Geräte und reales menschliches Handeln aufgenommen hat.
Deshalb halte ich Windows nicht für ein bloß altes Betriebssystem.
Es ist eine riesige, komplexe, ein wenig unbeholfene Plattform, die weiterläuft, während sie sich mit der Realität arrangiert.
Und Software zu bauen, die darauf zuverlässig läuft, hat auch heute noch einen großen Wert.
Aufhören, sich Sorgen zu machen.
Das heißt aber nicht, unvorsichtig zu werden.
Die Sorge in Design, Tests und Beobachtung verwandeln.
So bin ich, Stück für Stück, dazu gekommen, Windows zu lieben.
Referenzlinks
- Application Verifier - Overview - Microsoft Learn
- High DPI Desktop Application Development on Windows - Microsoft Learn
- Setting the default DPI awareness for a process - Microsoft Learn
- Running 32-bit Applications - Microsoft Learn
- Maximum Path Length Limitation - Microsoft Learn
- MSIX documentation - Microsoft Learn
- Version compatibility in .NET Framework - Microsoft Learn
Verwandte Artikel
Aktuelle Artikel mit denselben Schlagwörtern führen zu verwandten Themen weiter.
Windows-App-Outsourcing und Auftragsentwicklung: Was Sie vor der Beauftragung klären sollten
Bevor Sie die Entwicklung einer Windows-App outsourcen oder in Auftrag geben, sollten Sie folgende Punkte klären: Überarbeitung bestehend...
Process Monitor (ProcMon) Praxisleitfaden — „Konfiguration wird nicht gelesen“ und ACCESS DENIED in 10 Minuten identifizieren
„Ich habe die Konfigurationsdatei korrigiert, aber die Änderung wird nicht übernommen“ – „Bis gestern lief es noch, aber heute startet es...
Wenn man eine Windows-App besser nicht ins Web migriert: Entscheidungstabelle und die pragmatische Lösung der Aufteilung
Der Wunsch, interne Windows-Anwendungen ins Web zu migrieren, nimmt stetig zu. Doch bei Apps mit Gerätekopplung, lokaler Dateiverarbeitun...
Mehrsprachigkeit für WinForms/WPF-Anwendungen ── resx, Satelliten-Assemblies und Kulturumschaltung in der Praxis
Dieser Artikel behandelt die Mehrsprachigkeit von Windows-Desktopanwendungen aus Praxissicht: den Unterschied zwischen CurrentCulture und...
CSV ist nicht „nur Text“ ── CSV in der Praxis für C#-Business-Anwendungen (Zeichenkodierung, Excel-Kompatibilität, Schutz vor Injection)
Typische Fehlerquellen bei der CSV-Ein-/Ausgabe in Business-Anwendungen – selbstgebautes Parsen mit Split(','), Excel-Zeichensalat bei UT...
Verwandte Themen
Diese Seiten ordnen den Artikel in einen größeren Leistungs- und Entscheidungskontext ein.
Technische Windows-Themen
Portal zu Windows-Entwicklung, Fehleranalyse und der Nutzung bestehender Assets.
ActiveX-Migration
Entscheidungen zum Beibehalten, Kapseln oder Ersetzen von COM / ActiveX / OCX.
Leistungen zu diesem Thema
Dieser Artikel ist direkt mit den folgenden Leistungen verbunden.
Windows-App-Entwicklung
Geschäftsanwendungen, Geräteintegration und Kommunikationstools von den Anforderungen bis zur Umsetzung.
Nutzung und Migration bestehender Assets
Wiederverwendung und Migration von COM / ActiveX / OCX sowie 32-/64-Bit-Abhängigkeiten.
Autorenprofil
Profilseite des Artikelautors.
Go Komura
Geschäftsführer von KomuraSoft LLC
Spezialisiert auf Windows-Softwareentwicklung, technische Beratung und Fehleranalyse, insbesondere bei bestehenden Systemen und schwer reproduzierbaren Störungen.
Öffentliche Links