Man sieht es immer wieder. Es gibt eine Funktion, die etwas prüft und das Ergebnis als boolsche Variable (also true oder false) zurück gibt. Was man aber unbedingt nicht-nicht bleiben lassen sollte, ist die Funktion mit notXYZ() benennen. Zum Beispiel isNotLinked(). Das wird für manche spätestens bei if (!isNotLinked()) schwierig. Also besser die Funktion isLinked() nennen. Das kommt dem menschlichen Hirn mehr entgegen und der Code bleibt verständlicher.

Gestern war am Nachmittag ein Kundentermin geplant. Diesen Termin musste der Kunde wegen Krankheit kurzfristig absagen und so hatte ich unerwartet Freizeit. Ich hätte zwar zu einer Veranstaltung im Rahmen eine ehrenamtlichen Engagements gehen können, doch darauf habe ich bewusst verzichtet und die kleine unerwartete Auszeit genossen.

Ganz untätig war ich allerdings nicht. Ich habe ein neues Webseitenprojekt auf den Weg gebracht und mit den ersten Anpassungen am Template begonnen. Und nebenbei habe ich mein Visual Studio 2015 so modifiziert, dass ich damit Cordova-Projekte erstellen kann. Ein erster schneller Test zeigte, dass es scheinbar gut, ja sogar besser als mit Eclipse funktioniert. Doch dieser erste Eindruck muss sich erst noch bestätigen. Auf jeden Fall habe ich mir vorgenommen meine alte Liebe, die Fußball-Ticker-Berichte-App (fupes) mal wieder voran zu bringen. Und nach der demnächst anstehenden kurzen Auszeit geht es los – so wenigstens die Planung.

AppDieZweite

 

„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.

Ein Kunde ruft bei uns an und berichtet von einem Nutzer, bei dem nach der Deinstallation einer Software plötzlich Systemdateien fehlten. Er kündigt am nächsten Tag zu diesem Thema eine Telefonkonferenz an. Ein kurzer Blick in den Code offenbart furchtbares. Wenn jemand die Software nicht in den vorgeschlagenen Ortner installiert, sondern beispielsweise in den Systemordner, werden dort mit der Deinstallation alle Dateien gelöscht.

Es ist zwar noch nicht evaluiert, aber das dürfte das Problem sein. Eine mögliche Lösung: Mit dem ersten Start schreiben wir eine Datei mit den vorhandenen Dateien und Ordnern (also quasi dir /b > installed.txt). bei der Deinstallation lesen wir diese Datei aus und löschen nur die darin gelisteten Dateien einschließlich der Datei selbst. Der Ordner wird nur gelöscht, wenn er leer ist.

So geht es auf jeden Fall nicht:

private void Permission_AfterUninstall(object sender, InstallEventArgs e)
{
	string Path_LabelFiles = Path.Combine(Application.StartupPath, @"Labels");
	if (Directory.Exists(Path_LabelFiles))
	{
		try
		{
			Directory.Delete(Path_LabelFiles, true);
		}
		catch (Exception ex)
		{
			//nope
		}
	}

	try
	{
		Directory.Delete(Application.StartupPath, true);
	}
	catch
	{
	}

}