kraft shdl

Wenn man mit einem Programm die Registrierung auslesen muss, sollte man besonders bei 64-Bit Systemen aufpassen. Öffnet man das Tool regedit bekommt man die  64-Bit-Ansicht der Windows-Registry angezeigt. Soweit so gut.

Öffnet man die Registry aber aus dem Code heraus, kommt es darauf an, wie man das Executable Kompiliert hat. Mit der Einstellung X86 öffnet man die Registry in der 32-Bit-Ansicht. Mit der Einstellung X64 öffnet man die Registry in der 64-Bit-Ansicht. Bei AnyCPU kommt es noch auf die Einstellung unter Prefer 32-Bit an. Richtig: ist hier ein Haken gesetzt, wird die 32-Bit, sonst die 64-Bit-Ansicht geöffnet. Klingt ziemlich verworren? Ist es auch.

Den Abhängigkeiten über das Platform-Target kann man dadurch umgehen, dass man beim Öffnen der Registrierung angibt, in welcher Ansicht man die Registry öffnen will. Und das geht so:

//needed for the registry access
using Microsoft.Win32;
//search in current user
RegistryKey currentUser64 = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.CurrentUser, RegistryView.Registry64);						
RegistryKey currentUser32 = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.CurrentUser, RegistryView.Registry32);						

 Nützlich kann es bei dieser Verarbeitung noch sein, dass man nach der Architektur des Betriebssystems unterscheidet. Dazu kann der folgende Einzeiler verwendet werden:

Mich erreicht eine Fehlermeldung vom Kunden. Bei bestimmten Geräten wird die Status-LED in der Initialisierungsphase nicht korrekt geschaltet bzw. sie bleibt aus. Ich lasse mir einen Trace schicken und stelle fest, dass beim Auslesen der Daten aus dem EEPROM etwas schief läuft und für die Revision kein Wert zurückkommt. Ich schaue in den Code und entdecke das folgende Schmuckstück Programmierkunst. Diese Abfrage macht sicher nicht das was sie soll.

if (buffer[1] == 0x00)
{
	//answer seems to be ok
	iFeederRevision = Convert.ToInt32(string.Format("{0:x2}{1:x2}", buffer[3], buffer[2]), 16);
}
else if (buffer[1] == 0x00)
{
	iFeederRevision = 1;
}

Ihr kennt das? Ihr habt schreibt euch ein eigenes Steuerelement und leitet dieses von einem vorhandenen Steuerelement ab. Wenn ihr im Visual Studio auf die entsprechende Datei doppelt klickt öffnet sich das Entwurfsfenster.

Entwurfsansicht

Für manche Steuerelementerweiterungen mag das Sinn machen. Für manche nicht. Wenn ihr die Codeansicht anzeigen wollt, könnt ihr mit F7 dorthin wechseln oder ihr tragt die folgende Anweisung in den Quellcode ein:

[System.ComponentModel.DesignerCategory("Code")]
public class UptimeTablePanel : Panel, IGUIPanel, IGUIDragAndDrop

 

„Egal, was der Bediener eingibt, es steht immer nichts in den manuellen Messwerten drinnen“: so lautet die Fehlerbeschreibung beim Kunden. Und tatsächlich es lässt sich nachvollziehen. Man trägt einen Wert ein, verlässt die Zeile bzw. klickt auf Ok und dann verschwindet der wert wieder. Ein Blick in den Code macht auch schnell deutlich, warum das so ist.

if (oNewValue != null)
{
  clsMesBO.TValue = oNewValue.ToString();
}
{
   clsMesBO.TValue = null;
}

Hier fehlt ein else. So wie es programmiert ist, werden alle Werte mit null überschrieben.

Inzwischen war Zeit, sich die hier bemängelte Verarbeitung näher anzusehen. Es ist noch schlimmer als gedacht und es werden Dateien gelöscht, die sicher nicht gelöscht werden dürfen und zwar unabhängig davon, wo die Software installiert wird. Und der Grund ist, dass in Application.StartupPath nicht der Pfad der Applikation steht, denn gestartet wird bei der Deinstallation der Installer (bei Windows 7 in syswow64).

Beheben lässt sich das in dem man den Applicationpfad aus dem Context ausliest:

string strAssemblyPath = Context.Parameters["assemblypath"].ToString();
strAssemblyPath = Path.GetDirectoryName(strAssemblyPath);

Das löst aber noch nicht das Problem, dass möglicherweise Dateien aus einem Ordner gelöscht werden, die gar nicht zur Software gehören. Das umgehen wir, indem wir eine Datei mit allen installierten Dateien schreiben (dir /b /s > deletefiles.txt). Beim Deinstallieren wird diese Datei eingelesen und es werden nur noch die Dateien gelöscht, die dort aufgeführt sind.