HowTo: C# Programm nur mit NotifyIcon ohne Form starten

Für den Fall, dass ihr eine Anwendung erstellen wollt, welche (zum Start) nur ein NotifyIcon (also ein Symbol in der Taskleiste besitzt), müsst ihr den Standardprogrammaufruf etwas abändern.
Der standardmäßig erstellte Code von VisualStudio startet automatisch eine Form. Diese könnte man nun ausblenden (WindowState = Minimized, ShowInTaskBar = false) aber es geht auch eleganter. Erstellt einfach ein NotifyIcon mit Icon und Visible = true und ruft Application.Run() ohne Parameter auf.

		/// <summary>
		/// 	Der Haupteinstiegspunkt für die Anwendung.
		/// </summary>
		[STAThread]
		private static void Main()
		{
			Application.EnableVisualStyles();
			Application.SetCompatibleTextRenderingDefault(false);

			_trayIcon = new NotifyIcon {Icon = Icon.FromHandle(new Bitmap("Gear.png").GetHicon()), Visible = true};
			_trayIcon.Click += TrayIconClick;

			Application.Run();
			_trayIcon.Dispose();
		}

Im Anhang findet ihr eine Beispielsolution. Wichtig ist, dass ihr euch selbst ums Dispose() kümmern müsst, damit etwa das NotifyIcon aus der Taskleiste verschwindet, sobald die Applikation beendet wird. Das Beispiel öffnet beim Klick auf das NotifyIcon eine leere Form. Wird diese geschlossen, wird das ganze Programm beendet.

Download: Beispiel Solution – Start App With Notify Icon

Wie bringe ich mich selbst zum Kommentieren meines Codes?

Man ist ja selbst etwas faul. Meist weiß man, was sein Code so macht (oder besser machen sollte) und man kommentiert daher nur sehr sporadisch. Wenn man den Code dann eine Weile später wieder zur Hand nimmt, fällt es einem oft schwer seinen alten Code zu verstehen.
Daher gibt es Kommentare, in C# in Form des „<summary>„-Tags. Drei Slashes und Visual Studio fügt schon automatisch das Grundgerüst ein.
Damit nun auch wirklich jede public / internal Methode / Property kommentiert wird, muss man den Kompiler sagen, dass er fehlende Summaries als Fehler an erkennen soll.

Dazu geht ihr in die Projekteigenschaften und aktiviert unter dem Reiter „Erstellen“ den Hacken bei „XML-Dokumentationsdatei“. Nun erstellt er euch aus den Kommentaren bei jedem Build eine solche XML-Datei. Im Editor wird nun auch schon angemeckert, dass die XML-Kommentare fehlen. Um euch nun wirklich zu zwingen, sollte die Solution gar nicht erst gebaut werden, wenn die Kommentare fehlen. Das Fehlen wird als Warning gemeldet, daher sagen wir den Kompiler einfach, er soll Warnings als Fehler behandeln.
Dies geschieht ebenfalls in den Projekteigenschaften unter „Erstellen“. Evtl. kann man das noch verfeinern, indem man nur bestimmte Warnungen als Fehler behandelt, jedoch konnte ich auf die schnelle keine entsprechenden Informationen dazu finden. Ich versuche diese nachzureichen.

Von nun an lässt sich die Solution also nicht mehr kompilieren, sofern nicht überall Kommentare verfasst wurden. Um sich das Leben an dieser Stelle deutlich einfacher zu machen, empfehle ich die kostenlose Visual Studio Erweiterung GhostDoc. Mit ihr könnt ihr per Rechtsklick oder Tastenkombination eure Methode oder Property kommentieren. Dabei werden zum Beispiel schon vorhandene Kommentare aus Interfaces über Überladungen übernommen. Ansonsten erstellt er anhand des Methodennamen eine entsprechende Dokumentation. Man kann sich auch eigene Templates anlegen (habe ich mir sagen lassen). Gebündelt mit einem ordentlichen Programmierstil (bei der Namensgebung) kann man so bestimmt 80% automatisch kommentieren. Eine unglaubliche Zeitersparnis.

WinMerge mit AnkhSVN nutzen

Sollte jemand von euch AnkhSVN in Visual Studio nutzen und ihr möchtet eure Dateien mit WinMerge vergleichen oder mergen, dann müsst ihr unter Optionen -> Source Control -> Subversion User Tools folgende Befehle angeben

C:\Program Files (x86)\WinMerge\WinMergeU.exe /x /e /wl /ub /dl "$(BaseName)" /dr "$(MineName)" "$(Base)" "$(Mine)"

C:\Program Files (x86)\WinMerge\WinMergeU.exe /x /e /wl /ub /dl "$(TheirName)" /dr "$(MineName)" "$(Theirs)" "$(Mine)" "$(Merged)"

Den Merge-Befehl (der zweite) habe ich noch nicht getestet. Wichtig ist, dass die Anführungszeichen setzt. Sonst gibt es Probleme bei Leerzeichen und WinMerge will irgendwelche Verzeichnisse anstatt Dateien öffnen.

C#4.0 – Problematik bei Default Values

Golo Roden erwähnte es bereits in den Kommentaren, daher möchte ich noch mal genauer darauf eingehen.
Dazu erstelle ich eine Solution in Visual Studio 2010 mit einer Konsolenapplikation, welche ich „DefaultValues“ nenne. C#4.0 – Problematik bei Default Values weiterlesen

Boolschen Rückgabewert einer Stored Procedures in C#

Ich hatte mir eine Stored Procedure erstellt, welche überprüft, ob es schon einen bestimmten Eintrag in der Datenbank gibt. Sie sollte mir also nur ein true oder false zurück liefern.

ALTER PROCEDURE dbo.LineExists	
	(
	@name nvarchar(100)	
	)	
AS BEGIN
	IF(EXISTS(Select [Name] FROM DemoTable WHERE [Name] = @name))
		RETURN(1)
	ELSE
		RETURN(0)
END

Meine passende C# Funktion sah in etwa so aus:

SqlConnection sqlConn = new SqlConnection(this.connstring);
SqlCommand sqlCom = new SqlCommand("LineExists", sqlConn);
sqlCom.CommandType = CommandType.StoredProcedure;
sqlCom.Parameters.Add("@name", SqlDbType.NVarChar).Value = "TestLeine";

sqlConn.Open();
bool vorhanden = ((int)sqlCom.ExecuteScalar() == 1) ? true:false;

Das führte immer zu einer Null-Reference-Exception. Auch der Weg über einen SqlDataReader funktionierte nicht. Eine Möglichkeit wäre, die Stored Procedure anzupassen und statt „Return(0)“ „Select 0“ zurück zu geben. Dann würde der obere Code auf jeden Fall funktionieren.

Andere Möglichkeit wäre, den Return Value auszulesen. Dazu muss man dem SqlCommand einen Parameter mitgeben, welchen ihr nach der SQL Operation wieder auslest. Kurzes Code-Beispiel:

SqlConnection sqlConn = new SqlConnection(this.connstring);
SqlCommand sqlCom = new SqlCommand("LineExists", sqlConn);
sqlCom.CommandType = CommandType.StoredProcedure;
sqlCom.Parameters.Add("@name", SqlDbType.NVarChar).Value = "TestLeine";
sqlCom.Parameters.Add("RETURN_VALUE", SqlDbType.Int).Direction = ParameterDirection.ReturnValue;

sqlConn.Open();
sqlCom.ExecuteNonQuery();
bool vorhanden = ((int)sqlCom.Parameters["RETURN_VALUE"].Value == 1) ? true:false;

Beide liefern das selbe Ergebnis. Pro oder Contra habe ich bei einer spontanen Google-Recherche nicht gefunden, ist sicherlich Geschmackssache.