Blog Home  Home Feed your aggregator (RSS 2.0)  
Peter Nowaks Mobile Blog - Thursday, July 05, 2007
Mobility on the Run
 
 Thursday, July 05, 2007

Hach, es ist einfach herrlich mit dem .NET Compact Framework zu arbeiten. Zugegeben, es ist manchmal müssig, da man nicht den Komfort genießt, den Programmierer mit dem .NET Framework zu Teil wird. Dafür, so finde ich, ist man viel näher an der Materie, wenn sich das eine oder andere selbst erstellen muss. Man kann so viel tiefer in die Materie eindringen.

Doch dies hat auch seine Schattenseiten, denn wenn man schon bei seinen Möglichkeiten eingeschränkt ist, so sollte man auch erwarten, daß zumindest diese Einschränkungen unterstützt werden.
So mag ich einfach nicht verstehen wollen, warum die im .NET 2.0 vorhandene Komprimierung nicht auch vom .NET Compact Framework unterstützt wird. Dabei unterstützt doch gerade das HTTP Protokoll in der Version 1.1 bereits die Komprimierung vom Protokoll her.

Gerade bei mobiler Datenkommunikation wäre es doch sinnvoll, insbesondere wenn es um Geschäftsanwendungen geht, Daten zu reduzieren:

  • Mobile Geräte besitzen meist nur (sofern keine weiteren Speicherkarten verwendet werden) einige wenige MB an freiem Arbeitsspeicher
  • Daten werden meist immer noch mittels schmalbandiger und nicht unbedingt günstiger GPRS-Verbindung ausgetauscht. Bei einigen MB an Daten kann es sich bereits daher schon lohnen eine Kompression einzusetzen.

Die genaue Kompressionsrate bei einem ZIP-Algorithmus lässt sich nicht genau definieren. Dies ist von den zu komprimierenden Daten abhängig. Generell lässt sich jedoch sagen, daß eine Kompression von ca. 50% - 60% real ist.

Natürlich muss man dabei auch in Kauf nehmen, daß durch Komprimierung die Performance einer Anwendung leidet, da der Prozess zur Komprimierung und Dekomprimierung ziemlich speicher- und prozessorintensiv ist.

Somit wird ein komprimierter Datenaustausch zwischen mobilen Client und Server nicht wirklich schneller, da die gewonnene Zeit hierbei für durch die Kompression/Dekompression verloren geht. Man spart jedoch Speicherplatz und ggfs. ein wenig Geld.

Nachfolgend wird daher dargestellt, wie sich diese fehlende Funktionalität nachrüsten lässt.

Teil 1: Der Server

Zu allererst ist es nötig dem Webanwendung / dem WebService die Komprimierung "beizubringen", respektive die Komprimierung im Webserver für aspx, asmx und Co zu aktivieren.
Dabei wird der ASP.NET Development Server ausser acht gelassen, da dieser für das hier beschrieben Szenario ungeeignet ist. Dieser unterstützt nämlich keinen Zugriff "von aussen" und kann daher nur Anfragen von localhost verarbeiten, was bei der mobilen Entwicklung leider nicht weiterhilft.

Möglichkeit 1: IIS 6 Komprimierung aktivieren.

Dieser englischsprachige Artikel beschreibt, wie die bereits im IIS 6 vorhandene Komprimierung für dynamische Inhalte (aspx, asmx und asp) aktiviert werden kann.
Vorteil: Alle auf dem Server befindlichen Webanwendungen und -dienste können von der Komprimierung profitieren. Werden jedoch einige dieser Webdienste von .NET Compact Framework Anwendungen verwendet, die diese Komprimierung nicht verstehen, kann dies u.U. böse Folgen nach sich ziehen.
Nachteil: Man benötigt einen entsprechenden Remotezugriff auf den Server, um diese Einstellung ermöglichen zu können. Weiterhin sollte man mit der Materie schon ein wenig vertraut sein.

Möglichkeit 2: anwendungsbasierte Komprimierung

Neben der zuvor beschriebenen Möglichkeit ist es auch möglich, lediglich für die entsprechende Webanwendung / den entsprechenden WebService eine Komprimierung zu verwenden.
Vorteil: Es sind keine Modifikationen an der Serveranwendung nötig, d.h. sie braucht nicht erneut kompiliert zu werden. Es reichen einfach einige Konfigurationsänderungen an der web.config und ein paar zusätzliche DLLs. Ein weiterer Vorteil ist, daß alle anderen Webanwendungen / WebServices auf dem gleichen Webserver hiervon unberührt bleiben.

Um dies zu ermöglichen verwenden Sie bspw. das HttpCompressionModule von blowery.org. Sie erhalten es dort sowohl für ASP.NET 2.0, als auch für ASP.NET 1.1 jeweils als Sourcecode, oder als bereits vorkompilierte Bibliotheken. Dabei gilt zu beachten, daß unter ASP.NET 2.0 System.IO.Compression zur Komprimierung verwendet wird, während unter ASP.NET 1.1 die Kompressionsbibliothek SharpZipLib verwendet wird. Hierzu jedoch später mehr.

Das HttpCompressionModule agiert als so genanntes HTTP Modul. Dieses verändert Daten entweder beim Empfang oder jedoch beim Versenden. In unserem Fall geschieht dies beim Versenden. Hierzu wird das unterstützte Encoding beim Empfang ermittelt, und, sofern der GZip- oder Deflate-Komprimierungsalgorithmus vom Client unterstützt wird, die Antwort vor dem Versenden an den Client noch mal durch einen Filter (also dem HTTP Modul) komprimiert.

Um HttpCompressionModule in Ihrer Webanwendung zu nutzen, entpacken Sie bitte folgende Dateien in das bin-Verzeichnis der Webanwendung / des WebServices aus dem heruntergeladenen Archiv:

  • blowery.Web.HttpCompress.dll
  • blowery.Web.HttpCompress.xml
  • ICSharpCode.SharpZipLib.dll
  • ICSharpCode.SharpZipLib.xml

Diese Dateien befinden sich im Verzeichnis "Example\bin" des genannten Archivs.

Danach editieren Sie bitte die web.config der Webanwendung / des WebServices um folgende Einträge:

  • Im Abschnitt <configuration> fügen Sie bitte den folgenden Inhalt hinzu:
    <!-- This chunk sets up the configuration section handler for blowery.webmodules/ -->
      <configSections>
        <sectionGroup name="blowery.web">
          <section name="httpCompress" type="blowery.Web.HttpCompress.SectionHandler, blowery.Web.HttpCompress"/>
        </sectionGroup>
      </configSections>
     
      <!-- config section for my http module -->
      
      <blowery.web>
        <!-- ...Here's an example on how to change the algorithm or compressionlevel...
          <compressionModule preferredAlgorithm="deflate|gzip" compressionLevel="high|normal|low"/>
    ...so, to use deflate by default, and high compression, you have to set the following line
    ...-->
        <httpCompress preferredAlgorithm="gzip" compressionLevel="high">
          <excludedMimeTypes>
            <add type="image/jpeg"/>
            <add type="image/gif"/>
          </excludedMimeTypes>
          <excludedPaths>
            <add path="NoCompress.aspx"/>
          </excludedPaths>
        </httpCompress>
      </blowery.web>
  • Im Abschnitt <system.web> fügen Sie bitte noch folgendes hinzu:
        <httpModules>
          <add name="CompressionModule" type="blowery.Web.HttpCompress.HttpModule, blowery.web.HttpCompress"/>
        </httpModules>

Ggfs. ist noch ein Neustart des Webservers nötig, den Sie beispielsweise leicht mittels auf der Kommandozeile ausgeführten Kommando "iisreset" durchführen können.

Der erste dargestellte Abschnitt beschreibt die sectionGroup, welche von HTTPCompress verwendet wird. In dieser Sektion ("<blowery.web>") werden die Konfigurationseinstellungen für die Komprimierung definiert. Dabei ist sowohl der Komprimierungsalgorithmus (gzip oder deflate), als auch die Komprimierungsstärke (high, normal oder low) verwendbar.

Der zweite Konfigurationsabschnitt in "<system.web>" macht ASP.NET gegenüber dieses HTTP Modul bekannt, so daß es verwendet werden kann.

Teil 2: Testen der serverseitigen Komprimierung

Wenn Sie testen möchten, ob Ihr Daten nun korrekterweise komprimiert versendet werden, verwenden Sie doch einfach das kostenfreie und erweiterbare Microsoft Tool Fiddler.
Bei diesem Tool handelt es sich um einen HTTP Proxy (auch HTTP Debugging Proxy genannt), welcher sehr häufig von Webentwicklern eingesetzt wird. HTTP Proxy bedeutet in diesem Fall, das die über diesen Dienst durchgeschleust und aufgezeichnet wird. Dieser HTTP Proxy wird in den Proxyeinstellungen des lokalem Webbrowsers eingetragen. War hier zuvor bereits ein Proxy eingetragen, so wird diese vom HTTP Proxy übernommen, so daß die Kommunikation weiter wie gewohnt erfolgt.

Dieser HTTP Proxy ist jedoch nicht nur auf den Webbrowser beschränkt. Werden die Einstellungen in andere proxyfähige Anwendungen eingetragen, so kann diese Kommunikation mit aufgezeichnet werden.

Für .NET Anwendungen ist dies im Regelfall nicht nötig, da diese die Einstellungen des Internet Explorers übernehmen, wenn nicht anders definiert.

Fiddler ist jedoch nicht nur auf lokale HTTP Einstellungen beschränkt. Dies ist nur die Standardeinstellung. Durch eine Option kann dieser Proxy auch vom Netzwerk aus angesprochen werden. Somit ist es dann bspw. möglich Anfragen von Windows Mobile Anwendung mit zu protokollieren.

 

Um die HTTP-Kommunikation vom Windows Mobile Gerät über den Proxy zu aktivieren, muss dieser auch in Windows Mobile eingestellt werden und Fiddler hierzu ausgeführt werden. Wird Fiddler nicht ausgeführt, so kommt es zu Fehlern in Ihrer mobilen Anwendung.
Hierzu aktivieren Sie bitte den Punkt Verbindungen unter Start->Einstellungen auf dem Karteireiter Verbindungen. Wählen Sie dort dann unter dem Punkt Firmennetzwerk den Eintrag Proxyserver einrichten. Ist bereits ein Proxy eingetragen, so wählen Sie stattdessen Proxyserver bearbeiten aus.
Aktivieren Sie dann beide dargestellten Häckchen. Unter Proxyserver tragen Sie die IP-Adresse des Computers ein, auf welchem Fiddler ausgeführt wird (Beispiel: 192.168.0.5).
Wählen Sie danach die Schaltfläche Erweitert... aus. Aktivieren Sie nun im neu erscheinenden Dialog den Eintrag beginnend mit HTTP. Tragen Sie im erscheinenden Dialog im Punkt Anschluss die Portadresse von Fiddler ein. Der Standardwert ist normalerweise 8888.

Wenn Sie dieses Tool installiert haben und es aufrufen, wird normalerweise die HTTP Kommunikation bereits mitprotokolliert. Alternativ können Sie die Protokollierung mittels "F12" aktivieren/deaktivieren.

Rufen Sie in Ihrem Webbrowser die gewünschte ASMX-Seite / ASPX Seite auf, So sehen Sie bei einem Doppelklick auf den entsprechenden Eintrag bereits, ob die Antworten des Webservers komprimiert werden.

(Kommunikation ist nicht komprimiert)

(Kommunikation ist komprimiert)

Darüber hinaus können Sie sich in den entsprechenden Karteireitern die Daten ansehen, welche ausgetauscht werden. Sollten diese komprimiert sein, so kann Fiddler diese auch dekomprimiert darstellen.

Teil 3: Der Client

Der nachfolgend beschriebene Teil basiert auf einem englischsprachigen Artikel der Flow Group, hat aber im Gegensatz dazu einige Vorteile:

  • Anstatt ein Pseudoprotokoll zu verwenden (zHttp), wird hier das reguläre Http Protokoll verwendet. Vorteil hierbei ist, daß in der zur verwendenden Anwendung keine Modifikationen nötig sind und weiterhin das Http Protokoll funktional weiterverwendet werden kann. Es wird lediglich eine Zeile Code in der Anwendung selbst benötigt.
  • Es wurde darauf wert gelegt, daß die Implementation hierbei eher dem Designguide des WebRequest folgt.

Bevor wir jedoch hierzu kommen fangen wir lieber von Vorne an.

Um eine Komprimierung zu ermöglichen benötigt man Klassen oder eine Bibliothek, welche diese Aufgaben übernimmt. Hierfür gibt es lediglich 2 Möglichkeiten: SharpZipLib und zlibCE von OpenNETCF. Welche Bibliothek Sie letztlich verwenden, bleibt Ihnen überlassen.
Ich habe mich für die SharpZipLib Bibliothek entschieden. Dies hat einige Gründe:

  1. zlibCE ist nativ entwickelt worden und bietet zusätzlich einen Wrapper für das .NET Compact Framework, während die SharpZipLib komplett in C# erstellt worden ist. Dabei gilt jedoch zu beachten, daß zlibCE vermutlich schneller ist (Dies werde ich zu einem späteren Zeitpunkt testen).
  2. SharpZipLib ist neuerdings direkt für das .NET Compact Framework vorhanden
  3. zlibCE ist noch ziemlich neu, während SharpZipLib sich bereits bewährt hat.
  4. SharpZipLib unterstützt den Zip- und Deflate-Algorithmus und besitzt dazu noch einige weitere Funktionen. zlibCE unterstützt lediglich den Zip-Algorithmus.

Nachdem nun also bereits eine Komprimierungsbibliothek vorhanden ist, gilt es diese zu implementieren. Wie die Komprimierungsbibliothek für diesen Zweck zu verwenden ist, erfahren Sie im folgenden Abschnitt.

Das folgende Schaubild zeigt die Abhängigkeiten von SoapHttpClientProtocolWebRequest und WebResponse, aus denen u.a. eine WebService-Referenz besteht.

Wie Sie sehen, verwendet die abstrakte Klasse SoapHttpClientProtocol intern die Klassen WebRequest und WebResponse (leider nicht im Schaubild darstellbar).
Da die komprimierten Daten mittels der Methode GetResponseStream() der Klasse WebResponse zurückgegeben werden ist es sinnvoll an dieser Stelle anzusetzen. Somit gilt es also eine Proxyklasse für die Klasse WebResponse zu erstellen und die Methode GetResponseStream() zu überschreiben.
Damit diese Methode jedoch auch den dekomprimierten Stream zurückgibt ist es dementsprechend nötig auch die Klasse WebRequest zu überschreiben. Diese liefert nämlich mittels GetResponse ein Objekt der Instanz WebResponse zurück.

.
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;

namespace NetCompressionLibrary
{
    public class CompressedHTTPWebResponse:System.Net.WebResponse
    {
        // Create Proxy object
        private HttpWebResponse response;
        private System.Uri uri;

        internal CompressedHTTPWebResponse(WebRequest request, System.Uri uri)
        {
            this.uri = uri;
            response = (HttpWebResponse)request.GetResponse();
        }
        public override System.IO.Stream GetResponseStream()
        {
            if (response.ContentEncoding == "gzip")
            {
                return new GZipInputStream(response.GetResponseStream());
            }
            else if (response.ContentEncoding == "deflate")
            {
                return new InflaterInputStream(response.GetResponseStream());
            }
            else
            {
                return response.GetResponseStream();
            }
        }
        public override void Close()
        {
            response.Close();
        }

        public override System.Uri ResponseUri
        {
            get
            {
                return uri;
            }
        }
    }
}

Die Klasse CompressedHTTPWebResponse leitet somit von der abstrakten Klasse WebResponse ab.

Sie erhält zusätzlich eine Variable vom Typ HttpWebResponse, da unsere Klasse als eine Schale hierfür dienen soll. HttpWebRequest ist hierbei der Handler für HTTP Anfragen aus dem .NET (Compact) Framework heraus.

Wir wollen ja eigentlich auch nur die Methode GetResponseStream() überschreiben. Intern wird jedoch alles weitere auf die intern verwendete Variable response vom Typ HttpWebResponse weitergeleitet.

Damit in der überschriebenen Methode auch die Komprimierung verwendet werden kann, muss dem Projekt die Assembly ICSharpCode.SharpZipLib.dll hinzugefügt werden. Sie finden diese im heruntergeladenen Archiv von SharpZipLib im Ordner "SharpZipLib_0852_BinDoc\current\netcf-20".

Zusätzlich benötigen sie die beiden using Statements using ICSharpCode.SharpZipLib.GZip; und using ICSharpCode.SharpZipLib.Zip.Compression.Streams; , damit Sie die Klassen zur Komprimierung einfacher in Ihrer Klasse verwenden können.

Bevor Sie die Dekomprimierung verwenden, prüfen Sie auf das ContentEncoding des verwendeten Objektes response. Hier ist die Information enthalten, ob die erhaltenen Daten komprimiert sind, respektive, wie diese komprimiert wurden. Wird keine Komprimierung verwendet, so wird der ResponseStream von response einfach 1:1 zurückgegeben und ermöglicht so die Klasse als Standardklasse für HTTP-Kommunikation anstatt HttpWebRequest zu verwenden.
Wird die GZip-Komprimierung durch den Webserver verwendet (ContentEncoding == "gzip"), so wird um den ResponseStream noch der GZipInputStream gelegt, welcher die Daten beim Abfragen direkt dekomprimiert. Analog geschieht dies beim Deflate-Algorithmus (ContentEncoding == "deflate") mit dem InflaterInputStream.

Wie bereits beschrieben ist für die korrekte Verwendung von CompressedHTTPWebResponse auch analog eine Ableitung der Klasse WebRequest nötig.

.
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;

namespace NetCompressionLibrary
{

    public class CompressedHTTPWebRequest : System.Net.WebRequest
    {
        private HttpWebRequest request;
        private System.Uri uri;

        private CompressedHTTPWebRequest(System.Uri uri)
        {
            this.uri = uri;
            request = (HttpWebRequest)WebRequest.Create(uri);
            request.Headers.Add("Accept-Encoding", "gzip, deflate");
        }
        
        public override System.Net.WebResponse GetResponse()
        {
            CompressedHTTPWebResponse response = new CompressedHTTPWebResponse(request,uri);
            return (WebResponse)response;
        }
        ...

        /// <summary>
        /// Creates a CompressedWebRequest object for doing compressed HTTP Communication
        /// </summary>
        /// <param name="uri">The URI of the WebService</param>
        /// <returns></returns>
        public static CompressedHTTPWebRequest Create(Uri uri)
        {
            return new CompressedHTTPWebRequest(uri);
        }
    }
}

Hier sehen Sie, daß analog zu CompressedHTTPWebResponse auch diese Klasse eine Schale (Proxyklasse) für HttpWebRequest darstellt. Hier wird daher ebenfalls ein Objekt vom Typ HttpWebRequest erstellt, an welches alle Anfragen weitergeleitet werden (die hier dargestellte Klasse ist lediglich die Minimalimplementation. Das im Anhang beigefügte Archiv ist eine Vollimplementation).

Damit man also komprimierte Daten anfordern kann ist es nötig dem verwendeten HttpWebRequest einen Header beizufügen, der dem Webserver gegenüber erklärt, daß die Komprimierung unterstützt wird.

Um jedoch auch die CompressedHTTPWebResponse zu erhalten, ist es nötig die Methode GetResponse() zu überschreiben.

Die statische Methode Create erzeugt konform zum WebRequest jeweils ein Objekt vom Typ CompressedHTTPWebRequest und gibt diesen zurück.

Mit diesen beiden Klassen ist es bereits möglich Daten mittels HTTP Kommunikation auszutauschen. Das folgende Beispiel zeigt, wie dies geht.

Teil 3.1: Abfragen komprimierter Daten mittels CompressedHTTPWebRequest

Versuchen Sie es doch nun einmal, mit diesen neuen Klassen eine Verbindung mit bspw. der URL http://msdn.microsoft.com.
.
            ...
            CompressedHTTPWebRequest wr = CompressedHTTPWebRequest.Create(http://msdn.microsoft.com);
            StreamReader sr = new StreamReader(wr.GetResponse().GetResponseStream());
            MessageBox.Show(sr.ReadToEnd());
            ...

Wenn Sie die Methode CompressedHTTPWebResponse debuggen, werden Sie sehen, daß die Seite mit komprimierten Daten geantwortet hat.

Was noch als letztes fehlt ist die Verwendung dieser Klassen innerhalb der WebService-Referenz.

Teil 3.2: komprimierte Datenkommunikation mit WebServices

Wie ist es nun aber möglich WebService-Referenz, bzw. der Klasse SoapHttpClientProtocol beizubringen, die neuen Klassen CompressedHTTPWebRequest und CompressedHTTPWebResponse intern zu verwenden. Sie leiten ja von WebRequest und WebResponse ab. Also sollte dies möglich sein.

Nun könnte man ja auf die Idee kommen und die Klasse SoapHttpClientProtocol zu überschreiben. Dies wäre jedoch viel zu aufwändig und ist auch gar nicht nötig.

Viel sinnvoller wäre es doch, genauso wie bereits beim HTTP-Handler auf der Serverseite den HTTP-Handler für die komprimierten Daten auf der Clientseite zu verwenden. Hierzu müsste lediglich der Standardhandler für HTTP deregistriert und unser Handler registriert werden.

Dies geschieht mittels der Codezeile CompressedHttpProtocol.Register();.Dies ist die einzige Zeile (ich sprach bereits am Anfang des Artikels davon), welcher der Clientanwendung hinzugefügt werden muss. Hierdurch wird der "neue" HTTP-Handler registriert und wird für die Laufzeit der Anwendung verwendet.

Einziges Problem hierbei ist, daß dieser Handler sich nicht deregistrieren lässt. Dies ist jedoch auch nicht nötig, da unser Handler ebenfalls unkomprimierte Daten verarbeiten kann.

Achtung: Es gilt zu beachten, daß die eben beschriebene Codezeile VOR der Verwendung eines WebServices aufgerufen wird.

Hinter dieser Codezeile verstecken sich 2 kleine Klassen.

.
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;

namespace NetCompressionLibrary
{
    public class CompressedHttpProtocol
    {
        /// <summary>
        /// Register the protocol
        /// </summary>
        /// <returns></returns>
        static public bool Register()
        {
            return WebRequest.RegisterPrefix("http", new CompressedHTTPWebRequestCreate());
        }
    }
}

Bei dieser Klasse handelt es sich um eine kleine Hilfsklasse. Die Methode Register() registriert den CompressedHTTPWebRequest mit einer weiteren Hilfsmethode, welche im folgenden beschrieben wird, als Handler für die HTTP Kommunikation. Alle Anfragen, welche das Prefix "http" verwenden, werden also durch unsere neuen Klassen verarbeitet. Dies ist generell sinnvoll, da, wie bereits beschrieben, auch unkomprimierte HTTP Kommunikation verarbeiten können.

Die Hilfsklasse CompressedHTTPWebRequestCreate sieht, wie folgt aus:

.

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;

namespace NetCompressionLibrary
{
    public class CompressedHTTPWebRequestCreate : IWebRequestCreate
    {
        /// <summary>
        /// Create the WebRequest object able to handle the Uri
        /// </summary>
        /// <param name="uri">the requested Uri</param>
        /// <returns>the WebRequest object</returns>
        public System.Net.WebRequest Create(System.Uri uri)
        {
            return CompressedHTTPWebRequest.Create(uri);
        }
    }
}

Diese Klasse leitet vom Interface IWebRequestCreate ab, welches für die Registrierung eines Handlers benötigt wird und beim Aufruf jeweils die korrekten WebRequest und WebResponse Klassen verwendet.

Wenn Sie nun, wie gewohnt Ihren Webverweis und die eben erstellte Bibliothek Ihrem Projekt hinzufügen und den clientseitigen HTTP-Handler wie eben gezeigt registrieren, können Sie wie gewohnt Ihre Anwendungen weiter entwickeln und zusätzlich Zeit Platz und Geld sparen.

Fazit

Eigentlich nicht viel Aufwand, jedoch eine Menge "Benefit". Microsoft, bitte baut dies doch direkt in das .NET Compact Framework 3.5 ein. Ihr erspart vielen Personen eine Menge Ärger.

Die Bibliothek lässt sich natürlich noch erweitern. So liesse sich, mit entsprechend erstellten Bibliotheken die Komprimierung auch noch verschlüsseln. Dies könnte ebenfalls mit einem HTTP-Händler durchgeführt werden. Hiermit wäre das einfache Abhören der Kommunikation zuerst einmal unterbunden.

 

Link: Bibliothek als Source und Binary NetCompressionLibrary.zip (226,15 KB)

 

This posting is provided "AS IS" with no warranties, and confers no rights.

Thursday, July 05, 2007 11:29:03 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]   .NET Compact Framework | Windows Mobile  |  Trackback
 Tuesday, July 03, 2007

Seth Forgie von InformIT ist einer der ersten glücklichen Besitzer eines IPhones, welches seit wenigen Tagen in den USA verfügbar ist.
Er beschreibt in seinem englischsprachigen Artikel sehr detailiert die Funktionen, welche das Geräte bietet und vergleicht diese mit Windows Mobile Geräten.
Dabei nimmt er eine sehr neutrale Position ein.

Mein Fazit aus diesem Artikel: Beim IPhone handelt es sich um ein sehr formschönes und stylisches Gerät. Jedoch, wenn man einmal die Kosten betrachtet und die Schönheit des Gerätes einmal vergisst, dann handelt es sich doch nur um ein sehr eingeschränktes teures Spielzeug.

Tuesday, July 03, 2007 2:20:17 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]   Geräte | Windows Mobile  |  Trackback

Sind Sie schon mal in die missliche Lage gekommen, daß Ihnen eine Schriftart unter Windows Mobile und somit auch in Ihrer Anwendung fehlt?

Mit ein wenig P/Invoke lässt sich dies schnell beheben:

[DllImport("coredll.dll", SetLastError = true)]
public static extern int AddFontResource(string lpName);

Rufen Sie in Ihrer Anwendung nur noch die Methode AddFontResource(@"\pfad\" + fontdateiname); auf, und schon können Sie die Schriftart in ihrer Anwendung verwenden.

Quelle: http://fabdecret.blogspot.com/2007/07/install-unicode-fonts.html

Tuesday, July 03, 2007 2:09:11 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [2]   .NET Compact Framework | P/Invoke | Windows Mobile  |  Trackback
 Monday, July 02, 2007

Keider ist dieser "Post" mehrfach aus dem Blogsystem "verschwunden". Daher sei er hier nochmals aufgeführt.

 

 

Aus der MSDN Reihe "Gewusst wie", oder wie sie im englischen heißt "How do I", gibt es nun einige Videos zum Thema Mobility.

In den 10 - 20 minütigen Videos werden kleinere Hilfestellungen für den Arbeitsalltag eines .NET Entwicklers gegeben.

Das schöne an den Videos ist, daß man sie in diversen (mobilen) Formaten neben WMV erhält (bspw.: 3GP). Alternativ gibt es auch nur die Tonspuren als MP3 und Co.

Die ersten beiden englischsprachigen Videos von Jim Wilson sind bereits online:

 

Doch weitere Themen sind geplant und sollen im Abstand von einer Woche erscheinen.

Bisher geplant:

  • Configuring the Device Emulator to use the Cellular Emulator
  • Automatically start an app when the device wakes up
  • Create an application CAB file that automatically installs .NET CF 
  • Setup and use the Remote Performance Manager
  • Make a merge replication publication available to remote devices

 

Link: http://msdn2.microsoft.com/de-de/netframework/bb495180.aspx

 

 

 

Monday, July 02, 2007 6:36:03 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]   Geräte | Visual Studio | Windows Mobile  |  Trackback

Es gibt Situationen, in denen man unter Windows XP SP2 mit einem USB-Bluetoothadapter arbeiten möchte. Dabei wäre es wünschenswert, den bei SP2 mitgelieferten Microsoft Bluetooth Stack zu verwenden, da es hierfür einen .NET Wrapper (32Feet .NET: http://www.codeplex.com/32feet)gibt, der unter dem .NET Framework, als auch gleichzeitig unter dem. NET Compact Framework arbeitet.

Die meisten USB-Bluetoothadapter werden jedoch mit der Widcomm / Broadcom Software ausgeliefert, die mit diesem Wrapper inkompatibel sind. Schließt man das Gerät jedoch ohne die installierte Software an, so passiert ersteinmal nichts, da daß Gerät nicht als solches erkannt wird.

Die meisten ausgelieferten Adapter sind jedoch mit dem Microsoft-Stack kompatibel, jedoch werden diese nicht gelistet. Dies lässt sich aber ändern. Hierfür sind wenige Schritte notwendig.
Sollte die Widcom / Broadcom Software installiert sein, so gilt es, diese zu entfernen.
Danach benötigt man die Vendor ID (VID) und dir Product ID (PID). Diese erhält man, wenn man sich die Eigenschaften des entsprechenden Gerätes im Geräte Manager anschaut:
geraetemanager.jpg

In unserem Fall notieren wir uns also die Zeichenfolge:"USB\VID_0Bf8&PID_1003". Die dahinterfolgende Zeichenfolge ist irrelevant.

Diese Information muss nun in die Datei "bth.inf" im Ordner"Windows\inf" oder entsprechend hinzugefügt werden:

bth.jpg

Wie dargestellt, fügen Sie diese Informationen einer Kategorie hinzu (hier bspw.: "Microsoft.NT.5.1") mit einem sprechenden Namen für Ihren Adapter und der zugehörigen Information "BthUsb" und dem ermittelten Wert.

Nachdem nun die Datei gespeichert wurde und Sie den Adapter an das System angeschlossen haben, sollte Ihr Gerät erkannt und die zugehörige Software installiert werden.

Monday, July 02, 2007 6:34:28 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]   Geräte  |  Trackback
 Friday, June 08, 2007

Wie Jason Landridge hier berichtet, soll es im 3. Quartal diesen Jahres ein kostenloses Update geben, welches Office 2007 auf die genannten Geräte bringt.
Damit werden die neuen Dokumentenformate (pptx, docx und xlsx) und FAX Dokumente direkt unterstützt und können mit den mobilen Geräten verarbeitet werden.

Alle Geräte, die ab dem 3. Quartal verfügbar sind, sollen dieses Update bereits im ROM integrieren.

Friday, June 08, 2007 11:55:02 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]   Windows Mobile  |  Trackback

Das Windows Mobile Device Center 6.1 wurde mittlerweile ebenfalls in deutscher Sprache veröffentlicht.
Es bringt einige Bugfixes mit sich, welche zumeist die Synchronisation mit Windows Mobile 6 Geräten betrifft.

Zusätzlich lassen sich nun auch HTML Mails synchronisieren, wenn entsprechend eingestellt.

 

Die Software kann hier kostenfrei heruntergeladen werden.

Friday, June 08, 2007 11:49:31 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]   Windows Mobile  |  Trackback
 Wednesday, June 06, 2007

Auf der TechEd 2007 in Orlando wurde nun der offizielle Produktname für Visual Studio "Orcas" bekannt gegeben: Microsoft Visual Studio 2008.
Der Erscheinungstermin ist weiterhin offen, doch halten sich die Gerüchte hartnäckig, daß es noch in 2007 erscheinen soll.

Wednesday, June 06, 2007 7:46:03 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]   Windows Mobile | Visual Studio  |  Trackback

Wie bereits angekündigt wird es eine zweite Auflage unseres Buches "Programmieren mit dem .NET Compact Framework - zweite Auflage" geben.
Torsten hat hierzu bereits die ersten Informationen hier und hier verfasst.

Damit die zweite Auflage noch besser wird, sind wir auf Ihr Feedback angewiesen. Zwar haben wir bereits schon einiges an Feedback erhalten, wofür wir sehr dankbar sind. Möchten Sie auch noch Ihre Meinung abgeben, so können Sie uns gerne diese unter info@nahtlos-mobil.de zukommen lassen.

Wednesday, June 06, 2007 6:27:49 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]   Buch  |  Trackback

Bereits gestern wurde das HTC Touch vorgestellt. Soweit nichts besonderes. Jedoch wird dieses Gerät als der IPhone Killer (welches noch selbst nicht erschienen ist) bezeichnet.
Das IPhone soll eine sehr ausgeklügelte und intuitive Steuerung des Gerätes ermöglichen, da daß Touchscreen komplett verwendet werden kann. Dies ist nun auch mit dem HTC Touch möglich, welches hierzu die selbst entwickelte TouchFLO-Technologie verwendet. Diese soll neben einer vereinfachten Steuerung auch die Art der Eingabe zwischen Stift und Finger unterscheiden können.

Das Windows Mobile 6 Professional Tri-Band-Gerät (900, 1800, 1900 MHz) soll nach Herstellerangaben 112 Gramm wiegen. Es besitzt dabei nur eine Größe von 100 x 58 x 14 Millimeter. Als Zubehör liefert HTC eine ein GByte große microSD-Karte zum bereits intern vorhandenen 64 MB Speicher mit.
Das 2,8 Zoll Touchscreen-Display hat eine Auflösung von 240 x 320 Pixel bei 65.536 Farben. Zeitgemäß bietet integriert das Gerät eine 2-Megapixel-Kamera. Als Prozessor wird ein OMAP 850 von Texas Instruments mit 201 MHz verwendet
Drahtlose Datenverbindung sind mit GPRS, EDGE und W-LAN (b/g) möglich. Bluetooth 2.0 besitzt das Gerät natürlich auch.

In Großbritannien ist das HTC Touch laut HTC bereits erhältlich. Es soll noch Ende Juni im restlichen Europa und in Asien auf den Markt kommen.
In Deutschland soll es von O2 unter dem Namen xda nova, wahrscheinlich exklusiv ab Juni 2007 (14 Tage vor anderen Anbietern), vertrieben werden. T-Mobile wird dieses Gerät wohl unter dem MDA Touch anbieten.

Ich hatte letzte Woche bereits beruflich die Möglichkeit eines der Vorabgeräte zu testen. Dabei ist die 3D Optik wirklich sehr hübsch. Die Animationen bei Drehungen sind dabei auch sehr flott. Die Steuereung per TouchFLO ist ebenfalls angenehm und geht einfach zur Hand. Der Today-Screen ist ebenfalls angepasst. Sie besitzt bspw. zusätzlich ein Icon für die aktuelle Wettervorhersage.
Mal schauen, ob ich mir dieses Gerät in naher Zukunft mal anlegen kann.

Da aber das IPhone noch nicht auf dem Markt ist, bleibt abzuwarten, ob es wirklich ein IPhone killer sein wird.

 


 

Wednesday, June 06, 2007 5:46:30 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]   Geräte  |  Trackback
Copyright © 2008 Peter Nowak. All rights reserved.
DasBlog 'Portal' theme by Johnny Hughes.