<?xml version="1.0" encoding="iso-8859-1"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<copyright>Manuel Josupeit-Walter</copyright>
		<generator>Capits.Simple Blog</generator>
		<language>de</language>
		<lastBuildDate>Wed, 08 Sep 2010 17:55:21 +0200</lastBuildDate>
		<managingEditor>webmaster@josupeit.com (Manuel Josupeit-Walter)</managingEditor>
		<webMaster>webmaster@josupeit.com (Manuel Josupeit-Walter)</webMaster>
		<ttl>1440</ttl>
		<title>Informatik und Technik @ josupeit.com</title>
		<link>http://www.josupeit.com/weblog~informatik-und-technik</link>
		<description>Aus dem Leben eines Homo Informaticus</description>
		<pubDate>Wed, 24 Oct 2007 21:41:36 +0200</pubDate>
		<atom:link rel="self" type="application/rss+xml" href="http://www.josupeit.com/weblog~informatik-und-technik?output=rss" />
		
		<item>	
			<title>Auf dem Weg zur Überwachungsgesellschaft?</title>
			<link>http://www.josupeit.com/weblog~informatik-und-technik~web,auf-dem-weg-zur-ueberwachungsgesellschaft.html</link>
			<guid>http://www.josupeit.com/front_content.php?lang=1&amp;idart=95</guid>
			<pubDate>Thu, 25 Feb 2010 20:29:38 +0100</pubDate>
			<author>webmaster@josupeit.com (Manuel Josupeit-Walter)</author>
			<description><![CDATA[ <p>
			Dass Facebook mit bereits Anfang 2009 auf den Keks ging, habe ich ja bereits im Artikel <a href="front_content.php?idart=75&amp;idcat=9&amp;lang=1&amp;client=1" title="Facebook Account l&ouml;schen">Facebook Account l&ouml;schen</a> beschrieben. Abgesehen davon, dass ich mir trotz allen L&ouml;schens nur schwer vorstellen kann, dass die Daten angesichts aktueller Meldungen gerade bei Facebook &quot;dauerhaft entfernt&quot; werden, frage ich mich: &Auml;ndert das &uuml;berhaupt was am Schutz meiner Daten?
			</p>
			<p>
			Vor einiger Zeit habe ich bei Heise online gelesen, dass es mittlerweile m&ouml;glich ist, sein Handyadressbuch mit Facebook zu &quot;synchronisieren&quot; und sein Mailkonto (nach Angabe von Benutzernamen und Passwort selbstredend <i><b>[Achtung: Sarkasmus]</b></i>) abgrasen zu lassen<sup><a href="front_content.php?idart=95#fussnoten">1</a></sup>, um direkt mit seinen Freunden verbunden zu werden. Wozu habe ich damals also mein Konto gel&ouml;scht, wenn Freunde, Verwandte, entfernte Bekannte oder Leute, denen ich aus irgendwelchen Gr&uuml;nden mal eine E-Mail gesendet habe meine Daten ohne R&uuml;ckfrage an diese Datenschleuder versenden? X-O
			</p>
			<p>
			Was mich, abgesehen davon, dass sehr viele Menschen, darunter vor allem junge Menschen, sehr sehr viele Informationen &uuml;ber sich sowieso bereitwillig durchs Internet jagen jedoch wirklick sorgt, ist&nbsp; dass ich nun von allen &quot;Interessenten&quot; nicht blo&szlig; gegooglet oder &quot;gefacebookt&quot; werden kann, sondern dass diese stumpfsinnige Arbeit jetzt gleich biometrisch gest&uuml;tzt erledigt wird<sup><a href="front_content.php?idart=95#fussnoten">2</a></sup>. Der Firma &quot;The Astonishing Tribe&quot; (die Verlinkung spare ich mir an dieser Stelle bewusst) haben wir das Gl&uuml;ck zu verdanken, dass bald jeder Besitzer eines Handys mit 5 Megapixel-Kamera blo&szlig; noch sein Objektiv auf ein Gesicht richten muss und die Software automatisch alle gesammelten Daten zu der geknipsten Person zur&uuml;ckgibt.
			</p>
			<p>
			Bin ich der Einzige, der sich schon darauf freut, sich selbst zu knipsen?
			</p>
			<hr />
			<a title="fussnoten" name="fussnoten"></a>
			<p>
			<sup>1</sup> <a href="http://www.heise.de/newsticker/meldung/Was-Facebook-ueber-Nicht-Mitglieder-weiss-921350.html" target="_blank">Was Facebook &uuml;ber Nicht-Mitglieder wei&szlig;</a> (Heise Online)<br />
			<sup>2</sup> <a href="http://www.heise.de/newsticker/meldung/Handy-identifiziert-Fotografierte-ueber-Facebook-Co-939784.html" target="_blank">Handy identifiziert Fotografierte &uuml;ber Facebook &amp; Co.</a> (Heise Online)
			</p>
			 ]]></description>
		</item>
		<item>
			<title>SpamAssassin anhand von IMAP Flags lernen lassen</title>
			<link>http://www.josupeit.com/weblog~informatik-und-technik~linux,spamassassin-anhand-von-imap-flags-lernen-lassen.html</link>
			<guid>http://www.josupeit.com/front_content.php?lang=1&amp;idart=90</guid>
			<pubDate>Sat, 30 Jan 2010 14:38:46 +0100</pubDate>
			<author>webmaster@josupeit.com (Manuel Josupeit-Walter)</author>
			<description><![CDATA[ <p>
			All meine eingehenden E-Mails werden direkt meinem Homeserver zugestellt. Dort wird auch ein Gro&szlig;teil an Spam gefiltert. In der Vergangenheit trainierte ich den dort laufenden SpamAssassin durch bouncen der entsprechenden Mails an spezielle E-Mail Adressen, die die Mails dann an <span class="inline_code">sa-learn</span> pipeten. Da mir das immer wieder einmal auf den Keks ging fragte ich mich, ob es nicht viel einfacher m&ouml;glich w&auml;re, Spam anhand der Thunderbird Junk-Markierung lernen zu lassen.
			</p>
			<p>
			Gl&uuml;cklicherweise bietet das IMAP4 Protokoll laut RFC 3501 die M&ouml;glichkeit, Mails mit Flags zu versehen. Von Hause aus gibt es beispielsweise Flags, wie <span class="inline_code">\Seen</span> oder <span class="inline_code">\Deleted</span>, die Kennzeichnen, ob eine Nachricht gelesen oder gel&ouml;scht wurde, jedoch erlaubt das Protokoll auch die Vergabe eigener Flags. Diese benutzerdefinierten Flags werden allerdings als Keywords bezeichnet. Thunderbird verwendet f&uuml;r die Markierung, ob eine Mail Spam oder Ham (also kein Spam) ist, die Keywords <span class="inline_code">Junk</span> und <span class="inline_code">NonJunk</span>, wobei nur Mails, die als Junk markiert wurden und explizit auf &quot;Kein Junk&quot; geklickt wurde, als <span class="inline_code">NonJunk </span>markiert werden.
			</p>
			<p>
			Nun verwende ich ein Perl-Skript, das alle 15 Minuten als Cronjob gestartet wird, mit den Benutzerdaten des Administrators zu meinem Cyrus-IMAP Server verbindet und alle Ordner aller Benutzer auf Mails durchsucht, die entsprechend gekennzeichnet wurden und den Inhalt dann an SpamAssassin &uuml;bergibt. Anschlie&szlig;end werden die Mails entsprechend als <span class="inline_code">LernedJunk</span> und <span class="inline_code">LernedNonJunk</span> gekennzeichnet. Dadurch werden automatisch alle Mails, die Thunderbird als Junk einstuft oder von Hand eingestuft werden bereits serverseitig gelernt und entsprechend stetig besser gefiltert.
			</p>
			<p>
			Dieses Skript stelle ich hiermit unter GPLv3 zur Verf&uuml;gung, vielleicht findet ja noch jemand Verwendung daf&uuml;r:<br />
			</p>
			<p class="code">
			#!/usr/bin/perl<br />
			use Mail::IMAPClient;<br />
			use MIME::Base64;<br />
			<br />
			do('/etc/bayes_learn_spam.conf')<br />
			&nbsp; or die &quot;Unable to read configuration file /etc/bayes_learn_spam.conf&quot;;<br />
			<br />
			my $imap = Mail::IMAPClient-&gt;new(<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Server =&gt; $host,<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Port =&gt; $port,<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Debug =&gt; 0)<br />
			<br />
			&nbsp; or die &quot;Unable to connect to imap server&quot;;<br />
			<br />
			$imap-&gt;has_capability(&quot;STARTTLS&quot;) and $imap-&gt;starttls;<br />
			$imap-&gt;tag_and_run(&quot;AUTHENTICATE PLAIN &quot; . encode_base64(&quot;\0&quot; . $authuser . &quot;\0&quot; . $password))<br />
			&nbsp; or die &quot;Unable to login to imap server with user &quot; . $authuser;<br />
			<br />
			my @folders = $imap-&gt;folders<br />
			&nbsp; or die &quot;Unable to retrieve user list from imap server&quot;;<br />
			<br />
			my @users;<br />
			<br />
			foreach $folder (@folders) {<br />
			&nbsp; if ( $folder =~ /^user\..*$/i ) {<br />
			&nbsp;&nbsp;&nbsp; $folder =~ s/^user\.([^\.]*).*/\1/i;<br />
			<br />
			&nbsp;&nbsp;&nbsp; if (! grep /$folder/, @users) {<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push (@users, $folder);<br />
			&nbsp;&nbsp;&nbsp; }<br />
			&nbsp; }<br />
			}<br />
			<br />
			$imap-&gt;disconnect<br />
			&nbsp; or die &quot;Unable to close connection to imap server&quot;;<br />
			<br />
			foreach $user (@users) {<br />
			&nbsp; print &quot;Processing messages for user &quot; . $user . &quot;...\n&quot;;<br />
			&nbsp; undef($imap);<br />
			<br />
			&nbsp; my $imap = Mail::IMAPClient-&gt;new(<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Server =&gt; $host,<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Port =&gt; $port,<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Uid =&gt; 0,<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Peek =&gt; 1,<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Debug =&gt; 0)<br />
			<br />
			&nbsp;&nbsp;&nbsp; or die &quot;Unable to connect to imap server&quot;;<br />
			<br />
			&nbsp; $imap-&gt;has_capability(&quot;STARTTLS&quot;) and $imap-&gt;starttls;<br />
			&nbsp; $imap-&gt;tag_and_run(&quot;AUTHENTICATE PLAIN &quot; . encode_base64($user . &quot;\0&quot; . $authuser . &quot;\0&quot; . $password))<br />
			&nbsp;&nbsp;&nbsp; or die &quot;Unable to do plain auth&quot;;<br />
			<br />
			&nbsp; foreach $folder ($imap-&gt;folders) {<br />
			&nbsp;&nbsp;&nbsp; print &quot;Processing folder &quot; . $folder . &quot;...\n&quot;;<br />
			&nbsp;&nbsp;&nbsp; $imap-&gt;select($folder)<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or die &quot;Unable to select imap folder &quot; . $folder . &quot; for user &quot; . $user;<br />
			<br />
			&nbsp;&nbsp;&nbsp; @spam = $imap-&gt;search(&quot;UNDELETED KEYWORD &quot; . $junktag .&nbsp;&nbsp;&nbsp; &quot; UNKEYWORD &quot; . $learnedjunktag);<br />
			&nbsp;&nbsp;&nbsp; @ham&nbsp; = $imap-&gt;search(&quot;UNDELETED KEYWORD &quot; . $nonjunktag . &quot; UNKEYWORD &quot; . $learnednonjunktag);<br />
			<br />
			&nbsp;&nbsp;&nbsp; # Process spam<br />
			&nbsp;&nbsp;&nbsp; print &quot;Learning &quot; . @spam . &quot; spam messages...\n&quot;;<br />
			&nbsp;&nbsp;&nbsp; foreach (@spam) {<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $imap-&gt;store($_, &quot;-FLAGS&quot;, $learnednonjunktag)<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or die &quot;Unable to flag message &quot; . $_ . &quot; in folder &quot; . $folder . &quot; for user &quot; . $user;<br />
			<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @msg = $imap-&gt;message_string($_)<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or die &quot;Unable to fetch spammy mail &quot; . $_ . &quot; from folder &quot; . $folder . &quot; for user &quot; . $user;<br />
			<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; open(my $sa, &quot;| &quot; . $salearn . &quot; --spam&quot;)<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or die (&quot;Unable to pipe to sa-learn&quot;);<br />
			<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print $sa @msg;<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; close($sa);<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; undef($sa);<br />
			<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $imap-&gt;store($_, &quot;+FLAGS&quot;, $learnedjunktag)<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or die &quot;Unable to flag message &quot; . $_ . &quot; in folder &quot; . $folder . &quot; for user &quot; . $user;<br />
			&nbsp;&nbsp;&nbsp; }<br />
			<br />
			&nbsp;&nbsp;&nbsp; # Process ham<br />
			&nbsp;&nbsp;&nbsp; print &quot;Done. Learning &quot; . @ham . &quot; ham messages...\n&quot;;<br />
			&nbsp;&nbsp;&nbsp; foreach (@ham) {<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $imap-&gt;store($_, &quot;-FLAGS&quot;, $learnedjunktag)<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or die &quot;Unable to flag message &quot; . $_ . &quot; in folder &quot; . $folder . &quot; for user &quot; . $user;<br />
			<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @msg = $imap-&gt;message_string($_)<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or die &quot;Unable to fetch hammy mail &quot; . $_ . &quot; from folder &quot; . $folder . &quot; for user &quot; . $user;<br />
			<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; open(my $sa, &quot;| &quot; . $salearn . &quot; --ham&quot;)<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or die (&quot;Unable to pipe to sa-learn&quot;);<br />
			<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print $sa @msg;<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; close($sa);<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; undef($sa);<br />
			<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $imap-&gt;store($_, &quot;+FLAGS&quot;, $learnednonjunktag)<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or die &quot;Unable to flag message &quot; . $_ . &quot; in folder &quot; . $folder . &quot; for user &quot; . $user;<br />
			&nbsp;&nbsp;&nbsp; }<br />
			<br />
			&nbsp;&nbsp;&nbsp; print &quot;Done learning messages from folder &quot; . $folder . &quot;.\n&quot;;<br />
			&nbsp; }<br />
			<br />
			&nbsp; $imap-&gt;disconnect;<br />
			&nbsp; print &quot;All messages for user &quot; . $user . &quot; have been processed.\n&quot;;<br />
			} 
			</p>
			<p>
			<br />
			Die Konfiguration erfolgt &uuml;ber die Datei /etc/bayes_learn_spam.conf, die (entsprechend Zugriffsgesch&uuml;tzt) folgende Daten enth&auml;lt:
			</p>
			<p class="code">
			$host&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 'localhost';<br />
			$port&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 143;<br />
			$authuser&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 'cyrus';<br />
			$password&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 'passwort';<br />
			<br />
			$salearn&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = '/usr/bin/sa-learn';<br />
			<br />
			$junktag&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 'Junk';<br />
			$nonjunktag&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 'NonJunk';<br />
			$learnedjunktag&nbsp;&nbsp;&nbsp; = 'LearnedJunk';<br />
			$learnednonjunktag = 'LearnedNonJunk'; 
			</p>
			<p>
			&nbsp;<br />
			Viel Spa&szlig; beim Trainieren. :-) &Uuml;brigens: Thunderbird bietet die M&ouml;glichkeit, benutzerdefinierte Schl&uuml;sselworte zu definieren und farbig hervorzuheben, so hat man immer und &uuml;berall den &Uuml;berblick, was gelernt wurde und was nicht...
			</p>
			<hr />
			<a href="front_content.php?idart=37&amp;idcat=4&amp;lang=1&amp;client=1"><img src="upload/grafiken/gplv3-88x31.gif" alt="GPLv3" align="right" height="31" width="88" /></a>
			<div class="clear">
			</div>
			 ]]></description>
		</item>
		<item>
			<title>Phishing als Geschäftsmodell</title>
			<link>http://www.josupeit.com/weblog~informatik-und-technik~web,phishing-als-geschaeftsmodell.html</link>
			<guid>http://www.josupeit.com/front_content.php?lang=1&amp;idart=86</guid>
			<pubDate>Sat, 07 Nov 2009 19:53:18 +0100</pubDate>
			<author>webmaster@josupeit.com (Manuel Josupeit-Walter)</author>
			<description><![CDATA[ <p>
			Heute, beim Kaffee mit zwei meiner Informatiker-Kollegen habe ich zum ersten Mal von einer durchaus popul&auml;ren Dienstleistung im Web erfahren: der <i>Sofort&uuml;berweisung</i>. Als die zwei mir davon erz&auml;hlten dache ich zun&auml;chst, dass sie mich aufs Korn nehmen wollen: Da gibt es so einen Bezahldienst, der, wenn man ihn benutzt, um in Online-Shops zu zahlen den Shop-Betreiber veranlasst, die Ware sofort loszuschicken. Dabei wird der zu zahlende Betrag aber nicht wie bei Paypal vom Konto eingezogen, sondern direkt an den H&auml;ndler &uuml;berwiesen. Und jetzt der Hammer: Vom eigenen Konto. Wie aber kann das funktionieren, wenn nicht ich selbst den Betrag von meinem Konto &uuml;berweise? Ganz einfach: Ich gew&auml;hre einem Webdienst direkt Zugriff auf mein Onlinebanking und soll dazu wahrhaftig meine Zugangskennung, PIN und eine Transaktionsnummer (TAN) angeben! Im Normalfall hei&szlig;t sowas <b>Phishing</b>!
			</p>
			<p>
			Der Anbieter loggt sich also automatisch mit den Zugangsdaten beim Onlinebanking ein, &Uuml;berweist das Geld auf das Konto des Empf&auml;ngers und best&auml;tigt dem Anbieter, dass die &Uuml;berweisung angewiesen wurde. Da aber die Bank in diesem Fall keine Haftung &uuml;bernimmt, springt Sofort&uuml;berweisung mit irgendeiner Versicherung ein. Ich muss gestehen, bereits da habe ich aufgeh&ouml;rt zu lesen und vor Emp&ouml;rung angefangen diesen Beitrag hier zu verfassen. Die interessante Frage ist doch: <u>Wieso zum Geier haftet die Bank nicht mehr?</u> Ganz einfach: Weil sie sich von Ihnen aus gutem Grund hat unterschreiben lassen, dass sie von der Haftung entbunden wird, wenn Sie Ihre Zugangsdaten weitergeben!
			</p>
			<p>
			Selbst wenn Sie &quot;Sofort&uuml;berweisung&quot; vertrauen und ich frage Sie, wieso sollten Sie das tun? Vielleicht wegen der T&Uuml;V Zertifizierung, dass Ihre Daten nicht gespeichert werden und ganz sicher <b>sicher</b> sind? Wie auch immer: Selbst wenn Sie &quot;Sofort&uuml;berweisung&quot; vertrauen, bereits in der Praxis wurde eine SSL Verschl&uuml;sselung wegen unsicherer Zertifikate ausgehebelt, vertrauen Sie dem Zertifikat? F&auml;llt Ihnen <i>sicher</i> auf, falls die Seite &uuml;berhaupt nicht SSL verschl&uuml;sselt ist und Sie vielleicht bereits bei &quot;Sofort&uuml;berweisung&quot; auf einer Phishing-Seite landen, die Originalgetreu nachgebildet wurde? Wenn Sie nicht den geringsten Zweifel hegen, dann schicken Sie mir bitte einfach Ihre EC-Karte und Ihre Geheimnummer an die Adresse im Impressum, ich werde mich k&uuml;nftig um Ihre Finanzen k&uuml;mmern, doch sein Sie versichert: Sie k&ouml;nnen mir vertrauen... 
			</p>
			<p>
			Zu guter Letzt bleibt also festzuhalten, dass es nicht gen&uuml;gt, dass die Banken auf Ihren Onlinebanking-Portalen darauf hinweisen, dass man niemandem seine Daten geben sollte. Statt dessen sollten endlich alle Institute das TAN, iTAN, mTAN oder Irgendein-Buchstabe-davor-und-trotzdem-unsicher-TAN Verfahren durch bekannte, sichere Verfahren, wie HBCI &uuml;ber Chipkarte abl&ouml;sen, damit weniger technikversierte Menschen gar nicht erst in die Versuchung kommen, solche Dienste zu nutzen... 
			</p>
			 ]]></description>
		</item>
		<item>
			<title>Windows Konsolenfenster maximieren</title>
			<link>http://www.josupeit.com/weblog~informatik-und-technik,windows-konsolenfenster-maximieren.html</link>
			<guid>http://www.josupeit.com/front_content.php?lang=1&amp;idart=85</guid>
			<pubDate>Tue, 03 Nov 2009 22:07:24 +0100</pubDate>
			<author>webmaster@josupeit.com (Manuel Josupeit-Walter)</author>
			<description><![CDATA[ <p>
			Ich arbeite auf meinen Desktop PCs und Notebooks seit Jahren mit Windows. Und mindestens genauso lange habe ich mich dar&uuml;ber ge&auml;rgert, dass Kommandozeilenfenster (ab Windows XP &uuml;ber Start/Ausf&uuml;hren/cmd zu &ouml;ffnen) in der Gr&ouml;&szlig;e oder zumindest in der Breite fixiert sind. Sp&auml;testens seit Windows XP gibt es jedoch einen Trick, &uuml;ber den sich die Gr&ouml;&szlig;e des Fensters leicht anpassen l&auml;sst.
			</p>
			<p>
			Dazu gebt Ihr auf der Kommandozeile <span class="inline_code">wmic</span> ein. Ehrlich gesagt habe ich keinen Plan, um was f&uuml;r ein Konsolentool es sich dabei handelt, aber jetzt kann man sein Fenster maximieren :-). Die Eingabe von <span class="code">exit </span>beendet <span class="inline_code">wmic</span>. Nachdem das geschehen ist, k&ouml;nnt Ihr &uuml;ber das Systemmen&uuml; des Konsolenfensters die Eigenschaften &auml;ndern und im Register Layout die Fensterpuffergr&ouml;&szlig;e &auml;ndern. Wer wie ich in der Breite nicht scrollen m&ouml;chte, kann dort die selbe Zahl eingeben, wie nun bei Fenstergr&ouml;&szlig;e steht. Vo&iacute;la, beim n&auml;chsten &ouml;ffnen der Kommandozeile ist das Fenster nun sch&ouml;n gro&szlig;...
			</p>
			 ]]></description>
		</item>
		<item>
			<title>Spamannahme verweigern mit Postfix und Postprox</title>
			<link>http://www.josupeit.com/weblog~informatik-und-technik~linux,spamannahme-verweigern-mit-postfix-und-postprox.html</link>
			<guid>http://www.josupeit.com/front_content.php?lang=1&amp;idart=84</guid>
			<pubDate>Thu, 22 Oct 2009 20:03:27 +0200</pubDate>
			<author>webmaster@josupeit.com (Manuel Josupeit-Walter)</author>
			<description><![CDATA[ <p>
			Wenn Sie einen eigenen Mailserver betreiben, haben Sie sich vielleicht auch schon gefragt wie es m&ouml;glich ist, die Annahme von Spam oder mit Viren infizierter Nachrichten direkt zu verweigern, denn jede zur&uuml;ckgewiesene Mail ist dann nicht mehr Ihr Problem, sondern das des versendenden Mailservers.
			</p>
			<p>
			Der Mail Transfer Agent (MTA) <a href="http://www.postfix.org/" target="_blank">Postfix</a> bietet hierf&uuml;r geeignete Schnittstellen an, wie z.B. sogenanntes <i>Pre-Queue Filtering</i>. Dabei wird die eingehende Mail bevor sie in die Mail-Warteschlange aufgenommen wird bereits an einen SMTP-Proxy weitergegeben, das hei&szlig;t, Postfix stellt die Mail einem anderen Mailserver zu, der idealerweise auf dem selben Host l&auml;uft. Dieser auf einen Anwendungsfall spezialisierte Mailserver ist jedoch nicht daf&uuml;r zust&auml;ndig, die Mail letztlich zuzustellen, sondern agiert als sogenannter <i>Proxy</i>. Er f&uuml;hrt auf der ihm zugestellten Mail seine &quot;Arbeit&quot; aus, wie z.B. die Untersuchung auf Spam mittels <a href="http://spamassassin.apache.org/" target="_blank">SpamAssassin</a> und gibt die Mail dann wahlweise wieder an Postfix zur&uuml;ck oder weist sie mit einem entsprechenden Statuscode ab. In letzterem Fall wird dann schlie&szlig;lich die Annahme verweigert.
			</p>
			<p>
			Der in diesem Beispiel verwendete SMTP-Proxy nennt sich <a href="http://www.ivarch.com/programs/postprox.shtml" target="_blank">postprox</a>. Postprox ist ein Programm, dass vom Standardeingabestream die eingehende E-Mail-Kommunikation erwartet und an einen anderen Server (eine weitere &quot;Instanz&quot; von Postfix) direkt weiterleitet, mit Ausnahnme des DATA Blocks (siehe auch: <a href="http://de.wikipedia.org/w/index.php?title=Simple_Mail_Transfer_Protocol&amp;oldid=64047489#Protokoll" target="_blank">Funktionsweise des SMTP-Protokolls bei Wikipedia</a>). Dieser Block wird nach Beendigung zun&auml;chst an ein &uuml;ber das Kommandozeilenargument <span class="inline_code">-c</span> angegebenes Programm weitergegeben. Der R&uuml;ckgabewert dieses Programms soll im fehlerfreien Fall 0 und im Fehlerfall 1 sein, denn basierend auf diesem R&uuml;ckgabewert wird der MTA die Mail annehmen (0) oder verweigern (1). Dabei wird der gesamte DATA Block zuvor in einer tempor&auml;ren Datei gespeichert, die das von Postprox aufgerufene Programm &uuml;ber die Umgebungsvariable <span class="inline_code">$EMAIL</span> &ouml;ffnen kann (weitere Umgebungsvariablen finden sich in der <a href="http://www.ivarch.com/programs/quickref/postprox.shtml" target="_blank">Manpage von Postprox</a>).
			</p>
			<p>
			M&ouml;chte man, wie oben angedeutet, die Nachricht mit SpamAssassins <span class="inline_code">spamc</span> untersuchen, eignet sich folgendes Skript, dass beispielsweise unter <span class="inline_code">/usr/bin/postprox_spamc_wrapper</span> gespeichert wird:
			</p>
			<p class="code">
			#!/bin/sh<br />
			SPAMC=/usr/bin/spamc<br />
			<br />
			$SPAMC -E &lt;$EMAIL &gt; $OUTFILE 2&gt;/dev/null<br />
			STATUS=$?<br />
			<br />
			if [ $STATUS -eq 1 ] ; then<br />
			&nbsp; echo 550 Message is considered to be spam 1&gt;&amp;2<br />
			&nbsp; exit 1<br />
			fi<br />
			<br />
			exit 0
			</p>
			<p>
			<br />
			Nun muss postprox in den MTA eingebunden werden. Dazu wird Postfix' Konfigurationsdatei <span class="inline_code">main.cf</span> um folgende Zeile erg&auml;nzt:
			</p>
			<p class="code">
			smtpd_proxy_filter = 127.0.0.1:10024 
			</p>
			<p>
			<br />
			Dadurch wird Postfix versuchen, eingehende Mails bereits vor der Warteschlange an den Proxy weiterzugeben, der lokal auf Port 10024 lauscht. Damit dort jedoch &uuml;berhaupt jemand lauscht, muss nun noch die Date <span class="inline_code">master.cf</span> angepasst werden:
			</p>
			<p class="code">
			[127.0.0.1]:10024 inet n &nbsp; &nbsp; n &nbsp; &nbsp; n &nbsp; &nbsp; - &nbsp; &nbsp; 20 &nbsp; &nbsp; spawn<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; user=cyrus argv=/usr/lib/postfix/postprox -r -c /usr/bin/postprox_spamc_wrapper 127.0.0.1:10025
			</p>
			<p>
			<br />
			In dieser Zeile muss ggf. noch der Benutzername, sowie der Pfad zu <span class="inline_code">postprox</span> angepasst werden. Diese Zeile bewirkt, dass Postfix daf&uuml;r sorgt, dass Postprox selbst nun auf Port 10024 auf eingehende Daten wartet und diese an den SMTP-Server auf dem lokalen Port 10025 weiterleitet. Auf diesem Port muss nun Postfix selbst wieder lauschen, daf&uuml;r gen&uuml;gt folgender Eintrag in der Datei <span class="inline_code">master.cf</span>: 
			</p>
			<p class="code">
			[127.0.0.1]:10025 inet n &nbsp; &nbsp; -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n&nbsp;&nbsp;&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp;&nbsp; smtpd<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -o smtpd_proxy_filter=<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -o mynetworks=127.0.0.1/32<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -o smtpd_authorized_xforward_hosts=127.0.0.1/32<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -o smtpd_client_restrictions=<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -o smtpd_data_restrictions=<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -o smtpd_end_of_data_restrictions=<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -o smtpd_helo_restrictions=<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -o smtpd_recipient_restrictions=permit_mynetworks,reject_unauth_destination<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -o smtpd_sender_restriction=<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -o receive_override_options=no_unknown_recipient_checks
			</p>
			<p>
			<br />
			Nach einem Neustart von Postfix wird dieser nun die Mais zun&auml;chst annehmen und an Postprox weiterreichen. Postprox wird mittels SpamAssassin pr&uuml;fen, ob es sich um Spam handelt (Konfiguration von SpamAssassin beachten) und die Mail entweder zur&uuml;ckweisen oder &uuml;ber Port 10025 wieder an Postfix zur&uuml;ckgeben. Erst danach wird die Mail der Warteschlange zugef&uuml;hrt. Als Spam erkannte Mails werden so garnicht erst angenommen.
			</p>
			<p>
			Auf diesem Weg lassen sich z.B. auch durch Viren infizierte Mails mit Clam AntiVirus &uuml;berpr&uuml;fen und fr&uuml;h abweisen. Falls Sie noch weitere Ideen haben, an welche Tools Postprox den DATA Block delegieren kann, bin ich f&uuml;r Kommentare dankbar. :-) 
			</p>
			 ]]></description>
		</item>
		<item>
			<title>Matroska zu AVI mit FFmpeg</title>
			<link>http://www.josupeit.com/weblog~informatik-und-technik,matroska-zu-avi-mit-ffmpeg.html</link>
			<guid>http://www.josupeit.com/front_content.php?lang=1&amp;idart=83</guid>
			<pubDate>Sun, 11 Oct 2009 13:09:23 +0200</pubDate>
			<author>webmaster@josupeit.com (Manuel Josupeit-Walter)</author>
			<description><![CDATA[ <p>
			Wer wie ich mit der Xbox 360 Mediadateien streamen m&ouml;chte, kommt mit dem freien Containerformat <a href="http://www.google.de/search?q=Matroska" target="_blank">Matroska</a> leider nicht weit. Trotzdem bin selbst ich an meine Grenzen gesto&szlig;en, als ich den im Matroska-Container gemuxten DTS-Ton in A/52 (Dolby Digital) konvertieren wollte. An vielen Stellen verweist Google auf Hilfsmittel, wie die Software Hypertube Transcoder, aber das alles dauert ewig und funktioniert nicht wirklich gut.
			</p>
			<p>
			Die L&ouml;sung erwies sich jedoch als viel einfacher: <a href="http://www.google.de/search?q=FFmpeg+download&amp;btnI=" target="_blank">FFmpeg</a>! Mit diesem frei erh&auml;ltlichen Tool l&auml;sst sich nahezu jedes Audio- und Videoformat umwandeln und in beliebigen Containern verpacken.
			</p>
			<p>
			Da das Videomaterial im Matroska-Container in der Regel im H.264 Format vorliegt, die Xbox in AVI-Containern aber nur DivX &amp; Co. lesen kann, muss auch noch das Videomaterial neu kodiert werden. Letztlich haben in meinem Fall die folgenden Aufrufe den Erfolg gebracht:
			</p>
			<p class="code">
			<span class="kommentar">rem Erster Durchlauf, kein Ton</span><br />
			ffmpeg -i Eingabe.mkv -vcodec mpeg4 -an -pass 1 -passlogfile Eingabe Ausgabe.avi
			</p>
			<p class="code">
			<span class="kommentar">rem Zweiter Durchlauf; Video in DivX mit 1400 KBit/s, Audio in Dolby Digital mit 384 KBit/s umwandeln</span><br />
			ffmpeg -i Eingabe.mkv -vcodec mpeg4 -vtag DX50 -vb 1400000 \<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-acodec ac3 -ab 384000 -ac 6 -pass 2 -passlogfile Eingabe Ausgabe.avi
			</p>
			<p>
			<br />
			Wenn zus&auml;tzlich noch die Framerate von NTSC nach PAL umgewandelt- und das Bildformat auf PAL Standard gebracht werden soll, l&auml;sst sich der Aufruf entsprechend erg&auml;nzen:
			</p>
			<p class="code">
			ffmpeg -r 23.976 -i Eingabe.mkv -s 720x576 -vcodec mpeg4 -vtag DX50 -vb 1400000 \<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -acodec ac3 -ab 384000 -ac 6 -pass 2 -passlogfile Eingabe -r 25 Ausgabe.avi
			</p>
			<p>
			<br />
			FFmpeg kann noch viiiiiiel mehr. Ein Aufruf von <span class="inline_code">ffmpeg -h</span> gibt Auskunft &uuml;ber alle Optionen.
			</p>
			<p>
			Frohes &quot;Transcoden&quot; :-) 
			</p>
			 ]]></description>
		</item>
		<item>
			<title>HP Toolbox...</title>
			<link>http://www.josupeit.com/weblog~informatik-und-technik,hp-toolbox.html</link>
			<guid>http://www.josupeit.com/front_content.php?lang=1&amp;idart=80</guid>
			<pubDate>Thu, 28 May 2009 22:20:03 +0200</pubDate>
			<author>webmaster@josupeit.com (Manuel Josupeit-Walter)</author>
			<description><![CDATA[ <h2>...und die Geschichte, wieso ich nichts mehr bei Hewlett-Packard kaufe. </h2>
			<p>
			Bereits seit knapp einem Jahr &auml;rgere ich mich dar&uuml;ber, dass es f&uuml;r meinen nicht allzu alten, aber dennoch gut funktionierenden Scanner nicht blo&szlig; kein Treiber f&uuml;r Vista mehr gibt, sondern aufgrund meines <span class="nobr">64-Bit</span> Systems auch kein Treiber f&uuml;r Windows XP verwendet werden kann. Nachdem ich mir bereits damals geschworen habe, keine HP Produkte mehr zu kaufen, habe ich mir dennoch ein Smartphone von Hewlett-Packard angeschafft, bei dem nach nicht einmal einem Monat eine Taste nach vorn hin aus dem Tastenfeld guckte. Doch der Versuch, auf dem Rechner meines Vaters die Treiber-Suite f&uuml;r den LaserJet 2840 zu installieren, setzt dem Ganzen die Krone auf: 
			</p>
			<p>
			Dieses Multifunktionsger&auml;t bietet n&auml;mlich die M&ouml;glichkeit, &uuml;ber die HP Toolbox eine Funktion namens &quot;<i>Scannen an...</i>&quot; einzurichten, die es erm&ouml;glichen soll, mit einem Tastendruck am Ger&auml;t die eingelegte Vorlage direkt an eine E-Mail Adresse (oder einen Ordner auf dem angeschlossenen Rechner) zu scannen. Da viele Multifunktionsger&auml;te das Scannen nur unterst&uuml;tzen, wenn sie per USB direkt mit dem Computer verbunden sind, &uuml;berraschte mich diese M&ouml;glichkeit zun&auml;chst, da der LaserJet selbst in diesem Home-Office Szenario im Netzwerk angeschlossen ist. Leider jedoch verlie&szlig; mich meine Freude relativ z&uuml;gig, da der Versuch, die Einstellungen &uuml;ber die HP Toolbox zu speichern im Sande verlief. 
			</p>
			<p>
			Diese Toolbox ist n&auml;mlich in Form einer webbasierten Javaanwendung umgesetzt worden, so dass w&auml;hrend der schrecklichen Installationsroutine des Treiberpaketes nicht nur das .net-Framework installiert wird, sondern gleich noch eine Version der Java-Laufzeitumgebung und eine abgespeckte, aber immernoch gen&uuml;gend gro&szlig;e Version des Apache Tomcat Application-Servers. Beim Absenden des Webformulars zur Konfiguration der Scanfunktion verabschiedete sich selbige auch gleich mit einer Java <span class="inline_code">NullPointerException</span> und dem dazugeh&ouml;rigen Stack-Trace. 
			</p>
			<p>
			Die nun folgenden zwei Stunden verbrachte ich damit, nach diesem Fehler zu googlen und wurde in verschiedenen Sprachen f&uuml;ndig. Auf diversen Seiten empfahl man einige Hotfixes oder ein R&uuml;cksetzen der &quot;persistierten Daten&quot; der Toolbox, was aber nie zu irgendeinem Erfolg f&uuml;hrte. Kurzerhand entschloss ich mich dazu, alle HP Produkte zu deinstallieren und das bereits angesprochene Treiberpaket in neuster Version herunterzuladen und neu zu installieren. Dieser ca. 520 MiB gro&szlig;e, von HP liebevoll &quot;All in one&quot; Paket genannter Haufen <span class="nobr">S... oftware</span> installierte sich jedoch offenbar nur zur H&auml;lfte - die Toolbox beispielsweise fehlte. 
			</p>
			<p>
			Die n&auml;chste Stunde verbrachte ich damit, die vom Installer entpackten Dateien zu durchforsten, um eine separate Installationsroutine nur f&uuml;r diese Toolbox zu finden. Bei diesem Versuch fiel mir auf, dass der Begriff &quot;die Installer&quot; eigentlich eher zutreffend gewesen w&auml;re, denn es existierten ohne &uuml;bertreiben zu wollen ca. 51.519 verschiedene <span class="inline_code">.exe</span>-Dateien, von denen jede eine x-beliebige &quot;Seite&quot; des Assistenten repr&auml;sentierte. Irgendwann jedoch stie&szlig; ich auf die Toolbox-Installationsroutine, die ich dann manuell aufgerufen habe. Nach der Installation und einem weiteren Neustart des Rechners (die anderen hundert Male habe ich der Leser wegen ausgelassen), waren im Taskmanager auch alle erforderlichen Prozesse zu sehen: <span class="inline_code">javaw.exe</span> und irgendwelche Tray-Anwendungen. Auch <a href="http://de.wikipedia.org/wiki/Netstat" class="inline_code" title="Wikipedia Artikel zum Thema" target="_blank">netstat</a> lieferte zur&uuml;ck, dass die f&uuml;r die Toolbox n&ouml;tigen Ports 5225 und 5226 abgeh&ouml;rt werden. Nicht, dass die Einrichtung des Scanners jetzt funktionerte,&nbsp; seither &ouml;ffnete sich ausschlie&szlig;lich eine Landing-Page mit dem Hinweis, ich solle warten, bis die Toolbox initialisiert sei. 
			</p>
			<p>
			Die n&auml;chste halbe Stunde verbrachte ich damit darauf zu warten, dass dieses Ereignis eintritt - vergebens! Da hilf nur: Googlen und wieder Tips abklappern, irgendwelche Bereinigungstools starten, die nicht helfen, hundert mal neu installieren, Stecker raus, Stecker rein und auf HP Empfehlung die Firewall abschalten (<i>gute</i> Idee!). An dieser Stelle war die Zeit reif, selbst als &quot;versierter Anwender&quot; mal den&quot;preisgekr&ouml;nten Support&quot; zu kontaktieren. (Normalerweise verzichte ich gern darauf, weil ich meistens Leute am anderen Ende habe, die im Chat ihre Textbausteine durchklicken, spontan verschwinden und letztlich weniger Plan haben, als ich selbst.) Nun denn: Link finden, Produkt ausw&auml;hlen, Plugins installieren, abwarten... und dann mitgeteilt bekommen, dass der Support nur bis 18:00 Uhr erreichbar ist (wieso auch sollte man mir als <a href="http://de.wikipedia.org/wiki/D%C3%BCmmster_anzunehmender_User" title="Wikipedia Seite zum Thema" target="_blank">DAU</a> diese Information auch fr&uuml;her zukommen lassen). 
			</p>
			<p>
			Lange Rede, kurzer Sinn: Wenn ich solche Software entwickeln w&uuml;rde, h&auml;tte ich schon heute keinen Job mehr. Wie auch immer, ich werde jedenfalls versuchen, das Ding noch irgendwie zum Laufen zu bekommen, jedenfalls bin ich f&uuml;r jeden sachdienlichen Hinweis dankbar :-P. Ansonsten verschenke ich das Ger&auml;t eben an jemanden, mit laufender Software aber kaputtem Drucker..... Ach ja:&nbsp; Derzeit l&auml;uft die Systemwiederherstellung. 
			</p>
			 ]]></description>
		</item>
		<item>
			<title>Eclipse Plugin zur Aufzeichnung von Programmieraktivitäten</title>
			<link>http://www.josupeit.com/weblog~informatik-und-technik~java,eclipse-plugin-zur-aufzeichnung-von-programmieraktivitaeten.html</link>
			<guid>http://www.josupeit.com/front_content.php?lang=1&amp;idart=78</guid>
			<pubDate>Mon, 23 Mar 2009 23:24:25 +0100</pubDate>
			<author>webmaster@josupeit.com (Manuel Josupeit-Walter)</author>
			<description><![CDATA[ <p>
			Von September bis Dezember 2008 wurde an der Universit&auml;t Duisburg-Essen eine empirische Studie an Softwareentwicklern durchgef&uuml;hrt. Im Rahmen dieser Studie der Form eines kontrollierten Experimentes, war es Aufgabe der Teilnehmer, typische Entwicklungsaufgaben zun&auml;chst rein objektorientiert, schlie&szlig;lich mit Hilfe einer aspektorientierten Spracherweiterung zu bew&auml;ltigen. Da die Auswertung der Ergebnisse am Ende der Studie durchgef&uuml;hrt werden sollte und es derzeit nahezu unm&ouml;glich ist, ein freies Tool im Internet zu finden, dass diese Aufgabe meistert, musste eine Entwicklungsumgebung geschaffen werden, die es erm&ouml;glicht, alle Aktivit&auml;ten jedes Entwicklers m&ouml;glichst detailliert nachvollziehen, und den Bearbeitungsstand der Aufgaben zu jedem Zeitpunkt reproduzieren zu k&ouml;nnen. Vor einiger Zeit berichtete ich bereits <a href="front_content.php?idart=66&amp;idcat=14&amp;lang=1&amp;client=1">hier</a> dar&uuml;ber.
			</p>
			<p>
			Ab sofort steht die Ausarbeitung zur Entwicklung dieses Plugins zum <a href="static~downloads,index.html?file=fa14d4fe2f19414de3ebd9f63d5c0169" title="Entwicklung eines Eclipse Plugins zur Aufzeichnung von Programmieraktivit&auml;ten in empirischen Experimenten">Download</a> zur Verf&uuml;gung. Das Plugin selbst ist sowohl in kompilierter Form, als auch als Quellcode der PDF-Datei im Bin&auml;ren ISO-Format angeh&auml;ngt. 
			</p>
			 ]]></description>
		</item>
		<item>
			<title>Reporter ohne Grenzen gegen Internetzensur</title>
			<link>http://www.josupeit.com/weblog~informatik-und-technik~web,reporter-ohne-grenzen-gegen-internetzensur.html</link>
			<guid>http://www.josupeit.com/front_content.php?lang=1&amp;idart=76</guid>
			<pubDate>Thu, 12 Mar 2009 22:19:06 +0100</pubDate>
			<author>webmaster@josupeit.com (Manuel Josupeit-Walter)</author>
			<description><![CDATA[ <div align="center">
			<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" width="400" height="600">
				<param name="width" value="400" />
				<param name="height" value="600" />
				<param name="src" value="http://www.reporter-ohne-grenzen.de/uploads/media/ROG_Banner_Welttag_gegen_Internetzensur2009_01.swf" />
				<embed type="application/x-shockwave-flash" width="400" height="600" src="http://www.reporter-ohne-grenzen.de/uploads/media/ROG_Banner_Welttag_gegen_Internetzensur2009_01.swf"></embed>
			</object>
			</div>
			 ]]></description>
		</item>
		<item>
			<title>Facebook Account (endlich) löschen</title>
			<link>http://www.josupeit.com/weblog~informatik-und-technik~web,facebook-account-loeschen.html</link>
			<guid>http://www.josupeit.com/front_content.php?lang=1&amp;idart=75</guid>
			<pubDate>Wed, 11 Mar 2009 22:36:14 +0100</pubDate>
			<author>webmaster@josupeit.com (Manuel Josupeit-Walter)</author>
			<description><![CDATA[ <p>
			Wieso genau ich mich damals bei Facebook registriert habe, ist mir heute ein R&auml;tsel. Weshalb dann noch mein Account so lange in diesem Datenschutzparadies vor sich her vegetiert ist, ohne dass es mich wirklich interessiert hat ist eigentlich unverzeihlich, wenn man bedenkt, wie viel Wert ich im Normalfall auf den Schutz meiner privaten Daten lege. Bereits vor Monaten wollte ich dem ein Ende setzen, doch es erwies sich damals als nicht m&ouml;glich seinen Account zu l&ouml;schen; lediglich eine &quot;Deaktivierung&quot; war m&ouml;glich. Nachdem ich vor zwei Wochen den Support anschieb, um meine Daten entg&uuml;ltig zu l&ouml;schen verwies man mich auf eine Seite, &uuml;ber die ich das selbst machen k&ouml;nne. Heute suchte ich abermals vergebens den Link zur L&ouml;schseite, bis ich auf <a href="javascript:void(0)" rev="http://www.fuellhaas.com/2008/08/13/facebook-account-endgultig-loschen/">einem Blog</a> <b><i>[Update vom 25.02.2010: Die Seite ist leider nicht mehr erreichbar]</i></b> endlich einen Direktlink fand, &uuml;ber den man seinen Account nach einer Frist von 14 Tagen endg&uuml;ltig l&ouml;schen kann.
			</p>
			<p>
			Diese Tortur ist nicht nur nervig, sondern geradezu eine Farce und zu Zeiten, in denen Datenschutz gl&uuml;cklicherweise &ouml;fter in den Medien genannt und dennoch viel zu klein geschrieben wird unverzeihlich! Aus diesem Grunde gibt es von mir als Belohnung f&uuml;r Facebook sogar einen Backlink: <a href="http://www.facebook.com/help/contact.php?show_form=delete_account" target="_blank" title="Facebook-Account l&ouml;schen">Zur L&ouml;schseite</a>.
			</p>
			<p>
			Liebe Facebook-Betreiber (wer auch immer ihr sein m&ouml;gt, ich m&ouml;chte nicht auch noch Euer Impressum suchen): <b>Klarer Daumen nach unten!</b> 
			</p>
			 ]]></description>
		</item>
		<item>
			<title>FPS-3003 mit &quot;alter&quot; Firmware flashen</title>
			<link>http://www.josupeit.com/weblog~informatik-und-technik~linux,fps-3003-mit-alter-firmware-flashen.html</link>
			<guid>http://www.josupeit.com/front_content.php?lang=1&amp;idart=73</guid>
			<pubDate>Wed, 07 Jan 2009 17:33:04 +0100</pubDate>
			<author>webmaster@josupeit.com (Manuel Josupeit-Walter)</author>
			<description><![CDATA[ <p>
			Vor kurzem ist leider einer der beiden USB Ports meines LevelOne Printservers FPS-3003 abgeraucht. Damit ich nur das Ger&auml;t tauschen muss und nicht noch das Netzteil, habe ich mir den selben Printserver erneut bestellt - vermeindlich den selben.
			</p>
			<p>
			Die aktuelle Version 4 des Ger&auml;ts wird n&auml;mlich mit einer v&ouml;llig anderen Firmware ausgeliefert, die direktes drucken &uuml;ber LPR Warteschlagen oder RAW Ports 9100 und 9101 nicht mehr unterst&uuml;tzt. Ausschlie&szlig;lich die Fileserver-Funktionen &uuml;ber Samba und FTP sind geblieben, alles &Uuml;brige wird durch eine neue Software ersetzt, die (ausschlie&szlig;lich unter Windows) mit den angeschlossenen Druckern verbinden kann. Die Firmware l&auml;sst sich zwar &uuml;ber die Weboberfl&auml;che updaten, allerdings kann keine Firmware f&uuml;r Ger&auml;teversion 3 installiert werden, die die gew&uuml;nschte Funktionalit&auml;t auf dem augenscheinlich baugleichen Ger&auml;t Version 4 bereitstellt.
			</p>
			<p>
			&Uuml;ber einen Umweg l&auml;sst sich dennoch die <a href="http://de.level1.com/support_download.php?searchdl=FPS-3003&amp;srch_firmware=1" target="_blank">Firmware Version 1.26</a> auf dem Ger&auml;t installieren: &uuml;ber <a href="http://de.wikipedia.org/wiki/TFTP" target="_blank">TFTP</a>. Vorraussetzung dazu ist ein entsprechender Client auf einem Host im Netzwerk. Unter Vista beispielsweise kann ein solcher &uuml;ber <i>Systemsteuerung/Programme und Funktionen/Windows-Funktionen ein- oder ausschalten</i> nachinstalliert werden, eine Installation unter Windows XP ist ebenfalls m&ouml;glich. Da TFTP ein einfaches und bekanntes Protokoll ist, gibt es aber auch f&uuml;r jede erdenkliche Linux Distribution entsprechende Clients.
			</p>
			<p>
			Nun muss der TFTP-Server des Printservers aktiviert werden. Dazu befindet sich ein Taster mit der Aufschrift <i>init</i> am Ger&auml;t, der gedr&uuml;ckt werden muss, w&auml;hrend die Stromversorgung des FPS-3003 zun&auml;chst getrennt und dann wiederhergestellt werden muss. Die blinkenden LEDs f&uuml;r beide USB-Ports signalisieren den erfolgreichen Start dieses &quot;Rettungsmodus&quot;. Alle Einstellungen gehen jedoch leider bei diesem Vorgang verloren, so auch die IP-Adressen, die in diesem Modus auch nicht via DHCP bezogen werden. Demzufolge muss der Client, von dem aus die Firmware geflasht werden soll zun&auml;chst in das selbe <a href="http://de.wikipedia.org/wiki/Subnetz" target="_blank">Subnetz</a> gebracht werden (Auslieferzustand des Printservers ist <span class="inline_code">192.168.1.10/24</span>), das hei&szlig;t, dem Host muss beispielsweise die IP-Adresse <span class="inline_code">192.168.1.1</span> und die Subnetzmaske <span class="inline_code">255.255.255.0</span> statisch zugewiesen werden, damit beide Ger&auml;te untereinander kommunizieren k&ouml;nnen.
			</p>
			<p>
			Nun muss &uuml;ber die Kommandozeile (in Windows XP und Vista erreichbar &uuml;ber <i>Start/Ausf&uuml;hren/cmd</i>) die Firmware auf das Ger&auml;t &uuml;bertragen werden. Damit dieser Vorgang erfolgreich abgeschlossen werden kann ist es n&ouml;tig, die Firmware-Datei (mit der Dateiendung .bin) in <span class="inline_code">app.bin</span> umzubenennen. Der anschlie&szlig;ende Konsolenaufruf<br />
			</p>
			<p class="code">
			tftp -i 192.168.1.10 PUT app.bin
			</p>
			<p>
			&uuml;bertr&auml;gt nun die Firmware aufs Ger&auml;t. Nun kann die Einrichtung &uuml;ber die Weboberfl&auml;che des Printservers beginnen: Viola, sogar die LPR und RAW Einstellungen lassen sich nun wieder vornehmen.
			</p>
			<p>
			Abschlie&szlig;end m&ouml;chte ich jedoch darauf aufmerksam machen, dass flashen von Hardware immer auch schief gehen und das Ger&auml;t dadurch kaputt gehen kann. Daher empfiehlt sich auch eine Sicherung der aktuellen Firmware (auch das ist sicher &uuml;ber TFTP m&ouml;glich, allerdings habe ich das nicht getestet), um den Ursprungszustand wiederherstellen zu k&ouml;nnen. Ob durch die Ersetzung der Firmware durch eine andere Version die Herstellergarantie erlischt, ist mir leider nicht bekannt. 
			</p>
			<p>
			In diesem Sinne: Viel Spa&szlig; beim flashen... 8-)
			</p>
			 ]]></description>
		</item>
		<item>
			<title>Rot und Blau vertauscht</title>
			<link>http://www.josupeit.com/weblog~informatik-und-technik,rot-und-blau-vertauscht.html</link>
			<guid>http://www.josupeit.com/front_content.php?lang=1&amp;idart=67</guid>
			<pubDate>Sun, 12 Oct 2008 17:42:48 +0200</pubDate>
			<author>webmaster@josupeit.com (Manuel Josupeit-Walter)</author>
			<description><![CDATA[ <p>
			In der letzten Zeit verfolgte mich im B&uuml;ro ein interessantes Ph&auml;nomen: Mein Arbeitsplatzrechner zeigte konsequent rote Schrift in blauer Farbe an und andersherum. Anfangs hielt ich es f&uuml;r ein Problem der RaveReport Software, mit der ich Berichte f&uuml;r eine Delphi Anwendung schrieb, bis mir auffiel, dass sich das Problem durch alle Anwendungen an meinem PC zog. Komischerweise trat es nur bei Text auf, nicht bei Grafiken, und auch nur dann, wenn die Schrift eine Gr&ouml;&szlig;e von 14pt &uuml;berstieg, oder fett war. (Schade, ich hielt es f&uuml;r ein neues Feature, dass Google die Schlagworte der Suchergebnisse nun in Rot zeigt. ;-))
			</p>
			<p>
			Was die Ursache des Problems ist, lie&szlig; sich bis heute nicht kl&auml;ren, allerdings half es, die Kantengl&auml;ttung f&uuml;r Schriften abzuschalten oder auf ClearType umzustellen. F&uuml;r alle, die das selbe Problem haben: Einfach ausprobieren. F&uuml;r bessere L&ouml;sungen bin ich angesichts meiner nunmehr pixeligen Schriften sehr dankbar. :-)
			</p>
			 ]]></description>
		</item>
		<item>
			<title>Entwicklung mit Eclipse protokollieren</title>
			<link>http://www.josupeit.com/weblog~informatik-und-technik~java,entwicklung-mit-eclipse-protokollieren.html</link>
			<guid>http://www.josupeit.com/front_content.php?lang=1&amp;idart=66</guid>
			<pubDate>Sat, 04 Oct 2008 16:57:51 +0200</pubDate>
			<author>webmaster@josupeit.com (Manuel Josupeit-Walter)</author>
			<description><![CDATA[ <p>
			Im Zuge einer empirischen Studie an der Universit&auml;t Duisburg-Essen habe ich im Rahmen meines Projektseminars ein Eclipse Plugin in Java entwickelt, das es erm&ouml;glicht, alle Schritte eines Entwicklers m&ouml;glichst detailliert nachvollziehen - und entwickelten Quellcode rekonstruieren zu k&ouml;nnen.
			</p>
			<p>
			Das einzige Tool auf das ich gesto&szlig;en bin, das in irgendeiner Form zu einem solchen Zweck geeignet gewesen w&auml;re, hei&szlig;t <a href="http://www.eclipse.org/tptp/home/downloads/" target="_blank">Automated GUI Recorder</a> vom TPTP Projekt. Leider erwies es sich jedoch als leichter gesagt, als getan, dieses Plugin in einer Form zu erweitern, die den Anforderungen der Studie entsprachen, so scheiterte ich bereits am vollst&auml;ndigen Checkout des Quellcodes via CVS. Auch diverse Newsgroup Aufrufe verliefen im Sande, so dass selbst entwickeln die einzig brauchbare L&ouml;sung zu sein schien.
			</p>
			<p>
			So entstand also das Development Trace Plugin, das auf Eclipse Ganymede (3.4) l&auml;uft und s&auml;mtliche Aktionen, wie Commands (g&auml;ngige Operationen, wie Copy und Paste, Builds oder Saves), Fensterwechsel (Ge&ouml;ffnet, Aktiviert, Geschlossen), Runs (Run, Debug) und intern getriggerte Aktionen in einer PostgreSQL Datenbank speichert. S&auml;mtliche gesammelten Datens&auml;tze, so auch alle Dateien und Ordner des Workspaces, die vom mitgelieferten Builder als kompilierbar oder nicht kompilierbar markiert und gespeichert werden, werden hierbei mit einer Sitzung verkn&uuml;pft, die beim Eclipse Start angelegt wird. Ein Speichern aller &Auml;nderungen wird automatisch nach jeder Modifikation in einem Editorfenster (mit einer Verz&ouml;gerung von 2 Sekunden) angesto&szlig;en, so dass eine sehr genaue Rekonstruktion zeitlicher &quot;Snapshots&quot;gew&auml;hrleistet wird.
			</p>
			<p>
			Sobald die Auswertung der gesammelten Daten fertiggestellt und die Ergebnisse der Studie ver&ouml;ffentlicht wurden, werde ich das Plugin und die Quelltexte inklusive der verwendeten Datenbankschemata und Ant-Scripte zur automatischen Rekonstruktion und Unit-Tests unter einer entsprechenden Lizenz im Downloadbereich ver&ouml;ffentlichen. 
			</p>
			 ]]></description>
		</item>
		<item>
			<title>Visual Studio 2008 auf Vista x64</title>
			<link>http://www.josupeit.com/weblog~informatik-und-technik~dotnet,visual-studio-2008-auf-vista-x64.html</link>
			<guid>http://www.josupeit.com/front_content.php?lang=1&amp;idart=64</guid>
			<pubDate>Fri, 03 Oct 2008 15:23:44 +0200</pubDate>
			<author>webmaster@josupeit.com (Manuel Josupeit-Walter)</author>
			<description><![CDATA[ <p>
			Seit geraumer Zeit bin ich endlich im Besitz meines neuen Rechners, allerdings bescherte mir die Installation von Visual Studio 2008 auf der 64-Bit Version von Windows Vista so einige Probleme, die auch <a href="http://grumpywookie.wordpress.com/2008/02/12/problems-installing-visual-studio-2008-on-vista-x64/" target="_blank">hier</a> bereits im Februar gebloggt wurden. (Leider bin ich trotz emsigen Googlens nicht auf eine solche Probleml&ouml;sung gesto&szlig;en.)
			</p>
			<p>
			Trotz einer frischen Installation von Windows und allen n&ouml;tigen Treibern scheiterte die Installation von Visual Studio bereits beim .NET Framework 3.5 mit einer ganzen Reihe roter Kreuze. Zudem erfreute ich mich seither daran, dass mein neuer Rechner nun ca. 10 Minuten (!!) zum booten brauchte, bis ich letztlich meinen Desktop vor mir sah (nicht, dass ich jetzt in der Lage gewesen w&auml;re, den PC in irgend einer Form zu bedienen :-)).
			</p>
			<p>
			Die L&ouml;sung des Problemes jedoch hei&szlig;t Service Pack 1 f&uuml;r Windows Vista x64, dass Microsoft gl&uuml;cklicherweise <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=874a414b-32b2-41cc-bd8b-d71eda5ec07c&amp;DisplayLang=de" target="_blank">online zum Download</a> bereitstellt. Schade allerdings, dass dort explizit vom Download abgeraten wird, da die Updates in Vista automatisch erfolgten -- Leider wurde, jedenfalls bei mir, dieses Service Pack nicht per Auto-Update ausgeliefert. Vielen Dank, Mr. Ballmer, das bescherte mir 10 Stunden Arbeit... 
			</p>
			 ]]></description>
		</item>
		<item>
			<title>Empirische Forschung an Objektorientierung</title>
			<link>http://www.josupeit.com/weblog~informatik-und-technik,empirische-forschung-an-objektorientierung.html</link>
			<guid>http://www.josupeit.com/front_content.php?lang=1&amp;idart=60</guid>
			<pubDate>Sat, 05 Jul 2008 18:02:08 +0200</pubDate>
			<author>webmaster@josupeit.com (Manuel Josupeit-Walter)</author>
			<description><![CDATA[ <p>
			Dass Software ein wesentlicher Bestandteil unserer Gesellschaft ist, stellt in der heutigen
			Zeit selbst ein Laie nicht mehr in Frage. Viele Ausbildungsbetriebe und
			Hochschulen lehren k&uuml;nftiges IT-Personal Design und Entwicklung von Software, oft in
			objektorientierten Hochsprachen, wie Java, C++ oder C#.
			</p>
			<p>
			Dennoch gibt es Alternativen zur Entwicklung dieser Software, wie die Nutzung prozeduraler
			oder logischer Programmiersprachen, wie Pascal oder Prolog. In der Praxis stellt
			sich daher h&auml;ufig die Frage, auf welche Weise ein Softwareprojekt entwickelt werden
			soll.
			</p>
			<p>
			Die <a href="front_content.php?idart=48&amp;idcat=13&amp;lang=1&amp;client=1&amp;file=5e9f92a01c986bafcabbafd145520b13">hier zum Download</a> bereitgestellte Arbeit setzt sich mit dem Thema empirischer Forschung an Objektorientierung kritisch
			auseinander und beleuchtet, in wie fern Empirie als Entscheidungsgrundlage f&uuml;r
			die Wahl bestimmter Softwaredesigns oder Entwicklungsalternativen dienen kann.
			</p>
			<p>
			Viel Spa&szlig; beim Lesen...
			</p>
			 ]]></description>
		</item>
		<item>
			<title>Systemweiter Singleton in C#: Nachtrag</title>
			<link>http://www.josupeit.com/weblog~informatik-und-technik~dotnet,systemweiter-singleton-nachtrag.html</link>
			<guid>http://www.josupeit.com/front_content.php?lang=1&amp;idart=59</guid>
			<pubDate>Fri, 16 May 2008 13:29:02 +0200</pubDate>
			<author>webmaster@josupeit.com (Manuel Josupeit-Walter)</author>
			<description><![CDATA[ <p>
			Vor einiger Zeit berichtete ich <a href="front_content.php?idart=29&amp;idcat=10&amp;lang=1&amp;client=1">hier</a> &uuml;ber die Implementierung eines systemweiten Singleton in C#. Trotz Freigabe des registrierten Mutexes bei Terminierung des Hauptprozesses und damit einhergehender Vernichtung der &uuml;ber die Anwendungsdom&auml;ne hinaus bereitgestellten Objekte, wurde bei Aufruf der GetInstance-Methode kein neues Objekt erzeugt (vielen Dank f&uuml;r den Hinweis, Tom).
			</p>
			<p>
			Diesem Problem habe ich etwas Zeit gewidmet und eine L&ouml;sung zum <a href="front_content.php?idcat=13&amp;lang=1&amp;client=1">Download</a> bereitgestellt. 
			</p>
			 ]]></description>
		</item>
		<item>
			<title>Capchas eingesetzt</title>
			<link>http://www.josupeit.com/weblog~informatik-und-technik~web,capchas-eingesetzt.html</link>
			<guid>http://www.josupeit.com/front_content.php?lang=1&amp;idart=57</guid>
			<pubDate>Wed, 07 May 2008 12:31:58 +0200</pubDate>
			<author>webmaster@josupeit.com (Manuel Josupeit-Walter)</author>
			<description><![CDATA[ <p>
			Nachdem ich anf&auml;nglich verschont wurde, sind nun doch endg&uuml;ltig Spam-Roboter auf meinen Blog aufmerksam geworden, so dass ich nun leider doch zu weiteren Mitteln greifen muss, um nicht t&auml;glich zig Spam-Kommentare l&ouml;schen zu m&uuml;ssen. Leider bleibt es mal wieder an den &quot;normalen&quot; Lesern h&auml;ngen, denn seit heute verwende ich, wie viele andere auch, visuelle Best&auml;tigungen. Das hei&szlig;t, wer k&uuml;nftig einen Kommentar schreiben m&ouml;chte, muss nun drei Buchstaben aus einem Bild ablesen und in ein K&auml;stchen eingeben.
			</p>
			<p>
			Vorher hatte ich einen Mechanismus verwendet, der bei Betreten dieser Seite die IP-Adresse des Besuchers mit t&auml;glich mehrfach aktualisierten Spammer-Datenbanken abglich. Da aber seit geraumer Zeit vermehrt IP-Adressen entf&uuml;hrter Rechner nur noch einmal verwendet werden, verlor diese Methode leider ihre Wirkung, so dass bedauerlicher Weise viele Leser von diesem Blog ausgesperrt wurden. Daher nochmal an dieser Stelle: Es tut mir wirklich leid, dass der Kampf gegen Spam immer auf Ihren Schultern ausgetragen wird, lieber Leser. Trotzdem hoffe ich, dass Sie mit der visuellen Best&auml;tigung kein Problem haben.
			</p>
			<p>
			Also: Nicht beirren lassen und flei&szlig;ig weiter kommentieren...&nbsp;
			</p>
			 ]]></description>
		</item>
		<item>
			<title>Contenido 4.8.1 erschienen</title>
			<link>http://www.josupeit.com/weblog~informatik-und-technik~web,contenido-481-erschienen.html</link>
			<guid>http://www.josupeit.com/front_content.php?lang=1&amp;idart=56</guid>
			<pubDate>Tue, 22 Apr 2008 17:45:00 +0200</pubDate>
			<author>webmaster@josupeit.com (Manuel Josupeit-Walter)</author>
			<description><![CDATA[ <p>
			Seit einigen Tagen ist sie da, die neuste Version des OpenSource CMS Contenido. Doch bereits kurz nach Veröffentlichung der Version 4.8.1 wurde auch diesmal direkt Version 4.8.2 hinterhergeschoben (Version 4.6.22 erschien ebenfalls am 04. Oktober 2007, Version 4.6.23 wurde am 22. Oktober veröffentlicht).
			</p>
			<p>
			Zunächst fällt ein komplett neues Design ins Auge: Nicht nur, dass der vom Hersteller for-four-business mitgelieferte "Beispielmandant" überarbeitet wurde, auch die Verwaltungsoberfläche, das sogenannte "Backend" erscheint in neuem Glanz. Erstes Manko: Selbst ich als geübter Contenido-Entwickler muss mich zunächst an die neuen Icons gewöhnen, so wird scheinbar nicht jedem auf Anhieb klar, dass ein Rechteck mit Schatten nun für "Artikel duplizieren" steht. Außerdem wirkt der neu eingeführte Hover-Effekt für die Hauptnavigation sehr träge, so dass ich bereits nach fünf Minuten Test genervt darüber war, dass ich, anstatt wie früher auf "Content" zu klicken, nun mit der Maus darüber verweilen muss, um zur gewünschten Verwaltungsseite zu gelangen.
			</p>
			<p>
			Einige Dinge sind dafür besser gelöst, so lassen sich nun beispielsweise Kategorien komfortabler erzeugen und im selben Schritt online setzen. Außerdem wurde das CMS um Workflows erweitert, so dass nun (offenbar) definiert werden kann, dass Redakteure Artikel zwar verfassen, ihre eigenen Artikel jedoch nicht selbst publizieren dürfen. Auch ein Linkchecker und eine Erweiterung namens "Content Allocation" wurden hinzugefügt (Sobald ich mir diese drei Dinge angesehen habe, werde ich an dieser Stelle darüber berichten).
			</p>
			<p>
			Dennoch scheint es sich bei allen "neuen Features" größtenteils um Schönheitsreparaturen zu handeln, so dass selbst seit September 2007 bekannte Bugs (vgl. <a href="http://forum.contenido.org/viewtopic.php?t=18175" title="Meta-Tags mit . in der Bezeichnung nicht möglich" target="_blank">http://forum.contenido.org/viewtopic.php?t=18175</a>) nicht behoben wurden. Eine Integration einer komfortablen mod_rewrite Kompatiblität ist seitens 4fB wieder einmal nicht integriert worden.
			</p>
			<p>
			Leider werde ich also - GPL sei Dank - wieder einmal meine eigene Contenido-Version aus eigenen Ergänzungen der Version 4.6.23 (wie verbesserte mod_rewrite-Unterstützung, so dass Artikel beispielsweise nicht gezwungenermaßen die Endung .html haben müssen, o.ä., Angabe eines Wertes zu Artikelspezifikationen und diverser Bugfixes wie oben angeführt) zusammenbauen. Schade, dass der Hersteller nicht einmal Fehler behebt, dessen Lösung die Community bereits ins Forum gestellt hat. 
			</p>
			 ]]></description>
		</item>
		<item>
			<title>TrueCrypt - Verschlüsselung für Jedermann</title>
			<link>http://www.josupeit.com/weblog~informatik-und-technik,truecrypt-verschluesselung-fuer-jedermann.html</link>
			<guid>http://www.josupeit.com/front_content.php?lang=1&amp;idart=46</guid>
			<pubDate>Fri, 28 Mar 2008 11:49:03 +0100</pubDate>
			<author>webmaster@josupeit.com (Manuel Josupeit-Walter)</author>
			<description><![CDATA[ <p>
			Zu Zeiten des Internet sollte sich jeder Gedanken &uuml;ber die Sicherheit seiner Daten machen. Wer Dateien per Mail verschickt, konnte bereits zu Zeiten PGPs effiziente asymmetrische Verschl&uuml;sselungsmechanismen einsetzen, um sensible Daten &uuml;bers Netz &quot;zu jagen&quot;. Seit PGP ab Version 8 nicht mehr frei erh&auml;ltlich ist, tritt die OpenSource Software GPG in diese Fu&szlig;stapfen. Heute ist es selbst bei Downloads gang und g&auml;be, GPG Hashwerte mit anzugeben, damit der Nutzer auch wirklich sicher sein kann, dass die Dateien, die er herunter l&auml;dt nicht ver&auml;ndert wurden. Zu diesem Thema habe ich bereits <a href="front_content.php?idart=41&amp;idcat=8&amp;lang=1&amp;client=1" title="Die eigene Privatsph&auml;re">hier</a> einen kurzen Artikel geschrieben. 
			</p>
			<p>
			Allerdings sind nicht nur Daten vor fremden Augen zu sch&uuml;tzen: Gerade jetzt, wo USB Sticks Wegwerf-Ware geworden sind und Speicher immer g&uuml;nstiger wird sollte man sich im Klaren dar&uuml;ber sein, dass auch auf tragbaren Medien (dazu z&auml;hle ich auch Notebooks) gesch&uuml;tzt werden m&uuml;ssen. Die Antwort auf die Frage &quot;Wie denn?&quot; hei&szlig;t in diesem Fall: <a target="_blank" href="http://www.truecrypt.org">TrueCrypt</a>! 
			</p>
			<p>
			TrueCrypt ist, wie GPG, eine freie Verschl&uuml;sselungssoftware, die virtuelle Laufwerke in einzelnen Dateien auf der Festplatte anlegen und verschl&uuml;sseln kann. Sogar ganze Partitionen, wie USB-Sticks oder gar die Systempartition, auf der in vielen F&auml;llen Windows installiert ist, verschl&uuml;sselt das Tool souver&auml;n - sogar nachtr&auml;glich. Dabei werden als Algorithmen derzeit AES, Twofish und Serpent unterst&uuml;tzt und k&ouml;nnen wahlweise sogar &quot;in Reihe&quot; ausgef&uuml;hrt werden. 
			</p>
			<p>
			Nat&uuml;rlich verschl&uuml;ssele ich seit geraumer Zeit auf meinem Linux-System zuhause diverse Festplatten, allerdings war mir f&uuml;r Windows bisher keine gescheite Software bekannt. Nun habe ich vor zwei Wochen die Festplatte meines Notebooks mit TrueCrypt Verschl&uuml;sselt und ich bin begeistert. TrueCrypt legt sich dabei im MBR der Festplatte ab und wartet bereits beim Anschalten des PCs auf ein Passwort, um die Daten zu entschl&uuml;sseln. Ohne Passwort l&auml;uft nun nichts mehr; so sind zumindest meine Daten sicher, falls mein Notebook oder meine USB-Sticks gestohlen werden. 
			</p>
			<p>
			In diesem Sinne, Pr&auml;dikat des Autors: Sehr empfehlenswert! 
			</p>
			<p>
			<br />
			Als &quot;Schmankerl&quot; f&uuml;r meinen speziellen Apple-Freund: Die Software gibts f&uuml;r Windows, Linux <b>und</b> Mac (ab OS X)! In diesem Sinne: Happy encrypting... 
			</p>
			 ]]></description>
		</item>
		<item>
			<title>Die eigene Privatsphäre</title>
			<link>http://www.josupeit.com/weblog~informatik-und-technik,die-eigene-privatsphaere.html</link>
			<guid>http://www.josupeit.com/front_content.php?lang=1&amp;idart=41</guid>
			<pubDate>Thu, 06 Mar 2008 12:02:17 +0100</pubDate>
			<author>webmaster@josupeit.com (Manuel Josupeit-Walter)</author>
			<description><![CDATA[ <p>
			Als ich <a href="http://www.thelackier.de/" target="_blank" title="thelackier">Sascha</a> letzten Samstag beim Umzug geholfen habe, hab ich mich mal wieder nett mit <a href="http://www.schlitt.info/" target="_blank">Toby</a> unterhalten k&ouml;nnen, diesmal &uuml;ber Datenschutz, Verschl&uuml;sselung, Zertifikate und sonstigen Informatiker-Smalltalk. Grob ging es darum, dass nicht nur viele Menschen nicht wissen, wie sie unter anderem im Netz sorgsam mit ihren Daten umgehen sollten, vielmehr fehlt teils gar das Interesse daran. Um nun ein wenig Aufkl&auml;rung zu betreiben, hat Toby schon einen Eintrag zum Thema in seinem Blog geschrieben <span class="nobr">(<a href="http://schlitt.info/applications/blog/index.php?/archives/584-Privacy-problems-explained.html" target="_blank">Quelle</a>&nbsp;<img src="upload/grafiken/english.gif" alt="Englische Seite" align="texttop" height="12" width="18" />)</span> und freundlicherweise eine nette Rundmail geschickt, die auch mich erreicht hat. Dem m&ouml;chte ich mich anschlie&szlig;en und poste an dieser Stelle ebenfalls den Link zu einem netten Flash-Video:
			</p>
			<p>
			<a href="http://eckpfeiler.net/panopticom/swf/index.htm" target="_blank">http://eckpfeiler.net/panopticom/swf/index.htm</a>
			</p>
			<p>
			Also einfach mal reinschauen, es lohnt sich!
			</p>
			<hr />
			<u>Weitere Empfehlungen:</u>
			<p>
			GNU Privacy Guard: <a href="http://www.gnupg.org/" target="_blank">http://www.gnupg.org/</a><br />
			Enigmail: <a href="http://enigmail.mozdev.org/" target="_blank">http://enigmail.mozdev.org/</a><br />
			Bundestrojaner: <a href="http://www.bundestrojaner.net/" target="_blank">http://www.bundestrojaner.net/</a><br />
			Virtuelles Datenschutzb&uuml;ro: <a href="http://www.datenschutz.de/" target="_blank">http://www.datenschutz.de/</a>
			</p>
			 ]]></description>
		</item>
		<item>
			<title>&quot;noindex&quot; im rel-Attribut</title>
			<link>http://www.josupeit.com/weblog~informatik-und-technik~web,noindex-im-rel-attribut.html</link>
			<guid>http://www.josupeit.com/front_content.php?lang=1&amp;idart=40</guid>
			<pubDate>Wed, 05 Mar 2008 20:34:20 +0100</pubDate>
			<author>webmaster@josupeit.com (Manuel Josupeit-Walter)</author>
			<description><![CDATA[ <p>
			Seit Google 2005 vorgemacht hat, wie man einzelne Links von der &quot;Verfolgung&quot; durch Suchmaschinen ausschlie&szlig;t <span class="nobr">(<a href="http://googleblog.blogspot.com/2005/01/preventing-comment-spam.html" target="_blank">Quelle</a> <img src="upload/grafiken/english.gif" alt="English Version" align="texttop" height="12" width="18" />)</span>, haben die meisten gro&szlig;en Suchmaschinen nachgezogen. An vielerlei Stellen wird Protest oder F&uuml;rsprache diesbez&uuml;glich laut, dem m&ouml;chte ich mich an dieser Stelle nicht anschlie&szlig;en. Vielmehr ist mir folgendes durch den Kopf gegangen: In Zeiten, in denen k&uuml;nftige Arbeitgeber f&auml;higen Leuten den Arbeitsplatz verweigern, weil sie zum Thema Umwelt in Greenpeace-Manier ihre Meinung mittels Kommentar in einem Blog kund getan haben, muss es doch m&ouml;glich sein, nicht nur Hyperlinks das <span class="inline_code">nofollow</span> Attribut zu &uuml;bergeben, sondern auch Teile einer Seite von der Indizierung durch Google &amp; Co. auszuschlie&szlig;en w&auml;hrend die Seite als Ganzes im Index bleibt.
			</p>
			<p class="code" rel="noindex">
			&lt;div rel=&quot;noindex&quot;&gt;<br />
			<span class="inaktiv">// Nicht indizierter Content //</span><br />
			&lt;/div&gt;
			</p>
			<p>
			Dieses Beispiel w&auml;re eine M&ouml;glichkeit daf&uuml;r, obgleich auch hier der Einsatz von <span class="inline_code">noindex </span>im Attribut rel semantisch falsch ist, den im obigen <span class="inline_code">div </span>eingeschlossenen Content (beispielsweise Blog-Kommentare auf Wunsch des Autors) &uuml;ber die Keywordsuche auszuschlie&szlig;en. Mit allen anderen Tags des <a href="http://de.wikipedia.org/w/index.php?title=Robots_Exclusion_Standard&amp;oldid=42855527" target="_blank">Robots Exclusion Standard</a> w&uuml;rde das &uuml;brigens analog funktionieren...
			</p>
			 ]]></description>
		</item>
		<item>
			<title>Systemweiter Singleton in C#</title>
			<link>http://www.josupeit.com/weblog~informatik-und-technik~dotnet,erweiterung-zum-globalen-singleton.html</link>
			<guid>http://www.josupeit.com/front_content.php?lang=1&amp;idart=29</guid>
			<pubDate>Wed, 19 Dec 2007 15:51:38 +0100</pubDate>
			<author>webmaster@josupeit.com (Manuel Josupeit-Walter)</author>
			<description><![CDATA[ <p>
			Am 21. November, also vor gut einem Monat habe ich in meinem Artikel <a href="front_content.php?idart=23&amp;idcat=10&amp;lang=1&amp;client=1">Singleton als vererbte Klasse am Beispiel C#</a> gezeigt, wie das Singleton Entwurfsmuster so implementiert werden kann, dass eine Klasse lediglich von einer Singleton-Oberklasse erben muss, um nicht mehr als einmal in der aktuellen Applikationsdom&auml;ne instanziiert werden zu k&ouml;nnen. Wie versprochen m&ouml;chte ich die damals Schritt f&uuml;r Schritt entwickelte Klasse heute so ausbauen, dass ein systemweiter Singleton realisiert werden kann. Dadurch kann von einer Klasse &uuml;ber die Applikationsdom&auml;ne hinaus nur ausschlie&szlig;lich eine Instanz existieren und wird es sehr einfach m&ouml;glich, dass eine Anwendung beispielsweise nur einmal gestartet werden kann und jeder weitere Start lediglich das Hauptfenster in den Vordergrund holt.
			</p>
			<p>
			Damit allerdings zwei Prozesse eines Systemes miteinander kommunizieren k&ouml;nnen, wird ein Datenkanal ben&ouml;tigt, &uuml;ber den dann ein Prozess von einem anderen ferngesteuert werden kann. Bitte behalten Sie also die folgende Illustration w&auml;hrend des lesens im Hinterkopf, es wird Ihnen das Leben etwas erleichtern:&nbsp;
			</p>
			<p>
			&nbsp;
			</p>
			<div style="text-align: center">
			<img src="upload/grafiken/remoting.gif" alt="Remoting Illustration" border="0" height="248" width="501" />
			</div>
			<br />
			<p>
			&nbsp;
			</p>
			<p>
			Bevor ich nun beginne, m&ouml;chte ich kurz den letzten Stand in Erinnerung rufen: Wir entwickelten eine <span class="inline_code">SingletonProvider</span> Klasse, die alle Instanzen im eigentlichen Sinne verwaltet hat. Eine Vererbung fand im Anschluss daran &uuml;ber die Klasse <span class="inline_code">SingletonBase</span> statt:
			</p>
			<br />
			<h4>SingletonProvider</h4>
			<span class="code"><span class="schluesselwort">using </span>System;<br />
			<span class="schluesselwort">using </span>System.Collections.Generic;<br />
			<span class="schluesselwort">using </span>System.Text;<br />
			<span class="schluesselwort">using </span>System.Collections;<br />
			<span class="schluesselwort">using </span>System.Reflection;<br />
			<br />
			<span class="schluesselwort">public static class</span> <span class="objekt">SingletonProvider</span><br />
			{<br />
			&nbsp; <span class="schluesselwort">private static</span> <span class="objekt">Hashtable </span>Selfs = <span class="schluesselwort">new </span>Hashtable();<br />
			&nbsp; <span class="schluesselwort">private static object</span> Lock&nbsp;&nbsp;&nbsp;&nbsp; = <span class="schluesselwort">new </span>Object();<br />
			<br />
			&nbsp; <span class="schluesselwort">public static</span> T GetInstance&lt;T&gt;(<span class="schluesselwort">out bool</span> New)<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">where </span>T: <span class="schluesselwort">class </span><span class="kommentar">// Jede Klasse ist erlaubt</span><br />
			&nbsp; {<br />
			&nbsp;&nbsp;&nbsp; <span class="kommentar">// Auf &ouml;ffentlichen Konstruktor pr&uuml;fen</span><br />
			&nbsp;&nbsp;&nbsp; <span class="objekt">ConstructorInfo </span>checkCtor = (<span class="schluesselwort">typeof</span>(T)).GetConstructor(<span class="objekt">Type</span>.EmptyTypes);<br />
			&nbsp;&nbsp;&nbsp; <br />
			&nbsp;&nbsp;&nbsp; <span class="kommentar">/*<br />
			&nbsp;&nbsp;&nbsp; &nbsp;* Falls es einen solchen Konstruktor gibt,<br />
			&nbsp;&nbsp;&nbsp; &nbsp;* schmei&szlig;en wir einen Fehler, da es dem <br />
			&nbsp;&nbsp;&nbsp; &nbsp;* Charakter eines Singleton widerspricht.<br />
			&nbsp;&nbsp;&nbsp; &nbsp;*/</span><br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">if </span>(checkCtor != <span class="schluesselwort">null</span>)<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="schluesselwort">throw new</span> InvalidOperationException(<span class="zeichenfolge">&quot;Singleton means that you don't have any public constructors&quot;</span>);<br />
			<br />
			&nbsp;&nbsp;&nbsp; <span class="kommentar">// Threadsynchronisation</span><br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">lock </span>(Lock) {<br />
			&nbsp;&nbsp;&nbsp; &nbsp; <span class="schluesselwort">if </span>(Selfs.ContainsKey(<span class="schluesselwort">typeof</span>(T).GUID))<br />
			&nbsp;&nbsp;&nbsp; &nbsp; {<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="kommentar">// Instanz existiert bereits</span><br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; New = <span class="schluesselwort">false</span>;<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="schluesselwort">return </span>(T)Selfs[<span class="schluesselwort">typeof</span>(T).GUID];<br />
			&nbsp;&nbsp;&nbsp; &nbsp; }<br />
			<br />
			&nbsp;&nbsp;&nbsp; &nbsp; <span class="kommentar">// Neue Instanz &uuml;ber Reflektion erstellen</span><br />
			&nbsp; &nbsp;&nbsp;&nbsp; <span class="objekt">ConstructorInfo </span>ctorInfo;<br />
			&nbsp;&nbsp;&nbsp; &nbsp; <br />
			&nbsp;&nbsp;&nbsp; &nbsp; <span class="kommentar">// Gesch&uuml;tzte Konstruktoren auslesen</span><br />
			&nbsp;&nbsp;&nbsp; &nbsp; ctorInfo = <span class="schluesselwort">typeof</span>(T).GetConstructor(<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">BindingFlags</span>.NonPublic | <br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; <span class="objekt">BindingFlags</span>.Instance,<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; <span class="schluesselwort">null</span>,<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; <span class="objekt">Type</span>.EmptyTypes,<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; <span class="schluesselwort">null</span><br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; );<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
			&nbsp;&nbsp;&nbsp; &nbsp; <span class="kommentar">// Konstruktor ohne Parameter aufrufen</span><br />
			&nbsp;&nbsp;&nbsp; &nbsp; T _Instanz = (T)ctorInfo.Invoke(<span class="schluesselwort">new object</span>[] { });<br />
			&nbsp;&nbsp;&nbsp; &nbsp; <br />
			&nbsp;&nbsp;&nbsp; &nbsp; <span class="kommentar">// Instanz der Hashtabelle zuf&uuml;hren</span><br />
			&nbsp;&nbsp;&nbsp; &nbsp; Selfs.Add(<span class="schluesselwort">typeof</span>(T).GUID, _Instanz);<br />
			&nbsp;&nbsp;&nbsp; &nbsp; New = <span class="schluesselwort">true</span>;<br />
			&nbsp;&nbsp;&nbsp; &nbsp; <br />
			&nbsp;&nbsp;&nbsp; &nbsp; <span class="schluesselwort">return </span>(T)Selfs[<span class="schluesselwort">typeof</span>(T).GUID];<br />
			&nbsp;&nbsp;&nbsp; }<br />
			&nbsp; }<br />
			&nbsp; <br />
			&nbsp; <span class="schluesselwort">public static</span> T GetInstance&lt;T&gt;()<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">where </span>T: <span class="schluesselwort">class</span><br />
			&nbsp; {<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">bool </span>_Trash;<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">return </span>GetInstance&lt;T&gt;(<span class="schluesselwort">out </span>_Trash);<br />
			&nbsp; }<br />
			}<br />
			</span>
			<br />
			<h4>SingletonBase</h4>
			<span class="code"><span class="schluesselwort">public abstract class</span> <span class="objekt">SingletonBase</span>&lt;T&gt;<br />
			&nbsp; <span class="schluesselwort">where </span>T: <span class="objekt">SingletonBase</span>&lt;T&gt;<br />
			{<br />
			&nbsp; <span class="schluesselwort">public static</span> T GetInstance(<span class="schluesselwort">out bool</span> New)<br />
			&nbsp; {<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">return </span><span class="objekt">SingletonProvider</span>.GetInstance&lt;T&gt;(<span class="schluesselwort">out </span>New);<br />
			&nbsp; }<br />
			&nbsp; <br />
			&nbsp; <span class="schluesselwort">public static</span> T GetInstance()<br />
			&nbsp; {<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">bool </span>_Trash;<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">return </span>GetInstance(<span class="schluesselwort">out </span>_Trash);<br />
			&nbsp; }<br />
			}<br />
			</span>
			<br />
			<p>
			Um nun zun&auml;chst die <span class="inline_code">SingletonProvider</span>-Klasse auszubauen, verwende ich einen sogenannten Mutex<a href="front_content.php?idart=29#fussnoten"><sup>1</sup></a>. Mutexe werden in aller Regel zur Prozesssynchronisation verwendet, das hei&szlig;t, um sicherzustellen, dass kritische Programmabschnitte nicht gleichzeitig ausgef&uuml;hrt werden k&ouml;nnen, um beispielsweise Dateninkonsistenzen zu vermeiden. Sie lassen sich allerdings auch f&uuml;r unseren Zweck nutzen, da Mutexe systemweit registriert werden. Da sich die n&ouml;tigen Klassen f&uuml;r Mutexe und unser folgendes Vorhaben aber in anderen Namensr&auml;umen (und Assemblies) befinden, m&uuml;ssen zun&auml;chst ein Verweis auf die Assembly <span class="inline_code">System.Runtime.Remoting</span> gesetzt - und die bekannten <span class="inline_code">using</span>-Direktiven um einige Namensr&auml;ume erg&auml;nzt werden, so dass unsere Klassendefinition <span class="inline_code">GlobalSingletonProvider</span> k&uuml;nftig von den folgenden Zeilen angef&uuml;hrt wird:<br />
			&nbsp;
			</p>
			<p class="code">
			<span class="schluesselwort">using </span>System;<br />
			<span class="schluesselwort">using </span>System.Threading;<br />
			<span class="schluesselwort">using </span>System.Runtime.InteropServices;<br />
			<span class="schluesselwort">using </span>System.Runtime.Remoting.Channels.Ipc;<br />
			<span class="schluesselwort">using </span>System.Runtime.Remoting.Channels;<br />
			<span class="schluesselwort">using </span>System.Runtime.Serialization.Formatters;<br />
			<span class="schluesselwort">using </span>System.Collections;<br />
			<span class="schluesselwort">using </span>System.Collections.Generic;<br />
			<span class="schluesselwort">using </span>System.Runtime.Remoting;<br />
			<span class="schluesselwort">using </span>System.Runtime.Serialization;<br />
			<span class="schluesselwort">using </span>System.Reflection;<br />
			<br />
			<span class="schluesselwort">public static class </span><span class="objekt">GlobalSingletonProvider</span><br />
			{ ... }
			</p>
			<br />
			<p>
			Dadurch aber m&uuml;ssen f&uuml;r jedes Singleton-Objekt nicht nur Instanzen verwaltet werden, sondern auch noch die zugeh&ouml;rigen Mutexe, die beim System registriert wurden. Hierzu wird unsere Liste von Deklarationen um eine Hashtabelle erweitert.<br />
			</p>
			<p class="code">
			<span class="schluesselwort">public static class</span> <span class="objekt">GlobalSingletonProvider</span><br />
			{<br />
			&nbsp; <span class="schluesselwort">private static </span><span class="objekt">Hashtable </span>Selfs&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = <span class="schluesselwort">new </span><span class="objekt">Hashtable</span>();<br />
			&nbsp; <span class="schluesselwort">private static </span><span class="objekt">Hashtable </span>ApplicationMutexes = <span class="schluesselwort">new </span><span class="objekt">Hashtable</span>();<br />
			&nbsp; <span class="schluesselwort">private static </span><span class="objekt">object </span>Lock&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = <span class="schluesselwort">new </span><span class="objekt">Object</span>();<br />
			<br />
			<span class="kommentar">&nbsp; // ... </span><br />
			}
			</p>
			<p>
			<br />
			Im Gegensatz zum herk&ouml;mmlichen SingletonProvider, wird im Rupf der Methode <span class="inline_code">GetInstance()</span> nun direkt nach der &Uuml;berpr&uuml;fung, ob bereits in der aktuellen Applikationsdom&auml;ne eine Instanz der Klasse existiert, ein neuer Mutex registriert, der als Namen die GUID, also eine absolut eindeutige ID der zu instanziierenden Klasse tr&auml;gt. Eine boolsche Variable <span class="inline_code">New </span>gibt hier an, ob dem System ein solcher Mutex bereits bekannt ist. Das n&auml;mlich ist genau dann der Fall, wenn bereits au&szlig;erhalb der Applikationsdom&auml;ne eine Instanz erstellt worden ist; der dort registrierte Mutex tr&auml;gt n&auml;mlich aufgrund der ID der Klasse den selben Namen. Jetzt wird &uuml;ber sogenannte Ipc Channels ein Remote-Proxy auf dieses Objekt geholt, so dass das bestehende Objekt quasi &quot;ferngesteuert&quot; werden kann. Als Resultat dieser Hintergrundarbeit k&ouml;nnen Sie auf dem Objekt arbeiten, als h&auml;tten Sie es in Ihrer Applikationsdom&auml;ne erzeugt (Achtung: Das hei&szlig;t nicht, dass sie auf dem Objekt arbeiten k&ouml;nnen, als h&auml;tten Sie es im gleichen Thread erzeugt. Beachten Sie Thread&uuml;bergreifende Vorg&auml;nge!), alle Aufrufe werden in Wahrheit allerdings transparent weitergereicht. Kann im Gegensatz dazu der Mutex beim System neu registriert werden, l&auml;sst das darauf schlie&szlig;en, dass es sich um eine neue Instanz der Klasse handelt. Auch in diesem Fall wird ein Ipc Kanal bereitgestellt und dar&uuml;ber das Objekt verf&uuml;gbar gemacht. Dieses Vorgehen bezeichnet man h&auml;ufig auch als Marshalling<a href="front_content.php?idart=29#fussnoten"><sup>2</sup></a>. Vorraussetzung f&uuml;r das Marshallen von Objekten ist allerings, dass diese Objekte von der Klasse <span class="inline_code">MarshalByRefObject</span> erben.
			</p>
			<p>
			Das folgende Listing zeigt nun die bisherigen Modifikationen an der herk&ouml;mmlichen <span class="inline_code">SingletonProvider</span>-Klasse, bereits bekannte Zeilen sind hier allerdings ausgegraut, damit deutlich wird, welche neuen Anweisungen unserem Vorhaben dienlich sind:
			</p>
			<p>
			<br />
			<span class="code"><span class="inaktiv">using System;<br />
			using System.Collections.Generic;<br />
			using System.Text;<br />
			using System.Collections;<br />
			using System.Reflection;<br />
			</span><span class="schluesselwort">using </span>System.Threading;<br />
			<span class="schluesselwort">using </span>System.Runtime.InteropServices;<br />
			<span class="schluesselwort">using </span>System.Runtime.Remoting.Channels.Ipc;<br />
			<span class="schluesselwort">using </span>System.Runtime.Remoting.Channels;<br />
			<span class="schluesselwort">using </span>System.Runtime.Serialization.Formatters;<br />
			<span class="schluesselwort">using </span>System.Runtime.Remoting;<br />
			<span class="schluesselwort">using </span>System.Runtime.Serialization;<br />
			<br />
			<span class="inaktiv">
			public static class</span> <span class="objekt">GlobalSingletonProvider</span><br />
			<span class="inaktiv">
			{<br />
			&nbsp; private static Hashtable Selfs&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = new Hashtable();<br />
			</span>&nbsp; <span class="schluesselwort">private static </span><span class="objekt">Hashtable </span>ApplicationMutexes = <span class="schluesselwort">new </span><span class="objekt">Hashtable</span>();<br />
			<span class="inaktiv">
			&nbsp; private static object Lock&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = new Object();<br />
			<br />
			&nbsp; public static T GetInstance&lt;T&gt;(out bool New)<br />
			&nbsp;&nbsp;&nbsp; where T: </span>
			<span class="objekt">MarshalByRefObjekt </span><span class="inaktiv">// Jede Klasse ist erlaubt</span><span class="kommentar">, die von MarshalByRefObjekt erbt</span><br />
			&nbsp; <span class="inaktiv">{<br />
			&nbsp;&nbsp;&nbsp; // Auf &ouml;ffentlichen Konstruktor pr&uuml;fen<br />
			&nbsp;&nbsp;&nbsp; ConstructorInfo checkCtor = (typeof(T)).GetConstructor(Type.EmptyTypes);<br />
			&nbsp;&nbsp;&nbsp; <br />
			&nbsp;&nbsp;&nbsp; /*<br />
			&nbsp;&nbsp;&nbsp; &nbsp;* Falls es einen solchen Konstruktor gibt,<br />
			&nbsp;&nbsp;&nbsp; &nbsp;* schmei&szlig;en wir einen Fehler, da es dem <br />
			&nbsp;&nbsp;&nbsp; &nbsp;* Charakter eines Singleton widerspricht.<br />
			&nbsp;&nbsp;&nbsp; &nbsp;*/<br />
			&nbsp;&nbsp;&nbsp; if (checkCtor != null)<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new InvalidOperationException(&quot;Singleton means that you don't have any public constructors&quot;);<br />
			<br />
			&nbsp;&nbsp;&nbsp; // Threadsynchronisation<br />
			&nbsp;&nbsp;&nbsp; lock (Lock) {<br />
			&nbsp;&nbsp;&nbsp; &nbsp; if (Selfs.ContainsKey(typeof(T).GUID))<br />
			&nbsp;&nbsp;&nbsp; &nbsp; {<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // Instanz existiert bereits<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; New = false;<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return (T)Selfs[typeof(T).GUID];<br />
			&nbsp;&nbsp;&nbsp; &nbsp; }</span>
			<br />
			<br />
			<span class="kommentar">
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Mittels Mutex &uuml;berpr&uuml;fen, ob bereits eine Instanz existiert<br />
			</span>
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ApplicationMutexes.Add(<span class="schluesselwort">typeof</span>(T).GUID, <span class="schluesselwort">new </span><span class="objekt">Mutex</span>(<span class="schluesselwort">true</span>, <span class="schluesselwort">typeof</span>(T).GUID.ToString(), <span class="schluesselwort">out </span>New));<br />
			<br />
			<span class="kommentar">
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Ipc Kanal deklarieren</span><br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">IpcChannel </span>_Channel;<br />
			<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="schluesselwort">if </span>(!New)<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="kommentar">/*<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Falls in einer anderen Applikationsdom&auml;ne eine Instanz existiert,<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * muss diese nun als Remote-Proxy bereitgestellt werden, dazu<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * wird zun&auml;chst ein Ipc Channel registriert.<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */</span><br />
			<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">SoapServerFormatterSinkProvider </span>_ServProv = <span class="schluesselwort">new </span><span class="objekt">SoapServerFormatterSinkProvider</span>();<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _ServProv.TypeFilterLevel = <span class="objekt">TypeFilterLevel</span>.Full;<br />
			<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">SoapClientFormatterSinkProvider </span>_ClientProv = <span class="schluesselwort">new </span><span class="objekt">SoapClientFormatterSinkProvider</span>();<br />
			<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="kommentar">// Zur Serialisierung wird der Soap-Formatter verwendet</span><br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _Channel = <span class="schluesselwort">new </span><span class="objekt">IpcChannel</span>(<span class="schluesselwort">null</span>, _ClientProv, _ServProv);<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">ChannelServices</span>.RegisterChannel(_Channel, <span class="schluesselwort">false</span>);<br />
			<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="kommentar">// Nun wird die Instanz &uuml;ber diesen Kanal geholt</span><br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; T _Inst = (T)<span class="objekt">Activator</span>.GetObject(<span class="objekt">typeof</span>(T), <span class="zeichenfolge">&quot;ipc://localhost:9190/GlobalSingleton_&quot;</span> + <span class="schluesselwort">typeof</span>(T).GUID.ToString());<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Selfs.Add(<span class="schluesselwort">typeof</span>(T).GUID, _Inst);<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="schluesselwort">else</span><br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="kommentar">/*<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Es existiert keine Instanz, also wird eine neue Instanz erstellt,<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * der Mutex wird bei Applikationsende wieder freigegeben<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */</span><br />
			<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">AppDomain</span>.CurrentDomain.ProcessExit += <span class="schluesselwort">delegate</span>(<span class="schluesselwort">object</span> sender, <span class="objekt">EventArgs </span>e)<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="schluesselwort">try</span><br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((<span class="objekt">Mutex</span>)ApplicationMutexes[<span class="schluesselwort">typeof</span>(T).GUID]).ReleaseMutex();<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="schluesselwort">catch </span>{ <span class="kommentar">/* Fehler ignorieren */</span> }<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<br />
			<br />
			<span class="inaktiv">&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; // Neue Instanz &uuml;ber Reflektion erstellen<br />
			&nbsp; &nbsp; &nbsp;&nbsp;&nbsp; ConstructorInfo ctorInfo;<br />
			&nbsp;&nbsp;&nbsp; &nbsp; <br />
			&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; // Gesch&uuml;tzte Konstruktoren auslesen<br />
			&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ctorInfo = typeof(T).GetConstructor(<br />
			&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BindingFlags.NonPublic | <br />
			&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; BindingFlags.Instance,<br />
			&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; null,<br />
			&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; Type.EmptyTypes,<br />
			&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; null<br />
			&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; );<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
			&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; // Konstruktor ohne Parameter aufrufen<br />
			&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; T _Instanz = (T)ctorInfo.Invoke(new object[] { });<br />
			&nbsp;&nbsp;&nbsp; &nbsp; <br />
			&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; // Instanz der Hashtabelle zuf&uuml;hren<br />
			&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; Selfs.Add(typeof(T).GUID, _Instanz);<br />
			</span><br />
			<span class="kommentar">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Ipc Kanal registrieren</span><br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">SoapServerFormatterSinkProvider </span>_ServProv = <span class="schluesselwort">new </span><span class="objekt">SoapServerFormatterSinkProvider</span>();<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _ServProv.TypeFilterLevel = <span class="objekt">TypeFilterLevel</span>.Full;<br />
			<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">SoapClientFormatterSinkProvider </span>_ClientProv = <span class="schluesselwort">new </span><span class="objekt">SoapClientFormatterSinkProvider</span>();<br />
			<br />
			<span class="kommentar">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Einstellungen f&uuml;r den Kanal werden in einer Hashtabelle abgelegt</span><br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">IDictionary </span>_Hashtable = <span class="schluesselwort">new </span><span class="objekt">Hashtable</span>();<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _Hashtable[<span class="zeichenfolge">&quot;portName&quot;</span>] = <span class="zeichenfolge">&quot;localhost:9190&quot;</span>;<br />
			<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="kommentar">// Zur Serialisierung wird der Soap-Formatter verwendet</span><br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _Channel = <span class="schluesselwort">new </span><span class="objekt">IpcChannel</span>(_Hashtable, _ClientProv, _ServProv);<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">ChannelServices</span>.RegisterChannel(_Channel, false);<br />
			<br />
			<span class="kommentar">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Objekt via Ipc Kanal &quot;marshallen&quot;</span><br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">RemotingServices</span>.Marshal((<span class="objekt">MarshalByRefObject</span>)Selfs[<span class="schluesselwort">typeof</span>(T).GUID], <span class="zeichenfolge">&quot;GlobalSingleton_&quot;</span> + <span class="schluesselwort">typeof</span>(T).GUID.ToString());<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
			<br />
			<span class="inaktiv">
			&nbsp;&nbsp;&nbsp; &nbsp; return (T)Selfs[typeof(T).GUID];<br />
			&nbsp;&nbsp;&nbsp; }<br />
			&nbsp; }<br />
			&nbsp; <br />
			&nbsp; public static T GetInstance&lt;T&gt;()<br />
			&nbsp;&nbsp;&nbsp; where T:</span> <span class="objekt">MarshalByRefObject</span><br />
			<span class="inaktiv">
			&nbsp; {<br />
			&nbsp;&nbsp;&nbsp; bool _Trash;<br />
			&nbsp;&nbsp;&nbsp; return GetInstance&lt;T&gt;(out _Trash);<br />
			&nbsp; }<br />
			}</span>
			<br />
			</span>
			</p>
			<p>
			<br />
			Die Klasse <span class="inline_code">GlobalSingletonBase </span>unterscheidet sich kaum von der Klasse <span class="inline_code">SingletonBase</span>, mit Ausnahme, dass die neue Klasse nun von <span class="inline_code">MarshalByRefObject </span>erbt, so dass schlussendlich folgender Quelltext genau die Funktionalit&auml;t bietet, die in der Einleitung erw&auml;hnt wurde:
			</p>
			<span class="code"><span class="schluesselwort">using </span>System;<br />
			<span class="schluesselwort">using </span>System.Collections.Generic;<br />
			<span class="schluesselwort">using </span>System.Text;<br />
			<span class="schluesselwort">using </span>System.Collections;<br />
			<span class="schluesselwort">using </span>System.Reflection;<br />
			<span class="schluesselwort">using </span>System.Threading;<br />
			<span class="schluesselwort">using </span>System.Runtime.InteropServices;<br />
			<span class="schluesselwort">using </span>System.Runtime.Remoting.Channels.Ipc;<br />
			<span class="schluesselwort">using </span>System.Runtime.Remoting.Channels;<br />
			<span class="schluesselwort">using </span>System.Runtime.Serialization.Formatters;<br />
			<span class="schluesselwort">using </span>System.Runtime.Remoting;<br />
			<span class="schluesselwort">using </span>System.Runtime.Serialization;<br />
			<br />
			<span class="schluesselwort">
			public static class </span><span class="objekt">GlobalSingletonProvider</span><br />
			{<br />
			&nbsp; <span class="schluesselwort">private static </span><span class="objekt">Hashtable </span>Selfs&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = <span class="schluesselwort">new </span><span class="objekt">Hashtable</span>();<br />
			&nbsp; <span class="schluesselwort">private static </span><span class="objekt">Hashtable </span>ApplicationMutexes = <span class="schluesselwort">new </span><span class="objekt">Hashtable</span>();<br />
			&nbsp; <span class="schluesselwort">private static object </span>Lock&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = <span class="schluesselwort">new </span><span class="objekt">Object</span>();<br />
			<br />
			&nbsp; <span class="schluesselwort">public static </span>T GetInstance&lt;T&gt;(<span class="schluesselwort">out bool</span> New)<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">where </span>T: 
			<span class="objekt">MarshalByRefObjekt </span><span class="kommentar">// Jede Klasse ist erlaubt, die von MarshalByRefObjekt erbt</span><br />
			&nbsp; {<br />
			<span class="kommentar">
			&nbsp;&nbsp;&nbsp; // Auf &ouml;ffentlichen Konstruktor pr&uuml;fen</span><br />
			&nbsp;&nbsp;&nbsp; <span class="objekt">ConstructorInfo </span>checkCtor = (<span class="schluesselwort">typeof</span>(T)).GetConstructor(<span class="objekt">Type</span>.EmptyTypes);<br />
			&nbsp;&nbsp;&nbsp; <br />
			&nbsp;&nbsp;&nbsp; <span class="kommentar">/*<br />
			&nbsp;&nbsp;&nbsp; &nbsp;* Falls es einen solchen Konstruktor gibt,<br />
			&nbsp;&nbsp;&nbsp; &nbsp;* schmei&szlig;en wir einen Fehler, da es dem <br />
			&nbsp;&nbsp;&nbsp; &nbsp;* Charakter eines Singleton widerspricht.<br />
			&nbsp;&nbsp;&nbsp; &nbsp;*/</span><br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">if </span>(checkCtor != <span class="schluesselwort">null</span>)<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="schluesselwort">throw new</span> <span class="objekt">InvalidOperationException</span>(<span class="zeichenfolge">&quot;Singleton means that you don't have any public constructors&quot;</span>);<br />
			<br />
			<span class="kommentar">
			&nbsp;&nbsp;&nbsp; // Threadsynchronisation<br />
			</span>
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">lock </span>(Lock) {<br />
			&nbsp;&nbsp;&nbsp; &nbsp; <span class="schluesselwort">if </span>(Selfs.ContainsKey(<span class="schluesselwort">typeof</span>(T).GUID))<br />
			&nbsp;&nbsp;&nbsp; &nbsp; {<br />
			<span class="kommentar">
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // Instanz existiert bereits</span><br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; New = <span class="schluesselwort">false</span>;<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="schluesselwort">return </span>(T)Selfs[<span class="schluesselwort">typeof</span>(T).GUID];<br />
			&nbsp;&nbsp;&nbsp; &nbsp; }
			<br />
			<br />
			<span class="kommentar">
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Mittels Mutex &uuml;berpr&uuml;fen, ob bereits eine Instanz existiert<br />
			</span>
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ApplicationMutexes.Add(<span class="schluesselwort">typeof</span>(T).GUID, <span class="schluesselwort">new </span><span class="objekt">Mutex</span>(<span class="schluesselwort">true</span>, <span class="schluesselwort">typeof</span>(T).GUID.ToString(), <span class="schluesselwort">out </span>New));<br />
			<br />
			<span class="kommentar">
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Ipc Kanal deklarieren</span><br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">IpcChannel </span>_Channel;<br />
			<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="schluesselwort">if </span>(!New)<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="kommentar">/*<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Falls in einer anderen Applikationsdom&auml;ne eine Instanz existiert,<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * muss diese nun als Remote-Proxy bereitgestellt werden, dazu<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * wird zun&auml;chst ein Ipc Channel registriert.<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */</span><br />
			<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">SoapServerFormatterSinkProvider </span>_ServProv = <span class="schluesselwort">new </span><span class="objekt">SoapServerFormatterSinkProvider</span>();<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _ServProv.TypeFilterLevel = <span class="objekt">TypeFilterLevel</span>.Full;<br />
			<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">SoapClientFormatterSinkProvider </span>_ClientProv = <span class="schluesselwort">new </span><span class="objekt">SoapClientFormatterSinkProvider</span>();<br />
			<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="kommentar">// Zur Serialisierung wird der Soap-Formatter verwendet</span><br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _Channel = <span class="schluesselwort">new </span><span class="objekt">IpcChannel</span>(<span class="schluesselwort">null</span>, _ClientProv, _ServProv);<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">ChannelServices</span>.RegisterChannel(_Channel, <span class="schluesselwort">false</span>);<br />
			<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="kommentar">// Nun wird die Instanz &uuml;ber diesen Kanal geholt</span><br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; T _Inst = (T)<span class="objekt">Activator</span>.GetObject(<span class="objekt">typeof</span>(T), <span class="zeichenfolge">&quot;ipc://localhost:9190/GlobalSingleton_&quot;</span> + <span class="schluesselwort">typeof</span>(T).GUID.ToString());<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Selfs.Add(<span class="schluesselwort">typeof</span>(T).GUID, _Inst);<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="schluesselwort">else</span><br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="kommentar">/*<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Es existiert keine Instanz, also wird eine neue Instanz erstellt,<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * der Mutex wird bei Applikationsende wieder freigegeben<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */</span><br />
			<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">AppDomain</span>.CurrentDomain.ProcessExit += <span class="schluesselwort">delegate</span>(<span class="schluesselwort">object</span> sender, <span class="objekt">EventArgs </span>e)<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="schluesselwort">try</span><br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((<span class="objekt">Mutex</span>)ApplicationMutexes[<span class="schluesselwort">typeof</span>(T).GUID]).ReleaseMutex();<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="schluesselwort">catch </span>{ <span class="kommentar">/* Fehler ignorieren */</span> }<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<br />
			<br />
			<span class="kommentar">&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; // Neue Instanz &uuml;ber Reflektion erstellen</span><br />
			&nbsp; &nbsp; &nbsp;&nbsp;&nbsp; <span class="objekt">ConstructorInfo </span>ctorInfo;<br />
			&nbsp;&nbsp;&nbsp; &nbsp; <br />
			<span class="kommentar">
			&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; // Gesch&uuml;tzte Konstruktoren auslesen</span><br />
			&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ctorInfo = <span class="schluesselwort">typeof</span>(T).GetConstructor(<br />
			&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">BindingFlags</span>.NonPublic | <br />
			&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; <span class="objekt">BindingFlags</span>.Instance,<br />
			&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; <span class="schluesselwort">null</span>,<br />
			&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; <span class="objekt">Type</span>.EmptyTypes,<br />
			&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; <span class="schluesselwort">null</span><br />
			&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; );<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
			<span class="kommentar">
			&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; // Konstruktor ohne Parameter aufrufen<br />
			</span>
			&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; T _Instanz = (T)ctorInfo.Invoke(<span class="schluesselwort">new </span><span class="schluesselwort">object</span>[] { });<br />
			&nbsp;&nbsp;&nbsp; &nbsp; <br />
			<span class="kommentar">
			&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; // Instanz der Hashtabelle zuf&uuml;hren</span><br />
			&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; Selfs.Add(<span class="schluesselwort">typeof</span>(T).GUID, _Instanz);<br />
			<br />
			<span class="kommentar">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Ipc Kanal registrieren</span><br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">SoapServerFormatterSinkProvider </span>_ServProv = <span class="schluesselwort">new </span><span class="objekt">SoapServerFormatterSinkProvider</span>();<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _ServProv.TypeFilterLevel = <span class="objekt">TypeFilterLevel</span>.Full;<br />
			<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">SoapClientFormatterSinkProvider </span>_ClientProv = <span class="schluesselwort">new </span><span class="objekt">SoapClientFormatterSinkProvider</span>();<br />
			<br />
			<span class="kommentar">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Einstellungen f&uuml;r den Kanal werden in einer Hashtabelle abgelegt</span><br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">IDictionary </span>_Hashtable = <span class="schluesselwort">new </span><span class="objekt">Hashtable</span>();<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _Hashtable[<span class="zeichenfolge">&quot;portName&quot;</span>] = <span class="zeichenfolge">&quot;localhost:9190&quot;</span>;<br />
			<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="kommentar">// Zur Serialisierung wird der Soap-Formatter verwendet</span><br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _Channel = <span class="schluesselwort">new </span><span class="objekt">IpcChannel</span>(_Hashtable, _ClientProv, _ServProv);<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">ChannelServices</span>.RegisterChannel(_Channel, false);<br />
			<br />
			<span class="kommentar">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Objekt via Ipc Kanal &quot;marshallen&quot;</span><br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">RemotingServices</span>.Marshal((<span class="objekt">MarshalByRefObject</span>)Selfs[<span class="schluesselwort">typeof</span>(T).GUID], <span class="zeichenfolge">&quot;GlobalSingleton_&quot;</span> + <span class="schluesselwort">typeof</span>(T).GUID.ToString());<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
			<br />
			&nbsp;&nbsp;&nbsp; &nbsp; <span class="schluesselwort">return </span>(T)Selfs[<span class="schluesselwort">typeof</span>(T).GUID];<br />
			&nbsp;&nbsp;&nbsp; }<br />
			&nbsp; }<br />
			&nbsp; <br />
			<span class="schluesselwort">
			&nbsp; public static</span> T GetInstance&lt;T&gt;()<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">where </span>T: <span class="objekt">MarshalByRefObject</span><br />
			&nbsp; {<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">bool </span>_Trash;<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">return </span>GetInstance&lt;T&gt;(<span class="schluesselwort">out </span>_Trash);<br />
			&nbsp; }<br />
			}
			<br />
			<br />
			<br />
			<span class="schluesselwort">public abstract class</span> <span class="objekt">GlobalSingletonBase</span>&lt;T&gt; : <span class="objekt">MarshalByRefObject</span><br />
			&nbsp; <span class="schluesselwort">where </span>T: <span class="objekt">GlobalSingletonBase</span>&lt;T&gt;<br />
			{<br />
			&nbsp; <span class="schluesselwort">public static</span> T GetInstance(<span class="schluesselwort">out bool</span> New)<br />
			&nbsp; {<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">return </span><span class="objekt">GlobalSingletonProvider</span>.GetInstance&lt;T&gt;(<span class="schluesselwort">out </span>New);<br />
			&nbsp; }<br />
			&nbsp; <br />
			&nbsp; <span class="schluesselwort">public static</span> T GetInstance()<br />
			&nbsp; {<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">bool </span>_Trash;<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">return </span>GetInstance(<span class="schluesselwort">out </span>_Trash);<br />
			&nbsp; }<br />
			}<br />
			</span>
			<p>
			&nbsp;<br />
			Auf diesem Weg kann nun &uuml;ber Vererbung ein systemweiter Singleton genutzt werden. Das folgende Beispiel zeigt die Verwendung in der Praxis:
			</p>
			<p class="code">
			<span class="schluesselwort">public class</span> <span class="objekt">Start </span>: <span class="objekt">GlobalSingletonBase</span>&lt;<span class="objekt">Start</span>&gt;<br />
			{<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">public </span><span class="objekt">Form </span>WinForm;<br />
			<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">private </span>Start()<br />
			&nbsp;&nbsp;&nbsp; { }<br />
			<br />
			&nbsp;&nbsp;&nbsp; [<span class="objekt">STAThread</span>]<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">static void</span> Main(<span class="schluesselwort">string</span>[] args)<br />
			&nbsp;&nbsp;&nbsp; {<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <span class="schluesselwort">bool </span>Created;<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">Start </span>MainProcedure = <span class="schluesselwort">Start</span>.GetInstance(<span class="schluesselwort">out </span>Created);<br />
			<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="kommentar">// Applikation starten, falls es sich um die erste Instanz handelt</span><br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="schluesselwort">if </span>(Created)<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MainProcedure.WinForm = <span class="schluesselwort">new </span><span class="objekt">HauptFormular</span>();<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MainProcedure.WinForm.Show();<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">Application</span>.Run();<br />
			&nbsp; &nbsp; &nbsp; }<br />
			&nbsp; &nbsp; &nbsp; <span class="schluesselwort">else</span><br />
			&nbsp; &nbsp; &nbsp; {<br />
			&nbsp; &nbsp; &nbsp; &nbsp; <span class="kommentar">// Applikation l&auml;uft bereits, also in den Vordergrund holen</span><br />
			&nbsp; &nbsp; &nbsp; &nbsp; MainProcedure.WinForm.WindowState = <span class="objekt">FormWindowState</span>.Maximized;<br />
			&nbsp; &nbsp; &nbsp; &nbsp; SetForegroundWindow(MainProcedure.WinForm.Handle);<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
			&nbsp;&nbsp;&nbsp; }<br />
			<br />
			&nbsp;&nbsp;&nbsp; [<span class="objekt">DllImport</span>(<span class="zeichenfolge">&quot;user32.dll&quot;</span>)]<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">public static extern bool</span> SetForegroundWindow(<span class="objekt">IntPtr </span>Handle);<br />
			}<br />
			<br />
			<span class="schluesselwort">public class </span><span class="objekt">HauptFormular </span>: System.Windows.Forms.<span class="objekt">Form</span><br />
			{<br />
			&nbsp;&nbsp;&nbsp; <span class="kommentar">// ...</span><br />
			}
			</p>
			<br />
			<p>
			An dieser Stelle m&ouml;chte ich mich f&uuml;r's lesen bedanken und hoffe, Ihnen an der ein oder anderen Stelle weitergeholfen zu haben. Dennoch bin ich mir bewusst dar&uuml;ber, dass einfach viele Dinge in diesem Artikel als bekannt vorrausgesetzt werden, daf&uuml;r m&ouml;chte ich mich entschuldigen. Sicher haben Sie Verst&auml;ndnis daf&uuml;r, dass es sich nur um einen kurzen Abriss dessen handelt, was m&ouml;glich ist und nicht um ein Handbuch und ich hoffe, dass bei Unklarheiten die Codebeispiele selbsterkl&auml;rend sind. Ohne Programmierkenntnisse f&auml;llt es sicherlich schwer, alle Gedanken auf anhieb zu verstehen, ich kann Ihnen daher nur empfehlen, diese Beispiele schrittweise nachzuvollziehen.
			</p>
			<p>
			&nbsp;
			</p>
			<hr />
			<a title="fussnoten" name="fussnoten"></a>
			<div style="float: right">
			<a href="front_content.php?idart=37&amp;idcat=4&amp;lang=1&amp;client=1"><img src="upload/grafiken/gplv3-88x31.gif" alt="GPLv3" border="0" /></a>
			</div>
			<sup>1</sup> <a href="http://de.wikipedia.org/wiki/Mutex" target="_blank">Mutex: Wikipedia</a><br />
			<sup>2</sup> <a href="http://de.wikipedia.org/wiki/Marshalling" target="_blank">Marshalling: Wikipedia</a>
			 ]]></description>
		</item>
		<item>
			<title>Implementierung eines Singleton in C#</title>
			<link>http://www.josupeit.com/weblog~informatik-und-technik~dotnet,implementierung-des-singleton.html</link>
			<guid>http://www.josupeit.com/front_content.php?lang=1&amp;idart=23</guid>
			<pubDate>Wed, 21 Nov 2007 09:59:24 +0100</pubDate>
			<author>webmaster@josupeit.com (Manuel Josupeit-Walter)</author>
			<description><![CDATA[ <p>
			Es gibt Situationen, in denen man als Entwickler sicherstellen m&ouml;chte, dass von einer Klasse nur ein Objekt instanziiert werden kann. F&uuml;r diesen Anwendungsfalls gibt es bereits einen L&ouml;sungsansatz: Das Singleton-Pattern<a href="front_content.php?idart=23#fussnoten"><sup>1</sup></a>. Das Prinzip dieses Ansatzes ist recht simpel und beruht unter anderem auf der Nutzung statischer Felder und Methoden. Diese sogenannten statischen Member einer Klasse unterscheiden sich von den Instanzmembern in sofern, als dass sie genutzt werden k&ouml;nnen, ohne explizit ein Objekt zu instanziieren.
			</p>
			<p>
			Am Beispiel C# (Mircosoft .NET Framework 2.0) m&ouml;chte ich an dieser Stelle in zwei Schritten eine Art systemweiten Singleton implementieren, dieser Artikel befasst sich allerdings zun&auml;chst mit dem ersten Schritt: der Implementierung des herk&ouml;mmlichen Singleton. Die Erweiterung einer bestehenden Klasse zum Singleton funktioniert in C# wie folgt:
			</p>
			<br />
			<span class="code"><span class="schluesselwort">public class</span> <span class="objekt">Beispiel</span><br />
			{<br />
			&nbsp; <span class="kommentar">/*<br />
			&nbsp;&nbsp; * Dieses statische Feld h&auml;lt unsere Instanz der<br />
			&nbsp;&nbsp; * Klasse<br />
			&nbsp;&nbsp; */<br />
			</span>&nbsp; <span class="schluesselwort">private static</span> <span class="objekt">Beispiel</span> _Instanz;<br />
			&nbsp; <br />
			&nbsp; <span class="kommentar">/*<br />
			&nbsp;&nbsp; * Konstruktor der Klasse wird &uuml;ber den Zugriffsmodifizierer<br />
			&nbsp;&nbsp; * &quot;private&quot; gesch&uuml;tzt, um eine Instanziierung der Klasse von<br />
			&nbsp;&nbsp; * au&szlig;en zu unterbinden.<br />
			&nbsp;&nbsp; */<br />
			</span>&nbsp; <span class="schluesselwort">private</span> Beispiel()<br />
			&nbsp; {<br />
			&nbsp;&nbsp;&nbsp; <span class="kommentar">// TODO: Implementieren Sie Ihren Konstruktor hier<br />
			</span>&nbsp; }<br />
			&nbsp; <br />
			&nbsp;<span class="kommentar"> /*<br />
			&nbsp;&nbsp; * Statische Methode, die die Instanz der Klasse zur&uuml;ck gibt.<br />
			&nbsp;&nbsp; */<br />
			</span>&nbsp; <span class="schluesselwort">public static</span> <span class="objekt">Beispiel</span> GetInstance()<br />
			&nbsp; {<br />
			&nbsp;&nbsp; if (_Instanz == <span class="schluesselwort">null</span>)<br />
			&nbsp;&nbsp;&nbsp; _Instanz = <span class="schluesselwort">new</span> Beispiel();<br />
			<br />
			&nbsp;&nbsp; <span class="schluesselwort">return</span> _Instanz;<br />
			&nbsp; }<br />
			}<br />
			</span><br />
			<p>
			Anhand dieses Beispiels sehen Sie, dass nur eine Instanz der Klasse Beispiel erzeugt wird und zwar &uuml;ber die statische Methode <span class="inline_code">GetInstance()</span>:
			</p>
			<br />
			<span class="code"><span class="schluesselwort">public static void</span> main(<span class="schluesselwort">string</span>[] args)<br />
			{<br />
			&nbsp;<span class="objekt">Beispiel</span> BeispielInstanz = <span class="objekt">Beispiel</span>.GetInstance();<br />
			}<br />
			</span><br />
			<p>
			Der direkte Aufruf von <span class="inline_code">BeispielInstanz = new Beispiel()</span>; ist unzul&auml;ssig, da der Konstruktor der Klasse privat ist.
			</p>
			<p>
			Um auf einfachem Wege ihren Quelltext wiederverwenden zu k&ouml;nnen, lagern wir nun diesen Code in eine Bibliothek aus. Dieses Vorhaben allerdings erscheint nur auf den ersten Blick einfach: &uuml;ber Vererbung. Allerdings kann aus der Basisklasse nicht ohne Weiteres auf die abgeleitete Klasse zugegriffen werden, dies widerspr&auml;che auch dem Sinn von Vererbung, so dass folgendes Vorhaben <u><b>nicht</b></u> funktioniert:
			</p>
			<br />
			<span class="code"><span class="schluesselwort">public abstract class</span> <span class="objekt">Singleton</span><br />
			{<br />
			&nbsp; <span class="schluesselwort">private static </span><span class="objekt">Singleton</span> _Instanz;<br />
			&nbsp; <br />
			&nbsp; <span class="schluesselwort">private</span> Singleton()<br />
			&nbsp; {<br />
			&nbsp;&nbsp;&nbsp; <span class="kommentar">// TODO: Implementieren Sie Ihren Konstruktor hier</span><br />
			&nbsp; }<br />
			&nbsp; <br />
			&nbsp; <span class="schluesselwort">public static</span> <span class="objekt">Singleton</span> GetInstance()<br />
			&nbsp; {<br />
			&nbsp;&nbsp; if (_Instanz == <span class="schluesselwort">null</span>)<br />
			&nbsp;&nbsp;&nbsp;&nbsp; <span class="kommentar">// Hier m&uuml;sste die Kindklasse instanziiert werden</span><br />
			&nbsp;&nbsp;&nbsp; _Instanz = <span class="schluesselwort">new</span> ?();<br />
			<br />
			&nbsp;&nbsp; <span class="schluesselwort">return</span> _Instanz;<br />
			&nbsp; }<br />
			}<br />
			</span><br />
			<p>
			Abgesehen von diesem Problem kann eine abgeleitete Klasse so nicht instanziiert werden, da die Basisklasse durch die Verwendung des Schl&uuml;sselwortes <span class="inline_code">private</span> den Konstruktor sch&uuml;tzt, ein Zugriff auf diesen Konstruktor durch Reflektion &uuml;ber die Basisklasse ist allerdings auch nicht m&ouml;glich<a href="front_content.php?idart=23#fussnoten"><sup>2</sup></a>.
			</p>
			<p>
			Das Zauberwort an dieser Stelle lautet Generika<a href="front_content.php?idart=23#fussnoten"><sup>3</sup></a>, denn generische Klassen erlauben es dem Entwickler, Typdefinitionen f&uuml;r ganze Klassen oder Methoden offen zu lassen. Wir entwickeln unser Singleton-Pattern also weiter zu einer statischen Klasse, also einer Klasse, die selbst nicht instanziiert werden kann, die aber unsere Singleton-Objekte verwaltet. Diese Klasse soll den Namen <span class="inline_code">SingletonProvider </span>bekommen. Damit k&uuml;nftig einfach entschieden werden kann, ob es sich um eine neue Instanz handelt oder nicht, erweitern wir gleich unsere Methode <span class="inline_code">GetInstance()</span> um einen boolschen Wert:
			</p>
			<br />
			<span class="code"><span class="schluesselwort">using </span>System;<br />
			<span class="schluesselwort">using </span>System.Collections.Generic;<br />
			<span class="schluesselwort">using </span>System.Text;<br />
			<span class="schluesselwort">using </span>System.Collections;<br />
			<span class="schluesselwort">using </span>System.Reflection;<br />
			<br />
			<span class="schluesselwort">
			public static class</span> <span class="objekt">SingletonProvider</span><br />
			{<br />
			&nbsp; <span class="kommentar">/*<br />
			&nbsp;&nbsp; * Die Hashtabelle Selfs h&auml;lt unsere Instanz-<br />
			&nbsp;&nbsp; * objekte intern im Speicher.<br />
			&nbsp;&nbsp; */</span><br />
			&nbsp; <span class="schluesselwort">private static</span> <span class="objekt">Hashtable </span>Selfs = <span class="schluesselwort">new </span>Hashtable();<br />
			&nbsp; <br />
			&nbsp; <span class="kommentar">// Dieses Objekt wird zur Threadsynchronisation verwendet</span><br />
			&nbsp; <span class="schluesselwort">private static object</span> Lock&nbsp;&nbsp;&nbsp;&nbsp; = <span class="schluesselwort">new </span>Object();<br />
			<br />
			&nbsp; <span class="schluesselwort">public static</span> T GetInstance&lt;T&gt;(<span class="schluesselwort">out bool</span> New)<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">where </span>T: <span class="schluesselwort">new</span>()<br />
			&nbsp; {<br />
			&nbsp;&nbsp;&nbsp; <span class="kommentar">// Threadsynchronisation</span><br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">lock </span>(Lock) {<br />
			&nbsp;&nbsp;&nbsp; &nbsp; <span class="kommentar">/*<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * &Uuml;berpr&uuml;fen, ob bereits eine Instanz<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; * des generischen Typen T existiert.<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; * Als Schl&uuml;ssel f&uuml;r die Hashtabelle verwenden<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; * wir die GUID des Typen.<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; */</span><br />
			&nbsp;&nbsp;&nbsp; &nbsp; <span class="schluesselwort">if </span>(Selfs.ContainsKey(<span class="schluesselwort">typeof</span>(T).GUID))<br />
			&nbsp;&nbsp;&nbsp; &nbsp; {<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="kommentar">// Instanz existiert bereits</span><br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; New = <span class="schluesselwort">false</span>;<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="schluesselwort">return </span>(T)Selfs[<span class="schluesselwort">typeof</span>(T).GUID];<br />
			&nbsp;&nbsp;&nbsp; &nbsp; }<br />
			<br />
			&nbsp;&nbsp;&nbsp; &nbsp; <span class="kommentar">// Neue Instanz erstellen</span><br />
			&nbsp;&nbsp;&nbsp; &nbsp; Selfs.Add(<span class="schluesselwort">typeof</span>(T).GUID, <span class="schluesselwort">new </span>T());<br />
			&nbsp;&nbsp;&nbsp; &nbsp; New = <span class="schluesselwort">true</span>;<br />
			&nbsp;&nbsp;&nbsp; &nbsp; <br />
			&nbsp;&nbsp;&nbsp; &nbsp; <span class="schluesselwort">return </span>(T)Selfs[<span class="schluesselwort">typeof</span>(T).GUID];<br />
			&nbsp;&nbsp;&nbsp; }<br />
			&nbsp; }<br />
			}<br />
			</span><br />
			<p>
			Durch diese Klasse k&ouml;nnen nun auf einfachem Wege Singleton-Objekte erzeugt werden:
			</p>
			<br />
			<span class="code"><span class="schluesselwort">public static void</span> main(<span class="schluesselwort">string</span>[] args)<br />
			{<br />
			&nbsp;<span class="schluesselwort">bool</span> neueInstanz;<br />
			&nbsp;<span class="objekt">Beispiel</span> MeinBeispiel = <span class="objekt">SingletonProvider</span>.GetInstance&lt;<span class="objekt">Beispiel</span>&gt;(<span class="schluesselwort">out</span> neueInstanz);<br />
			} <br />
			</span><br />
			<p>
			Die Variable MeinBeispiel enth&auml;lt nun eine neue Instanz der Klasse Beispiel, die Variable neueInstanz ist wahr, falls der SingletonProvider ein neues Objekt erzeugt hat. Der Typ Beispiel ist genau der &quot;L&uuml;ckenf&uuml;ller&quot; f&uuml;r unseren generischen Typen T im Beispiel oben. Einzige Bedingung: Es muss sich um eine Klasse handeln, die einen parameterlosen, &ouml;ffentlichen Konstruktor besitzt (siehe <span class="inline_code">where T: new()</span>). Dies allerdings widerspricht wiederum dem Singleton-Gedanken, denn nun kann wieder eine Instanz der Klasse von Au&szlig;en erzeugt werden: <span class="inline_code">MeinBeispiel = new Beispiel();</span> Der Singleton ist somit ausgehebelt.
			</p>
			<p>
			Wir modifizieren an dieser Stelle unseren SingletonProvider, so dass ausschlie&szlig;lich Klassen mit gesch&uuml;tzten Konstruktoren verwendet werden k&ouml;nnen. Au&szlig;erdem &uuml;berladen wir unsere GetInstance-Methode der Einfachheit halber wie folgt:
			</p>
			<br />
			<span class="code"><span class="schluesselwort">using </span>System;<br />
			<span class="schluesselwort">using </span>System.Collections.Generic;<br />
			<span class="schluesselwort">using </span>System.Text;<br />
			<span class="schluesselwort">using </span>System.Collections;<br />
			<span class="schluesselwort">using </span>System.Reflection;<br />
			<br />
			<span class="schluesselwort">public static class</span> <span class="objekt">SingletonProvider</span><br />
			{<br />
			&nbsp; <span class="schluesselwort">private static</span> <span class="objekt">Hashtable </span>Selfs = <span class="schluesselwort">new</span> Hashtable();<br />
			&nbsp; <span class="schluesselwort">private static object</span> Lock&nbsp;&nbsp;&nbsp;&nbsp; = <span class="schluesselwort">new </span>Object();<br />
			<br />
			&nbsp; <span class="schluesselwort">public static </span>T GetInstance&lt;T&gt;(<span class="schluesselwort">out bool</span> New)<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">where</span> T: <span class="schluesselwort">class </span><span class="kommentar">// Jede Klasse ist erlaubt</span><br />
			&nbsp; {<br />
			&nbsp;&nbsp;&nbsp; <span class="kommentar">// Threadsynchronisation</span><br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">lock </span>(Lock) {<br />
			&nbsp;&nbsp;&nbsp; &nbsp; <span class="schluesselwort">if </span>(Selfs.ContainsKey(<span class="schluesselwort">typeof</span>(T).GUID))<br />
			&nbsp;&nbsp;&nbsp; &nbsp; {<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="kommentar">// Instanz existiert bereits</span><br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; New = <span class="schluesselwort">false</span>;<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="schluesselwort">return </span>(T)Selfs[<span class="schluesselwort">typeof</span>(T).GUID];<br />
			&nbsp;&nbsp;&nbsp; &nbsp; }<br />
			<br />
			&nbsp;&nbsp;&nbsp; &nbsp; <span class="kommentar">// Neue Instanz &uuml;ber Reflektion erstellen</span><br />
			&nbsp; &nbsp;&nbsp;&nbsp; <span class="objekt">ConstructorInfo </span>ctorInfo;<br />
			&nbsp;&nbsp;&nbsp; &nbsp; <br />
			&nbsp;&nbsp;&nbsp; &nbsp; <span class="kommentar">// Gesch&uuml;tzte Konstruktoren auslesen</span><br />
			&nbsp;&nbsp;&nbsp; &nbsp; ctorInfo = <span class="schluesselwort">typeof</span>(T).GetConstructor(<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">BindingFlags</span>.NonPublic | <br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; <span class="objekt">BindingFlags</span>.Instance,<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; <span class="schluesselwort">null</span>,<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; <span class="objekt">Type</span>.EmptyTypes,<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; <span class="schluesselwort">null</span><br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; );<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
			&nbsp;&nbsp;&nbsp; &nbsp; <span class="kommentar">// Konstruktor ohne Parameter aufrufen</span><br />
			&nbsp;&nbsp;&nbsp; &nbsp; T _Instanz = (T)ctorInfo.Invoke(<span class="schluesselwort">new object</span>[] { });<br />
			&nbsp;&nbsp;&nbsp; &nbsp; <br />
			&nbsp;&nbsp;&nbsp; &nbsp; <span class="kommentar">// Instanz der Hashtabelle zuf&uuml;hren</span><br />
			&nbsp;&nbsp;&nbsp; &nbsp; Selfs.Add(<span class="schluesselwort">typeof</span>(T).GUID, _Instanz);<br />
			&nbsp;&nbsp;&nbsp; &nbsp; New = <span class="schluesselwort">true</span>;<br />
			&nbsp;&nbsp;&nbsp; &nbsp; <br />
			&nbsp;&nbsp;&nbsp; &nbsp; <span class="schluesselwort">return </span>(T)Selfs[<span class="schluesselwort">typeof</span>(T).GUID];<br />
			&nbsp;&nbsp;&nbsp; }<br />
			&nbsp; }<br />
			&nbsp; <br />
			&nbsp; <span class="kommentar">/*<br />
			&nbsp;&nbsp; * F&uuml;r den Fall, dass es egal ist,<br />
			&nbsp;&nbsp; * ob es sich um ein neues Objekt handelt<br />
			&nbsp;&nbsp; */</span><br />
			&nbsp; <span class="schluesselwort">public static</span> T GetInstance&lt;T&gt;()<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">where </span>T: <span class="schluesselwort">class</span><br />
			&nbsp; {<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">bool </span>_Trash;<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">return </span>GetInstance&lt;T&gt;(<span class="schluesselwort">out </span>_Trash);<br />
			&nbsp; }<br />
			}<br />
			</span><br />
			<p>
			Nun wird der private parameterlose Konstruktor zur Instanziierung verwendet. Als n&auml;chstes verbieten wir ausdr&uuml;cklich &ouml;ffentliche Konstruktoren und schmei&szlig;en andernfalls einen Fehler:
			</p>
			<br />
			<span class="code"><span class="schluesselwort">using </span>System;<br />
			<span class="schluesselwort">using </span>System.Collections.Generic;<br />
			<span class="schluesselwort">using </span>System.Text;<br />
			<span class="schluesselwort">using </span>System.Collections;<br />
			<span class="schluesselwort">using </span>System.Reflection;<br />
			<br />
			<span class="schluesselwort">public static class</span> <span class="objekt">SingletonProvider</span><br />
			{<br />
			&nbsp; <span class="schluesselwort">private static</span> <span class="objekt">Hashtable </span>Selfs = <span class="schluesselwort">new </span>Hashtable();<br />
			&nbsp; <span class="schluesselwort">private static object</span> Lock&nbsp;&nbsp;&nbsp;&nbsp; = <span class="schluesselwort">new </span>Object();<br />
			<br />
			&nbsp; <span class="schluesselwort">public static</span> T GetInstance&lt;T&gt;(<span class="schluesselwort">out bool</span> New)<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">where </span>T: <span class="schluesselwort">class </span><span class="kommentar">// Jede Klasse ist erlaubt</span><br />
			&nbsp; {<br />
			&nbsp;&nbsp;&nbsp; <span class="kommentar">// Auf &ouml;ffentlichen Konstruktor pr&uuml;fen</span><br />
			&nbsp;&nbsp;&nbsp; <span class="objekt">ConstructorInfo </span>checkCtor = (<span class="schluesselwort">typeof</span>(T)).GetConstructor(<span class="objekt">Type</span>.EmptyTypes);<br />
			&nbsp;&nbsp;&nbsp; <br />
			&nbsp;&nbsp;&nbsp; <span class="kommentar">/*<br />
			&nbsp;&nbsp;&nbsp; &nbsp;* Falls es einen solchen Konstruktor gibt,<br />
			&nbsp;&nbsp;&nbsp; &nbsp;* schmei&szlig;en wir einen Fehler, da es dem <br />
			&nbsp;&nbsp;&nbsp; &nbsp;* Charakter eines Singleton widerspricht.<br />
			&nbsp;&nbsp;&nbsp; &nbsp;*/</span><br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">if </span>(checkCtor != <span class="schluesselwort">null</span>)<br />
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="schluesselwort">throw new</span> InvalidOperationException(<span class="zeichenfolge">&quot;Singleton means that you don't have any public constructors&quot;</span>);<br />
			<br />
			&nbsp;&nbsp;&nbsp; <span class="kommentar">// Threadsynchronisation</span><br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">lock </span>(Lock) {<br />
			&nbsp;&nbsp;&nbsp; &nbsp; <span class="schluesselwort">if </span>(Selfs.ContainsKey(<span class="schluesselwort">typeof</span>(T).GUID))<br />
			&nbsp;&nbsp;&nbsp; &nbsp; {<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="kommentar">// Instanz existiert bereits</span><br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; New = <span class="schluesselwort">false</span>;<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="schluesselwort">return </span>(T)Selfs[<span class="schluesselwort">typeof</span>(T).GUID];<br />
			&nbsp;&nbsp;&nbsp; &nbsp; }<br />
			<br />
			&nbsp;&nbsp;&nbsp; &nbsp; <span class="kommentar">// Neue Instanz &uuml;ber Reflektion erstellen</span><br />
			&nbsp; &nbsp;&nbsp;&nbsp; <span class="objekt">ConstructorInfo </span>ctorInfo;<br />
			&nbsp;&nbsp;&nbsp; &nbsp; <br />
			&nbsp;&nbsp;&nbsp; &nbsp; <span class="kommentar">// Gesch&uuml;tzte Konstruktoren auslesen</span><br />
			&nbsp;&nbsp;&nbsp; &nbsp; ctorInfo = <span class="schluesselwort">typeof</span>(T).GetConstructor(<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="objekt">BindingFlags</span>.NonPublic | <br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; <span class="objekt">BindingFlags</span>.Instance,<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; <span class="schluesselwort">null</span>,<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; <span class="objekt">Type</span>.EmptyTypes,<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; <span class="schluesselwort">null</span><br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; );<br />
			&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
			&nbsp;&nbsp;&nbsp; &nbsp; <span class="kommentar">// Konstruktor ohne Parameter aufrufen</span><br />
			&nbsp;&nbsp;&nbsp; &nbsp; T _Instanz = (T)ctorInfo.Invoke(<span class="schluesselwort">new object</span>[] { });<br />
			&nbsp;&nbsp;&nbsp; &nbsp; <br />
			&nbsp;&nbsp;&nbsp; &nbsp; <span class="kommentar">// Instanz der Hashtabelle zuf&uuml;hren</span><br />
			&nbsp;&nbsp;&nbsp; &nbsp; Selfs.Add(<span class="schluesselwort">typeof</span>(T).GUID, _Instanz);<br />
			&nbsp;&nbsp;&nbsp; &nbsp; New = <span class="schluesselwort">true</span>;<br />
			&nbsp;&nbsp;&nbsp; &nbsp; <br />
			&nbsp;&nbsp;&nbsp; &nbsp; <span class="schluesselwort">return </span>(T)Selfs[<span class="schluesselwort">typeof</span>(T).GUID];<br />
			&nbsp;&nbsp;&nbsp; }<br />
			&nbsp; }<br />
			&nbsp; <br />
			&nbsp; <span class="schluesselwort">public static</span> T GetInstance&lt;T&gt;()<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">where </span>T: <span class="schluesselwort">class</span><br />
			&nbsp; {<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">bool </span>_Trash;<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">return </span>GetInstance&lt;T&gt;(<span class="schluesselwort">out </span>_Trash);<br />
			&nbsp; }<br />
			}<br />
			</span><br />
			<p>
			Mit Hilfe der obigen Implementierung der SingletonProvider-Klasse lassen sich nun beliebige Singleton-Objekte verwalten:
			</p>
			<br />
			<span class="code"><span class="schluesselwort">public class</span> <span class="objekt">Beispiel</span><br />
			{<br />
			<br />
			<span class="schluesselwort">&nbsp;private </span>Beispiel()<br />
			&nbsp;{<br />
			&nbsp; <span class="objekt">Console</span>.WriteLine(<span class="zeichenfolge">&quot;Klasse instanziiert&quot;</span>);<br />
			&nbsp;}<br />
			&nbsp;<br />
			&nbsp;<span class="schluesselwort">public static void</span> main(<span class="schluesselwort">string</span>[] args)<br />
			&nbsp;{<br />
			&nbsp; <span class="objekt">Beispiel </span>MeinBeispiel&nbsp; = <span class="objekt">SingletonProvider</span>&lt;<span class="objekt">Beispiel</span>&gt;.GetInstance();<br />
			&nbsp; <span class="objekt">Beispiel </span>MeinBeispiel2 = <span class="objekt">SingletonProvider</span>&lt;<span class="objekt">Beispiel</span>&gt;.GetInstance();<br />
			&nbsp;}<br />
			}<br />
			</span><br />
			<p>
			Dieses Beispiel erzeugt auf der Konsole einmalig die Ausgabe &quot;Klasse instanziiert&quot;, da der erste Aufruf von <span class="inline_code">GetInstance()</span> eine Instanz erzeugt. Der zweite Aufruf hingegen liefert ganz im Sinne des Singleton das selbe Objekt. Eine Instanz von Au&szlig;en &uuml;ber <span class="inline_code">MeinBeispiel = new Beispiel();</span> ist durch den gesch&uuml;tzten Konstruktor &uuml;brigens nicht mehr m&ouml;glich.
			</p>
			<p>
			M&ouml;chte man nun eine Klasse schreiben, um andere Klassen von dieser &quot;Singleton-Basis&quot; erben zu lassen, bedienen wir uns der oben bereits implementierten Klasse SingletonProvider, der Singleton selbst soll hier allerdings nicht instanziiert werden und ist deshalb abstrakt:
			</p>
			<br />
			<span class="code"><span class="schluesselwort">public abstract class</span> <span class="objekt">SingletonBase</span>&lt;T&gt;<br />
			&nbsp; <span class="schluesselwort">where </span>T: <span class="objekt">SingletonBase</span>&lt;T&gt;<br />
			{<br />
			&nbsp; <span class="schluesselwort">public static</span> T GetInstance(<span class="schluesselwort">out bool</span> New)<br />
			&nbsp; {<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">return </span><span class="objekt">SingletonProvider</span>.GetInstance&lt;T&gt;(<span class="schluesselwort">out </span>New);<br />
			&nbsp; }<br />
			&nbsp; <br />
			&nbsp; <span class="schluesselwort">public static</span> T GetInstance()<br />
			&nbsp; {<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">bool </span>_Trash;<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">return </span>GetInstance(<span class="schluesselwort">out </span>_Trash);<br />
			&nbsp; }<br />
			}<br />
			</span><br />
			<p>
			Da, wie oben bereits gesagt, die Elternklasse allerdings nicht auf die Kindklasse schlie&szlig;en kann, werwenden wir f&uuml;r die Anweisung <span class="inline_code">where T: SingletonBase&lt;T&gt;</span>, um den Typen zu &quot;ermitteln&quot;. Dies ist zwar in gewisser Hinsicht eine Redundanz, da eigentlich bereits durch die Vererbung klar ist, dass eine Instanz von &quot;Beispiel&quot; erzeugt werden soll, leider gibt es meiner Ansicht nach aber derzeit keine wesentlich elegantere L&ouml;sung dieses Problems. Das .NET Framework 3.5 l&auml;sst allerdings bereits heute auf sch&ouml;nere Ans&auml;tze hoffen...
			</p>
			<br />
			<span class="code"><span class="schluesselwort">public sealed class</span> <span class="objekt">Beispiel </span>: <span class="objekt">SingletonBase</span>&lt;<span class="objekt">Beispiel</span>&gt;<br />
			{<br />
			&nbsp;&nbsp;&nbsp; <span class="schluesselwort">private </span>Beispiel()<br />
			&nbsp;&nbsp;&nbsp; {<br />
			&nbsp;&nbsp;&nbsp; &nbsp;<span class="kommentar">// Konstruktor</span><br />
			&nbsp;&nbsp;&nbsp; }<br />
			}<br />
			</span><br />
			<p>
			Instanzen der Klasse k&ouml;nnen nun einfach via <span class="inline_code">Beispiel.GetInstance()</span> geholt werden, eine eigene Instanziierung durch Verwendung des Schl&uuml;sselwortes <span class="inline_code">new()</span> ist nicht mehr m&ouml;glich. Ein Haken allerdings bleibt: Die Klasse sollte versiegelt sein, so dass von ihr nicht weiter geerbt werden kann, denn
			</p>
			<br />
			<span class="code"><span class="schluesselwort">class </span><span class="objekt">GeerbtesBeispiel </span>: <span class="objekt">Beispiel</span><br />
			{ }<br />
			</span><br />
			<p>
			bietet nun auch die statische Methode <span class="inline_code">GetInstance()</span>, die allerdings nach wie vor die Basisklasse Beispiel instanziiert, nicht jedoch GeerbtesBeispiel.&nbsp;
			</p>
			<p>
			Damit nun dieser Artikel nicht noch l&auml;nger wird, als er bisher schon ist, m&ouml;chte ich dieses Beispiel beim n&auml;chsten Mal zu einem systemweiten Singleton ausbauen. Mit Hilfe dieser Methode l&auml;sst sich beispielsweise einfach realisieren, dass eine Anwendung nur einmal gestartet werden kann und jeder weitere Programmstart das bereits ge&ouml;ffnete Fenster in den Vordergrund holt. Dazu allerdings erst beim n&auml;chsten Mal mehr.
			</p>
			<p>
			Abschlie&szlig;end bleibt mir eigentlich nur noch zu sagen, dass es sich bei diesem Artikel lediglich um ein Beispiel einer M&ouml;glichkeit der Umsetzung handelt. Es gibt noch unz&auml;hlige weitere Implementierungen des Singleton, sehen Sie es also als eine Art Inspiration f&uuml;r Ihre Projekte, ich hoffe ich konnte Ihnen jedoch ein wenig bei der L&ouml;sung Ihres Problemes weiterhelfen.
			</p>
			<hr />
			<p>
			<a title="fussnoten" name="fussnoten" id="fussnoten"></a>
			</p>
			<div style="float: right">
			<a href="front_content.php?idart=37&amp;idcat=4&amp;lang=1&amp;client=1"><img src="upload/grafiken/gplv3-88x31.gif" alt="GPLv3" border="0" /></a>
			</div>
			<sup>1</sup> <a href="http://de.wikipedia.org/wiki/Singleton_%28Entwurfsmuster%29" target="_blank">Singleton (Entwurfsmuster): Wikipedia
			</a><br />
			<sup>2</sup> <a href="http://msdn2.microsoft.com/de-de/library/cs01xzbk%28VS.80%29.aspx#remarksToggle" target="_blank">Type.GetConstructor-Methode: Microsoft</a><br />
			<sup>3</sup> <a href="http://de.wikipedia.org/wiki/Generischer_Typ" target="_blank">Generische Typen: Wikipedia</a>
			<p>
			&nbsp;
			</p>
			<br />
			<p>
			<b>Siehe auch:</b><br />
			<a href="http://de.wikipedia.org/wiki/Sprachelemente_von_C-Sharp" target="_blank">Sprachelemente von C-Sharp (Wikipedia)</a>
			</p>
			 ]]></description>
		</item>
		<item>
			<title>min-height im Internet Explorer</title>
			<link>http://www.josupeit.com/weblog~informatik-und-technik~web,min-height-im-internet-explorer.html</link>
			<guid>http://www.josupeit.com/front_content.php?lang=1&amp;idart=20</guid>
			<pubDate>Fri, 26 Oct 2007 14:56:31 +0200</pubDate>
			<author>webmaster@josupeit.com (Manuel Josupeit-Walter)</author>
			<description><![CDATA[ <p>
			Dass ich den Internet Explorer, zumindest in Versionen vor 7 nicht mag, ist f&uuml;r meine Arbeitskollegen kein Geheimnis und wenn man betrachtet, wie wenig sich Microsoft bei der Entwicklung dieses Browsers an geltende Standards vom <a href="http://www.w3c.org" target="_blank">W3C</a> h&auml;lt, ist dies sicherlich auch kein Wunder. An dieser Stelle aufzuz&auml;hlen sind beispielsweise der 3-Pixel Fehler, die pr&auml;gnante Miturheberschaft am Quirks-Mode oder die fehlerhafte Berechnung von Element-Dimensionen in Zusammenhang mit Innenabst&auml;nden, von nicht implementierten CSS Attributen, wie min-width oder min-height einmal ganz abgesehen.
			</p>
			<p>
			Im Job ist es teils eine wahre Qual, als letzten Schritt in der Umsetzung einer Webseite mit CSS Hacks (die das Stylesheet nat&uuml;rlich nicht valide machen) oder Conditional Comments das Layout den Fehlern des Internet Explorers anzupassen. F&uuml;r alle Leidensgenossen m&ouml;chte ich an dieser Stelle k&uuml;nftig Tipps und Kniffe beschreiben, die einem das Leben hinsichtlich dieser und anderer Probleme hoffentlich ein wenig leichter machen.
			</p>
			<p>
			Das CSS-Attribut &quot;<span class="inline_code">min-height</span>&quot; beispielsweise wird vom IE leider nicht unterst&uuml;tzt, kann allerdings simuliert werden, m&ouml;chte man auf oben angef&uuml;hrte CSS-Hacks oder Conditional Comments verzichten. Dies funktioniert auf einfachem Wege durch folgende Angaben im Stylesheet:
			</p>
			<p>
			<span class="code">
			height: auto !important; <span class="kommentar">/* Wird von modernen Browsern interpretiert */</span><br />
			height: 100%;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="kommentar">/* F&uuml;r den IE: wie min-height */</span><br />
			min-height: 100%;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="kommentar">/* min-height f&uuml;r alle anderen Browser */</span></span>
			</p>
			<p>
			Diese Zeilen funktionieren durch eine fehlerhafte Interpretation der Angabe <span class="inline_code">!important</span>, die validen Browsern mitteilt, dass die Angabe &quot;<span class="inline_code">auto</span>&quot; bez&uuml;glich der Element-H&ouml;he des Wertes &quot;<span class="inline_code">100%</span>&quot; vorgezogen wird, sprich, das Element soll bei &uuml;bergro&szlig;em Inhalt automatisch wachsen. Obwohl das Attribut <span class="inline_code">height</span> im eigentlichen Sinne eine H&ouml;he festlegt, l&auml;sst der IE dennoch eine dynamische Vergr&ouml;&szlig;erung des Bereiches zu, sollte der Inhalt wachsen. <span class="inline_code">height</span> wird demnach vom Internet Explorer generell als <span class="inline_code">min-height</span> interpretiert. In diesem Sinne existiert die Angabe <span class="inline_code">min-height</span> sowieso nur f&uuml;r Browser, die CSS zumindest in dieser Hinsicht valide interpretieren, die Angabe <span class="inline_code">height: auto !important</span> setzt nur die 100%-ige H&ouml;henangabe ausser Kraft.
			</p>
			<p>
			An dieser Stelle sei generell noch einmal auf <a href="http://de.selfhtml.org" target="_blank">SelfHTML</a> hingewiesen, denn dort lassen sich viele Attribute nachschlagen. Informationen bez&uuml;glich Conditional Comments und CSS-Hacks werden dort auch sehr gut erkl&auml;rt. 
			</p>
			 ]]></description>
		</item>
		<item>
			<title>Bundestrojaner und Vorratsdatenspeicherung</title>
			<link>http://www.josupeit.com/weblog~informatik-und-technik,bundestrojaner-und-vorratsdatenspeicherung.html</link>
			<guid>http://www.josupeit.com/front_content.php?lang=1&amp;idart=18</guid>
			<pubDate>Wed, 24 Oct 2007 22:09:02 +0200</pubDate>
			<author>webmaster@josupeit.com (Manuel Josupeit-Walter)</author>
			<description><![CDATA[ <p>
			An jeder Ecke h&ouml;rt und liest man momentan vom Bundestrojaner: einem trojanischen Pferd, einer Art Computervirus, der dem Staat unterst&uuml;tzend zur Seite stehen soll, wenn es darum geht PCs verd&auml;chtiger B&uuml;rger genauer unter die Lupe zu nehmen. Wer oder was so alles &quot;verd&auml;chtig&quot; ist und den leichtfertigen Einsatz eines solchen Trojaners rechtfertigt, wage ich an dieser Stelle allerdings nicht zu beurteilen.
			</p>
			<p>
			So langsam habe ich mich mit dem Thema Bundestrojaner abgefunden, Firewalls auf Lecks gecheckt, Festplatte verschl&uuml;sselt, automatische Updates ausgestellt (<a href="http://blog.markus-pachali.de/2007/09/14/kommt-der-bundestrojaner-uebers-windows-update/" target="_blank">kommt der Bundestrojaner etwa &uuml;ber Updates?</a>), Windows gel&ouml;scht und Linux installiert und zu guter Letzt den Weg zur Netzwerkdose schon einmal frei ger&auml;umt und den Plastikn&uuml;ppel am Stecker abgebrochen, um im Fall aller F&auml;lle auch aus Distanz das Kabel aus der Dose zupfen zu k&ouml;nnen und schon diskutiert man &uuml;ber das n&auml;chste Thema: <a href="http://kaffeeringe.de/module-article-viewpub-tid-9-pid-335.html" target="_blank">Vorratsdatenspeicherung</a>.
			</p>
			<p>
			Offenbar ist geplant, zum Jahreswelchsel 2007/08 generell einmal von jedermann die Telefonverbindungen bis zu sechs Monate lang zu speichern; auch SMS sollen dann protokolliert werden und zwar nicht blo&szlig; mit Empf&auml;nger und Zeitstempel, sondern auch mit geographischem Standort zum Zeitpunkt des Versands. Im Klartext hei&szlig;t das: selbst der Ort von dem aus ich am Montag um 12:39 Uhr eine SMS an meine heimliche Geliebte schicke wird gespeichert, selbst, wenn es das stille &Ouml;rtchen ist. Die Frage, die sich nun durchaus stellen l&auml;sst ist: Ab wann empfinde ich das alles als zu gro&szlig;en Einschnitt in meine Freiheit? Werde ich bei meiner Shopping-Tour durch die Innenstadt meiner Wahl nicht bereits oft genug gefilmt? Reicht es nicht, dass man angeblich via Satellit die Schlagzeilen einer Zeitung lesen kann, die ich gerade an einem herrlichen Sommertag im Park lese? Stimmt all das &uuml;berhaupt?
			</p>
			<p>
			Ich denke, ich werde in die USA auswandern, da wird so etwas wie der Mensch doch noch gesch&auml;tzt, oder?&nbsp;
			</p>
			 ]]></description>
		</item>
	</channel>
</rss>