Freitag, 24. Juni 2011

Installierte Versionen des .Net-Framework ermitteln unter Windows Mobile

Heute hatte ich das Problem, dass ich eine kleine Testanwendung schreiben wollte die auf einem Windows Mobile und einem Windows CE Gerät laufen sollte. Einzige Voraussetzung war, dass kein neues .Net Framework bzw. Compact Framework installiert werden darf.

Da es sich bei dem einen Gerät um das Betriebssystem Windows CE 5.0 handelt, kommen für die Entwicklung erst einmal 2 Framework-Versionen in Frage. Und zwar hat die Version 5.0 standardmäßig das .Net-Framework 1.0 installiert. Handelt es sich jedoch um die Version 5.0 mit installiertem Service Pack 2, so ist auch das .Net-Framework 2.0 eingerichtet.

Wie bekommt man nur einfach raus, welches das aktuell höchste, vorhandene .Net-Framework ist.
Hierzu gibt es eigentlich zwei ganz einfache Methoden.

1. Im Windows-Verzeichnis befindet sich eine Datei mit dem Namen "cgacutil.exe". Wenn man diese einfach ausführt, bekommt man alle installierten .Net-Frameworks, sortiert von alt nach neu, aufgelistet.
Der letzte Eintrag ist also die höchste installierte Version.

2. Sollte die unter Punkt 1 beschriebene Datei aus irgendwelchen Gründen nicht aufrufbar sein, so kann man sich auch einen Registry-Editor zur Hilfe ziehen. Diesen installiert man auf dem PC und greift von dort aus auf das angeschlossene mobile Gerät zu.
Aus dem Editor geht man dann in der Registry unter folgenden Eintrag:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP
Hier werden alle installierten Versionen des .Net-Frameworks in Unterverzeichnissen aufgelistet.

Mittwoch, 22. Juni 2011

Zugriff aus .Net auf SQLite Datenbanken

In meinem letzten Beitrag habe ich mich ja mit einem universellen Datenbank-Browser für Mac OS und Windows beschäftigt. Dieses war mir auch sehr wichtig, da man so recht schnell Datenbanken erstellen, mit ersten Testdaten füllen und später die richtigen Daten gut prüfen kann.

Jetzt möchte ich aber den eigentlich interessanteren Teil ansprechen. Den Datenzugriff aus .Net auf eine SQLite-Datenbank.

In folgendem Beispiel möchte ich zeigen, wie man per C#-Code eine SQLite-Datenbank erstellt, eine Tabelle anlegt und diese mit Daten befüllt.


// Datenbanknamen angeben
string dataBaseName = "Maschinen.db";

// Connection-Objekt instanziieren
SQLiteConnection connection = new SQLiteConnection();

// Datenbankdatei erstellen (inkl. Standarddatenbank "main")
SQLiteConnection.CreateFile(dataBaseName);

// Connection-String für die Verbindung erstellen
connection.ConnectionString = "Data Source=" + dataBaseName;

// Verbindung zur Datenbank erstellen
connection.Open();

// Command-Objekt instanziieren um SQL-Statements auszuführen
SQLiteCommand command = new SQLiteCommand(connection);

// SQL-Statement ohne Parameter erstellen und ausführen
command.CommandText = "CREATE TABLE Maschinen(Id INTEGER PRIMARY KEY, Name VARCHAR(255), Typ VARCHAR(255));";
command.ExecuteNonQuery();

// SQL-Statement mit Parametern erstellen
command.CommandText = "INSERT INTO Maschinen VALUES (@Id, @Name, @Typ);";

// Command-Objekt mit Parametern füllen
command.Parameters.Add(new SQLiteParameter("@Id", 1));
command.Parameters.Add(new SQLiteParameter("@Name", "Maschine1"));
command.Parameters.Add(new SQLiteParameter("@Typ", "Typ1"));

// SQL-Statement mit Parametern ausführen
command.ExecuteNonQuery();

// Parameter aus Command-Objekt wieder entfernen
command.Parameters.Clear();

// Command-Objekt wieder freigeben
command.Dispose();

// Verbindung zur Datenbank schliessen
connection.Close();

Dienstag, 21. Juni 2011

SQLite Datenbank-Browser für Mac und Windows

Da ich momentan viel parallel mit Windows und Mac OS arbeite und auch bei kleineren Projekten oft SQLite-Datenbanken verwende, habe ich einen Datenbank-Browser gesucht, der unter beiden Plattformen läuft.

Bei der Suche bin ich über interessante Clients gestolpert, die auch wirklich gut waren. Viele sind aber entweder für Mac OS oder für Windows gewesen. Letztendlich bin ich bei einen Open Source Tool hängen geblieben. Dieses trägt den Namen "SQLite Database Browser" und ist zu finden unter folgendem Link.
http://sqlitebrowser.sourceforge.net/

SQLite Database Browser unter Mac OS

Dieses Tool ist zwar grafisch nicht sehr anspruchsvoll, aber das muss ein Datenbank-Browser meiner Meinung nach auch nicht sein. Man kann mit ihm alle Grundfunktionalitäten abdecken wie zum Beispiel:
- Neue Datenbanken erstellen
- Bestehende Datenbanken einlesen (Daten sowie Struktur anzeigen)
- Strukturen verändern (Tabellen und Indizes erstellen, ändern und löschen)
- SQL-Abfragen ausführen

Dienstag, 14. Juni 2011

Versionierung in .Net - Assembly Version setzen und auslesen

Wie ist eine Versionsnummer aufgebaut?
Eine Versionsnummer sieht z. B. so aus: 1.6.34.55
Diese Werte stehen standardmäßig für folgende Werte: Major Version, Minor Version, Build Number, Revision.

Wie kann man einfach und schnell eine .Net-Applikation mit einer Versionsnummer versehen?

Dieses kann man ganz einfach realisieren indem man die AssemblyInfo.cs anpasst. Die Datei enthält standardmäßig folgende Codezeile:
[assembly: AssemblyVersion("1.0.0.0")] 

Hier könnte man nun manuell eine neue Versionsnummer eintragen wie zum Beispiel folgende:
[assembly: AssemblyVersion("1.1.3.7")]

Da dieses aber aus der Erfahrung heraus in den meisten Fällen regelmäßig vergessen wird, wäre es doch sinnvoll, wenn sich die Versionsnummer automatisch erhöht wird.

Um dieses einfach, schnell und ohne viel Aufwand realisieren zu können, kann man die Zeile wie folgt anpassen.
[assembly: AssemblyVersion("1.0.*")]

Somit werden die letzten beiden Werte (Build Number und Revision) automatisch inkrementell erhöht.

Das Auslesen der aktuellen Versionsnummer ist genauso einfach. Dieses funktioniert mit folgender Zeile Code:
System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()

Donnerstag, 14. Oktober 2010

Trotz wenig Zeit endlich wieder bloggen.

Viele kennen das Problem des Zeitmangels. Und mittlerweile wird meistens einfach kurz etwas getwittert anstatt Informationen mittels eines zeitaufwendigeren Blogeintrags weiterzugeben. Viele Blogs die ich regelmäßig gelesen habe, bloggen nur noch wenig regelmäßig bis gar nicht mehr. Auch bei mir ist der letzte Eintrag mittlerweile schon fast ein Jahr alt. Dieses möchte ich aber in Zukunft wieder ändern. Ich habe mir vorgenommen regelmäßig kleinere Tipps & Tricks zu posten um dem ein oder anderen .Net-Neuling beim Einstieg etwas unter die Arme zu greifen.

Donnerstag, 17. Dezember 2009

"Timeout abgelaufen" bei Abfrage des Verbindungsservers

Kürzlich hatte ich das Problem, dass alle meine Abfragen gegen einen Verbindungsserver auf ein Timeout liefen. Es hat sich hierbei um einen Datenabgleich zwischen zwei Datenbanken auf unterschiedlichen Servern gehandelt. Den einen Server (S2) habe ich zuvor als Verbindungsserver auf dem anderen (S1) eingerichtet. Danach habe ich auf dem Server S1 folgendes SQL-Statement ausgeführt.

Statement:
INSERT INTO dbo.NeueTabelle
SELECT * FROM [Server2].[DatenbankAlt].[dbo].AlteTabelle
WHERE ID NOT IN (SELECT ID FROM dbo.NeueTabelle)
AND Imei IN (SELECT Imei FROM dbo.VertragsTabelle)
AND Erstellungsdatum > '29.11.2009 00:00:00'

Datenmengen:
Quelltabelle (AlteTabelle) = 60 Mio.
Zieltabelle (NeueTabelle) = 55 Mio.

Nach kurzer Zeit des Wartens wurde mir dann folgende Fehlermeldung ausgeworfen:
Der OLE DB-Anbieter 'SQLNCLI10' für den Verbindungsserver 'Server2' hat die Meldung 'Abfragetimeout abgelaufen' zurückgeben.
Meldung 7399, Ebene 16, Status 1, Zeile 4
Der OLE DB-Anbieter 'SQLNCLI10' für den Verbindungsserver 'Server2' hat einen Fehler gemeldet. Die Ausführung wurde vom Anbieter beendet, da ein Ressourcenlimit erreicht wurde.
Meldung 7421, Ebene 16, Status 2, Zeile 4
Das Rowset kann nicht vom OLE DB-Anbieter 'SQLNCLI10' für den Verbindungsserver 'Server2' abgerufen werden.

Abhilfe:
Da bei mir sichergestellt ist, dass das Statement nur einmalig läuft und nach Beendigung das Timeout wieder gesetzt werden kann, habe ich dieses kurzfirstig wie folgt deaktiviert bzw. auf unbegrenzt gesetzt.

Remote Login Timeout mithilfe dieses Codes auf 30 Sekunden festlegen:
sp_configure 'remote login timeout', 30
go
reconfigure with override
go

Remote Query Timeout auf 0 (unbegrenztes Warten) mithilfe dieser Code festgelegt wird:
sp_configure 'remote query timeout', 0
go
reconfigure with override
go

Donnerstag, 3. Dezember 2009

SQL-Statements blockweise verarbeiten und somit Tablelocks verhindern

Wenn man mit großen Datenmengen arbeiten muss und Abfragen viel Last erzeugen oder sogar komplette Tabellen sperren, so kann man dieses umgehen indem man die Daten blockweise verarbeitet. Hierzu gibt es einen einfachen Trick.

1. SET ROWCOUNT 500
2. insert_more:
3. INSERT INTO dbo.TabelleZiel
4. SELECT * FROM [TestDB].[dbo].TabelleQuelle
5. WHERE ID NOT IN (SELECT ID FROM dbo.TabelleZiel)
6. AND ErstellDatum > '29.11.2009 00:00:00'
7. IF @@ROWCOUNT > 0 GOTO insert_more
8. SET ROWCOUNT 0

Mit dem Befehl RowCount legt man die pro Block zu verarbeitende Anzahl an Datensätzen fest.
Hier ist es wichtig einen geeigneten Wert zu finden. Sollte man die Blöcke zu groß einstellen, so wird doch wieder die komplette Tabelle gesperrt. 500 Datensätze ist hier schon ein gängiger Wert, welcher eigentlich immer verwendet werden kann.

Im Beispiel sieht man eine Goto-Schleife zwischen Zeile 2 und 7.
zwischen diesen Zeilen kann man dann das auszuführende Statement eintagen.
Das Beispiel zeigt ein umfangreicheres Insert. Hier könnte genauso gut ein einfaches Delete stehen.

Wichtig ist auch, dass nach der Verarbeitung die Blockverarbeitung wieder deaktiviert wird.
Dieses geschieht in Zeile 8. Der Wert 0 steht für eine unbegranzte Menge an Datensätzen.

Die Blockverarbeitung ist etwas langsamer als die direkte Komplettverarbeitung. Jedoch ist sie Ressourcen schonender und erzeugt keine Table-Locks.