Sonntag, März 09, 2008

Cruise Control 1.4 und MSBuild/LaTeX

Diese Woche hatte ich mal wieder das Thema Build Integration bei uns angehen müssen. Der Auslöser war mal wieder die zwingende Aktualisierung von einigen Dokumenten unserer Anwendung. Außerdem habe ich eine Anwendung, die schon eine Weile nicht mehr funktionierte, nun kamen auch noch einige Bug Fixes dazu.

Grundsätzlich war der Build-Prozess bei uns immer so, dass wir Build-Skripte auf dem Server liegen hatte und auch notwendige Erweiterungen. CCNet konnte in früheren Versionen SVN-Dateien nicht (korrekt) abrufen, aus diesem Grund enthielten die Build-Skripte die Anweisungen zum Abrufen der Informationen aus der Versionsverwaltung. Zusätzlich wollten wir immer ein Clean-Build, d. h. der Server wird in den Ursprungszustand zurückgesetzt.

Sowohl abrufen, als auch das ausführen von Skripten vor dem eigentlichen Build ist mit den neueren CCNet Versionen möglich. (1.3 und 1.4) Somit werden nun die Skripte ordnungsgemäß versioniert und können sich auch in den Versionen deutlich unterscheiden. Ich hatte bereits vor einiger Zeit schon Teile unserer Build-Skripte angepasst, so dass Funktionen wie das Abrufen von Daten aus dem SCM-System nicht mehr ausgeführt wurden. Manche werden sich fragen, warum Dokumente über Build-Skripte erzeugt werden müssen, die Antwort ist ganz simpel, weil bei uns die Dokumente geTeXt sind.

Dokumente mit TeX bzw. LaTeX zu erstellen ist bei umfangreichen Dokumenten sehr nützlich und gerade bei einer Integration mit der Anwendung oder Build-Prozessen sinnvoll. Die großen Vorteile aus meiner Sicht sind:

·         Textbasierende Dokumente, dadurch effektives Merging möglich und geringere Größe

·         Wenige Formatierungen

·         Sauberes Schriftbild

·         Automatisches ersetzen von Platzhaltern, Versionsnummern der Anwendung, Versionsnummern des Dokumentes

Die Vorurteile, dass die Dokumente nicht mehr für alle lesbar sind, ist durch den Einsatz des Build-Systems ausgehebelt. Jeder kann sich das Finale Dokument laden und anschauen. Anmerkungen können genau zu einer Version gemacht werden. Hier das Target für die Erstellung der Dokumente:

  289   <Target Name="CreatePdf" DependsOnTargets="CreateRawFolderStructure">

  290     <!-- Eventuelle die Version der Anwendung setzen s-->

  291     <Message Text="Creating TexFile-Items! File is $(TexFile)" Importance="high"/>

  292     <CreateItem Include="$(SourceFolder)\**\$(TexFile)" Exclude="$(SvnExcludes)">

  293       <Output TaskParameter="Include" ItemName="texMaster"/>

  294     </CreateItem>

  295     <Message Text="Creating TexFile-Items  created! Versionnumber suffix is $(VersionNumberFileSuffix)" Importance="high"/>

  296     <CreateProperty Value="$(VersionNumberFile)-tex$(VersionNumberFileSuffix)">

  297       <Output TaskParameter="Value" PropertyName="TexVersionNumberFile"/>

  298     </CreateProperty>

  299     <CreateItem Include="$(SourceFolder)\**\*.tex" Exclude="$(SvnExcludes)">

  300       <Output TaskParameter="Include" ItemName="versionTexFiles"/>

  301     </CreateItem>

  302     <Exec Command="echo 1.0.0.0> &quot;$(VersionNumberFile)&quot;" Condition="!Exists('$(VersionNumberFile)')"/>

  303     <Version VersionFile="$(VersionNumberFile)" RevisionType="None" BuildType="None">

  304       <Output TaskParameter="Major" PropertyName="Major" />

  305       <Output TaskParameter="Minor" PropertyName="Minor" />

  306       <Output TaskParameter="Build" PropertyName="Build" />

  307       <Output TaskParameter="Revision" PropertyName="Revision" />

  308     </Version>

  309     <FileUpdate Files="@(versionTexFiles)" Singleline="false" Encoding="ISO-8859-1"

  310                 Regex="\\newcommand{\\Version}{.+}"

  311                 ReplacementText="\newcommand{\Version}{$(Major).$(Minor).$(Build)}"/>

  312 

  313     <Exec Command="echo 1.0.0.0> &quot;$(TexVersionNumberFile)&quot;" Condition="!Exists('$(TexVersionNumberFile)')"/>

  314     <Version VersionFile="$(TexVersionNumberFile)" RevisionType="Increment" BuildType="Increment" Condition="'$(CCNetLabel)'==''">

  315       <Output TaskParameter="Major" PropertyName="Major" />

  316       <Output TaskParameter="Minor" PropertyName="Minor" />

  317       <Output TaskParameter="Build" PropertyName="Build" />

  318       <Output TaskParameter="Revision" PropertyName="Revision" />

  319     </Version>

  320     <Exec Command="echo $(CCNetLabel)> &quot;$(TexVersionNumberFile)&quot;" Condition="'$(CCNetLabel)'!=''"/>

  321     <!-- immer Version herausholen -->

  322     <Version VersionFile="$(TexVersionNumberFile)" RevisionType="None" BuildType="None" >

  323       <Output TaskParameter="Major" PropertyName="Major" />

  324       <Output TaskParameter="Minor" PropertyName="Minor" />

  325       <Output TaskParameter="Build" PropertyName="Build" />

  326       <Output TaskParameter="Revision" PropertyName="Revision" />

  327     </Version>

  328     <FileUpdate Files="@(versionTexFiles)" Singleline="false"  Encoding="ISO-8859-1"

  329                 Regex="\\newcommand{\\DocVersion}{.+?}"

  330                 ReplacementText="\newcommand{\DocVersion}{$(Major).$(Minor).$(Build)}"/>

  331     <CreateProperty Value="$(CCNetArtifactDirectory)\texify.log">

  332       <Output PropertyName="TexifyLogFile" TaskParameter="Value"/>

  333     </CreateProperty>

  334     <Exec Command="&quot;$(LatexBinFolder)\texify&quot; -b --pdf -q --max-iterations=1 -e &quot;@(texMaster)&quot;" IgnoreExitCode="true" WorkingDirectory="@(texMaster->'%(RootDir)%(Directory)')" Outputs="$(TexifyLogFile)"/>

  335     <Exec Command="&quot;$(LatexBinFolder)\makeindex&quot; &quot;@(texMaster->'%(RootDir)%(Directory)%(Filename).nlo')&quot; -s nomencl.ist -o &quot;@(texMaster->'%(RootDir)%(Directory)%(Filename).nls')&quot;" IgnoreExitCode="true" WorkingDirectory="@(texMaster->'%(RootDir)%(Directory)')" Outputs="$(TexifyLogFile)"/>

  336     <Exec Command="&quot;$(LatexBinFolder)\bibtex&quot; &quot;@(texMaster->'%(RootDir)%(Directory)%(Filename)')&quot;" IgnoreExitCode="true" WorkingDirectory="@(texMaster->'%(RootDir)%(Directory)')" Outputs="$(TexifyLogFile)"/>

  337     <Exec Command="&quot;$(LatexBinFolder)\texify&quot; -b --pdf -q --max-iterations=1 -e &quot;@(texMaster)&quot;" IgnoreExitCode="true" WorkingDirectory="@(texMaster->'%(RootDir)%(Directory)')" Outputs="$(TexifyLogFile)"/>

  338     <!--<Exec Command="&quot;$(LatexBinFolder)\texify&quot; -b -pdf -e &quot;@(texMaster)" WorkingDirectory="@(texMaster->'%(RootDir)%(Directory)')" Outputs="$(TexifyLogFile)"/>-->

  339     <CreateProperty Value="@(texMaster->'%(RootDir)%(Directory)%(Filename).pdf')">

  340       <Output TaskParameter="Value" PropertyName="PdfResult"/>

  341     </CreateProperty>

  342     <Copy SourceFiles="$(PdfResult)" DestinationFiles="@(texMaster->'$(OutputPath)\%(Filename)_$(Major).$(Minor).$(Build).pdf')"/>

  343     <CreateItem Include="@(texMaster->'%(RootDir)%(Directory)Anlagen\*.*')" Exclude="$(SvnExcludes)">

  344       <Output ItemName="attachments" TaskParameter="Include"/>

  345     </CreateItem>

  346     <Copy SourceFiles="@(attachments)" DestinationFolder="$(OutputPath)\Anlagen"/>

  347   </Target>

Es ist auch möglich statt mit Regex die Dokumente anzupassen über ein Include-File alles Variable im Dokument in eine separate Datei auszulagern und diese während des Builds zu generieren. Die interessanten Zeilen in dem Skript sind die Aufrufe von Texify. Bei uns mussten die Anweisungen 2-mal durchlaufen werden, nach dem 1. Durchlauf wurden Index und Bibtex erzeugt/ausgeführt.

Das zweite Problem was auftrat war die Unterstützung von .NET Framework 3.5. Wobei ich hier einschränken muss, der Standard Logger ist gegen das .NET Framework 2.0 kompiliert, das Verursacht das Problem. Die Lösung ist eigentlich ganz einfach, Code nehmen und gegen .NET Framework 3.5 kompilieren. Leider habe ich die Quellen nicht gefunden. Nach etwas suchen habe ich mich dann für den „Improved MsBuild Logger“, allerdings habe ich zusätzlich noch die Lösung um einen detailierteren Build-Status zu erhalten gewählt "Viewing build progress". Beide Lösungen zusammen geworfen und angepasst und herausgekommen ist ein neuer Logger, ich wollte noch einige Infos über die Tasks haben. Eventuell werde ich noch ein separates Xslt schreiben, um die Timings besser auszuwerten. Den Fortschritt des Build zu sehen ist echt klasse, so hat man wenigstens einige Details zum Fortschritt. Der Logger wird wie gewöhnlich beim Aufruf angegeben, heraus kommt das Xml-File mit den Status-Infos.

Der Build-Prozess bei uns läuft nun so ab:

1.       Löschen aller Dateien – CCNET prebuild-Task mit MsBuild-Skript

2.       Abrufen der Sourcen aus der Versionsverwaltung – CCNET Sourcen abrufen

3.       Anstossen des eigentlichen Builds (kompilieren, Documente erstellen, FxCop, MSI erstellen, …) – MSBuild-Task

4.       Publishen der Sourcen – Über eigenen MsBuild-Task oder Publisher-Task

5.       Statistiken refreshen usw.

Ich habe leider kein vollständiges Projekt zur Hand, so dass es leider ohne Code gehen muss. L

Samstag, Februar 23, 2008

Sql Server Reporting Service Multivalue und die Integration in SharePoint

Am Wochende habe ich mich intensiv mit dem Sql Server Reporting Service beschäftigt, ich muss sagen, dass ich mir mal endlich richtig Zeit genommen habe und auch einige Tricky-Sachen gelöst habe. (Natürlich durch googlen) Letztendlich wollte ich dem Kunden ermöglichen in unserer Datenbank nach Einlieferungsnummern zu suchen, um so simple Fragen „Was ist mit meinen Daten passiert?“ selbst zu lösen. Der erste Schritt war das überfliegen eines Tutorials zu dem Thema. Das Beste was ich kenne, sind diese: Beginning SQL Server 2005 Reporting Services Part 1 - Building and deploying basic reports , Beginning SQL Server 2005 Reporting Services Part 2 , Beginning SQL Server 2005 Reporting Services Part 3 - The Chart Control und Beginning SQL Server Reporting Services Part 4 alle Artikel sind von Steve Joubert . Ich kann jedem diese Artikel nur Empfehlen.

Nun aber zu den eigentlichen Problemstellungen. Ich bin nun nicht gerade der beste zum Schreiben von Sql Statements, einige meiner Kollegen werden noch mit erschrecken zurückdenken. … Immer wenn ich an eine Prozedur in der DB ran wollte, weil es mir zu langsam ging, haben die Kollegen das Priorisiert gemacht, quasi gleich, denn immer nachdem ich an der DB war musste alles aufgeräumt werden … Die Statements gingen recht leicht, hätte ich gar nicht gedacht, ich hatte mir allerdings die Woche auch einige Tricks für die Erstellung und das zusammen setzen von komplexen Statements von einem Kollegen geholt. Für die Reporting Services sind die Datenquellen das wichtigste bei der Realisierung. Gerade bei der Realisierung von Online-Statements sollte man auf schnelle Ausfrührung und möglichst limitierte Daten achten. Gerade bei großen Ergebnismengen ist die Aufbereitung problematisch und zeitintensiv.

Für die Darstellung habe ich anschließend ein Drill Down Report gewählt, der über 4 Ebene/Gruppen geht, so wird die Anzeige kompakt und doch informativ.

Die Anforderung das MultiValue-Feld zu realisieren, war zunächst extrem schwierig umzusetzen. Den besten Tipp habe ich auf dem Blog RDA Corp – BI and Sql Server gefunden. Man benötigt für die Verwendung des Parameters die Prozedur um die Werte zurück zubekommen.

Parameter Expression: Join(Parameters!Param.Value, ",")

Statement:
… [tableSynonym].[KeyColumn] IN
(
SELECT [columniID]
FROM [schema].[table] tb, [dbo].[Split](@ItemList, ',') tmp
WHERE patindex('%' + tmp.Item + '%', tb.[KeyColumn]) > 0
)

Prozedur: ( RDA Corp – BI and Sql Server )
CREATE FUNCTION [dbo].[Split]
(
@ItemList NVARCHAR(8000 ),
@delimiter CHAR(1 )
)
RETURNS @IDTable TABLE (Item VARCHAR(200 ))
AS
BEGIN
DECLARE @tempItemList NVARCHAR(8000 )
SET @tempItemList = @ItemList
 
DECLARE @i INT
DECLARE @Item NVARCHAR(8000 )
SET @tempItemList = REPLACE (@tempItemList, @delimiter + ' ', @delimiter )
SET @i = CHARINDEX(@delimiter, @tempItemList )
WHILE (LEN(@tempItemList) > 0 )
BEGIN
IF @i = 0
SET @Item = @tempItemList
ELSE
SET @Item = LEFT(@tempItemList, @i - 1 )
INSERT INTO @IDTable(Item) VALUES(@Item )
IF @i = 0
SET @tempItemList = ''
ELSE
SET @tempItemList = RIGHT(@tempItemList, LEN(@tempItemList) - @i )
SET @i = CHARINDEX(@delimiter, @tempItemList )
END
RETURN
END

Nach dem der Report so richtig gut funktionierte, war es Zeit die Integration in den Sharepoint durchzuführen. Es gibt von MS ein Report Service WebPart für Sharepoint, außerdem hat man die Möglichkeit mit dem .NET FX2 das ReportViewer Webpart zu nutzen. Ich hatte zu erst versucht das fertige WebPart zu nutzen, bin dabei allerdings gescheitert, außerdem habe ich damit nicht die Möglichkeit kleinere Modifikationen durchzuführen. Also einen kleinen Wrapper für erstellt, der Connections-Akzeptiert, Parameter von einer anderen Quelle empfangen kann und über ein Parameter-Mapping verfügt. Man kann im Viewer-Control sehr schön die Ansichten modifizieren, so sind bei uns die Parameter nicht vorhanden, da diese durch ein anderes WebPart geliefert werden. Bisschen Probleme hat mir die Anzeige gemacht, da die Scrollbalken immer störten, leider konnte ich nicht einfach die gesamte Seitenhöhe verwenden, hier kann evtl. ein JavaScript helfen, aber es gibt wichtigeres.

Nach dem auch der Schritt erledigt war, hat ein Kollege sich den Report noch mal vorgenommen und versucht die Abfragen zu optimieren (ohne den Plan zu nutzen). Außerdem wurde das zugehörige DataWarehouse angepasst, um Datenstrukturen bereite optimiert vorzuhalten.

Man muss einfach sagen, dass die Reportings Services so viele extrem schöne Feature mitliefern, dass man diese einfach viel mehr nutzen sollte. Die Exportformate sehen sehr schick aus, richtig Klasse finde ich die Excel-Version des Reports. Man sollte bei der exzessiven Nutzung aber unbedingt die Serverresourcen im Auge behalten. Reporting kann sehr Rechenintensiv sein! Sorry, dass ich kein Bild vom Report einfüge, aber leider sind sehr viele vertrauliche Daten enthalten.

Hier noch eine weitere Webseite http://www.gotreportviewer.com/ mit vielen Tipps und Tutorials.

Donnerstag, Februar 21, 2008

Windows Vista Service Pack1

Wow, seit heute 19:30 zieht mein Rechner das Service Pack 1 über Windows Update. Ich bin vielleicht schockiert und habe schnell noch eine Sicherung des Rechners angeschmissen. Das Update wird gezogen, ohne das eine Veränderung an meinem System gemacht wurde. Jetzt bin ich mal gespannt, ob alles erfolgreich ist und danach noch alles ordentlich funktioniert. Ich vermute, dass das SP1 für x64 eher freigegeben wurde, da es schon am Anfang höhere Anforderungen an die Treiber gestellt hat.

Nun kann ich aber leider nicht den eigentlichen Blog-Post weiterschreiben, weil der Rechner gut beschäftigt ist. Ich habe schon einiges zusammengetragen für den Post und denke, dass ich ihn spätestens am Samstag fertig habe, wenn der Rechner nicht das zeitliche segnet.

Also bis auf weiteres Daumen drücken und die Meldungen der letzten Tage vergessen. (Loop restart with pre sp1, recovery after installing sp1, ...)


Update: Hab gestern bis kurz vor 23:00 das Backup laufen lassen und nach dem es abgeschlossen war das SP1 angeworfen. Nach dem ersten Schreck heute morgen, Rechner war nicht heruntergefahren, und den 2 reboots danach war alles Spitze. Service Pack ist installiert, System läuft noch. Bis jetzt weder positives noch negatives gemerkt. ICh freue mich schon darauf, wenn kein Delay mehr bei den Browser-Dialogs ist. Ansonsten geht nun die ganz normale Arbeit weiter.

Montag, Februar 18, 2008

Slowly blogging

In letzter Zeit habe ich das Bloggen etwas vernachlässigt, ich habe mich einfach z sehr in Arbeit eingedeckt. Ich wollte endlich unsere Portal-Anwendung live bringen. Dies hat aber leider nicht so richtig geklappt. Momentan gibt es erneut Diskussionen über die Navigation. Außerdem habe ich versucht noch einige Gimmicks einzubauen, allerdings bin ich mir noch nicht sicher, ob diese Funktion enthalten bleibt.

Ich habe immer enorm Schwierigkeiten, sobald ich alleine bin und Zeit zum nachdenken habe. Sie ist bestimmt schwer beschäftigt und hat für nichts Zeit, ich wünschte mir trotzdem, dass ich sie mal wieder sehe. Ich würde so gerne Informationen über sie hören und lesen, natürlich am liebsten sie treffen. Nur gleichzeitig macht mir das so Angst. Ich vermisse die Gefühle vom letzten Jahr, die Zeit mit ihr.

Am Wochenende habe ich eine tolle Zeit mit meinen besten Freunden verbracht. Die 4 sind schon was ganz spezielles und die beiden kleinen schaffen es 100ig einen abzulenken. Am Freitag habe ich mich zu dem mal mit Ex-Kollegen getroffen, die einige lustige Sachen über Timing bei meinem alten Arbeitgeber erzählt. Leider ist der Grund für die Erheiterung eigentlich nicht lustig.

Auf Arbeit läuft es momentan wie auf einem Schiff oder Achterbahn, es geht auf und ab oder auch hin und her. Es macht Spass, aber manchmal ist es einfach frustrierend. Wir haben seit 2 Wochen Storage, der Storage soll für unsere Virtualisierungsserver als Speicherplatz dienen. Leider musste wir feststellen, dass es nicht anzuschließen geht, zumindest bekommen wir das nicht hin.

Ich will die nächsten Tage einen kurzen Blog-Eintrag zum Sql Server Reporting Service erstellen, bzw. die Integration in ASP.NET/WSS.

Ich werde mir in nächster Zeit mehr Mühe geben, um regelmäßiger und pünktlicher zu bloggen.

Sonntag, Februar 10, 2008

ASP.NET Membership Provider custom password reset

Ich hatte schon länger Probleme mit dem Zurücksetzen des Passwortes in einer ASP.NET-Anwendung. Benutzt man nicht das Standardverhalten in dem man altes Passwort und neues Passwort abfragt, so hat man richtig Probleme ein Passwort-Reset durchzuführen. Diese Woche habe ich noch mal gegooglet und auch 2 Blog-Einträge mit einer ähnlichen Problemstellung gefunden. Der Blog-Eintrag „MembershipUser.ChangePasswort“ von Simon Steckermeier hat eine schöne Erläuterung der Problemstellung, einige kleine Macken hatten aber die Lösungen. Was passiert, wenn das Passwort nicht gesetzt werden kann, weil es die Regeln verletzt?

Also konnte ich die Lösung nicht so verwenden. Aber ein wenig ausprobieren und eine Lösung war gefunden. Allerdings kann man diese Lösung nicht mit Hashed-Passwords verwenden. Folgende Code-Zeilen sind meine Lösung:

string oldPW = Membership.Provider.GetPassword(this.txtUserName.Text, null);

string generatedPW = Membership.Provider.ResetPassword(this.txtUserName.Text, null);

try

{

Membership.GetUser(this.txtUserName.Text).ChangePassword(generatedPW, pw);

}

catch (ArgumentException ex)

{

Membership.GetUser(this.txtUserName.Text).ChangePassword(generatedPW, oldPW);

throw;

}

Unbedingt zu beachten ist, dass die web.config für die Provider-Einstellung korrekt eingestellt ist! Hier auch die Web.config-Attribute, die für den Provider entsprechend eingestellt sein müssen: enablePasswordRetrieval="true" enablePasswordReset="true" requiresQuestionAndAnswer="false" passwordFormat="Encrypted"

Im Anschluss ist alles super und die Password Veränderung kann man ansteuern, wie man möchte.

Sonntag, Januar 20, 2008

Exchange 2007 Webservice Zugriff mit VS 2008

Ich hab mich am Wochenende mit Exchange 2007 WebService Zugriff beschäftigt. Ich habe dazu auch einige nette Guides gefunden im Internet, unter anderem von Eric Lee. Meine Versuche gestalteten sich allerdings etwas schwieriger. Ich wollte alles mit Visual Studio 2008 machen, allerdings basiert hier alles auf WCF. Die generierten Proxy-Klassen sich komplett anders aus, so dass die Beschreibungen nicht ganz halfen.

Zu erst musste ich mal meine Konfigurationsdatei hinbiegen, irgendwann sah die Datei so aus:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
      <client>
        <endpoint name="CapeVisionExchange" address="https://mail.capevision.net/EWS/Exchange.asmx" binding="basicHttpBinding" bindingConfiguration="ExchangeServiceBinding" contract="ExchangeWebServices.ExchangeServicePortType" behaviorConfiguration="ServiceAuth">
        </endpoint>
      </client>
      <behaviors>
        <endpointBehaviors>
          <behavior name="ServiceAuth">
            <clientCredentials >
              <windows allowNtlm="true" allowedImpersonationLevel="Identification"/>
            </clientCredentials>
          </behavior>
        </endpointBehaviors>
      </behaviors>
        <bindings>
            <basicHttpBinding>
                <binding name="ExchangeServiceBinding" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <security mode="Transport">
                      <transport clientCredentialType="Ntlm" proxyCredentialType="None" />
                      <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
    </system.serviceModel>

</configuration>

Das war nicht mehr mit den alten WebService-Kenntnissen vergleichbar, allerdings es funktioniert.

Ich habe anschließend versucht mich nahe an dem Beispiel entlang zu hangeln, aber irgendwie war alles anders. Letztendlich habe ich es geschafft und einen Aufruf hinbekommen.  ExpandDL ist zur Abfrage von Distribution Lists (Verteiler) gedacht, eine komplette Dokumentation der WebServices gibt es in der MSDN. Nun aber mein Code-Brocken.
ExpandDLType dl = new ExpandDLType();
EmailAddressType addr = new EmailAddressType();
addr.EmailAddress = "<email>@capevision.de";
dl.Mailbox = addr;
ExchangeServicePortTypeClient exchange = new ExchangeServicePortTypeClient();
exchange.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
ExpandDLResponseType resp;
exchange.ExpandDL(null, null, "de-DE", null, dl, out resp);

Die Rückgabe der Methode enthält den Response und auch alle Nutzer der Liste. Aber am besten mal selber ausprobieren.

Mein zweiter Versuch zielte dann auf die Suche nach bestimmten Mail-Items, allerdings bin ich hier noch nicht glücklich. Ich habe 20 Zeilen Code (eine Übertreibung) und noch immer keine Ergebnisse. Am leichtesten hat sich die Entwicklung mit dem durchstöbern der Proxy-Klasse gemacht und immer wieder probieren. Fehlermeldung lesen, meist wird die Basisklasse genannt, anschließend in der Proxy-Klasse suchen und dann versuchen weiterzukommen. Meist beginnt der Prozess wieder von vorn. Nicht desto trotz hier mal der Code bisher: (bekomme keine Ergebnisse)
FindItemType item = new FindItemType();
item.Traversal = ItemQueryTraversalType.Shallow;
item.ItemShape = new ItemResponseShapeType();
item.ItemShape.BaseShape = new DefaultShapeNamesType();
item.ItemShape.BodyTypeSpecified = true;
item.ItemShape.BaseShape = DefaultShapeNamesType.Default;
GroupByType g = new GroupByType();
g.Order = SortDirectionType.Ascending;
item.Item1 = g;
PathToUnindexedFieldType u = new PathToUnindexedFieldType();
u.FieldURI = UnindexedFieldURIType.itemParentFolderId;
g.Item = u;
g.AggregateOn = new AggregateOnType();
g.AggregateOn.Aggregate = AggregateType.Minimum;
g.AggregateOn.Item = u;
item.Restriction = new RestrictionType();
ContainsExpressionType c = new ContainsExpressionType();
c.ContainmentMode = ContainmentModeType.Substring;
c.ContainmentComparison = ContainmentComparisonType.IgnoreCase;
PathToUnindexedFieldType pi = new PathToUnindexedFieldType();
pi.FieldURI = UnindexedFieldURIType.itemSubject;
c.Item = pi;
c.Constant = new ConstantValueType();
c.Constant.Value = "Test";
item.Restriction.Item = c;
IndexedPageViewType i = new IndexedPageViewType();
i.Offset = 0;
i.MaxEntriesReturned = 10;
item.Item = i;
DistinguishedFolderIdType id = new DistinguishedFolderIdType();
id.Id = DistinguishedFolderIdNameType.inbox;
item.ParentFolderIds = new BaseFolderIdType[] { id };
item.SortOrder = new FieldOrderType[1];
item.SortOrder[0] = new FieldOrderType();
item.SortOrder[0].Order = SortDirectionType.Ascending;
item.SortOrder[0].Item = pi;
ExpandDLType dl = new ExpandDLType();
EmailAddressType addr = new EmailAddressType();
addr.EmailAddress = "<email>@capevision.de";
dl.Mailbox = addr;
ExchangeServicePortTypeClient exchange = new ExchangeServicePortTypeClient();
exchange.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
FindItemResponseType findResp;
exchange.FindItem(null, null, Thread.CurrentThread.CurrentUICulture.ToString(), null, item, out findResp);
Console.WriteLine(resp.ToString());

Sonntag, Januar 13, 2008

VMWare ESX 3.5 Windows AD

Diese Woche waren noch mal eher Support Themen zu bearbeiten. Allerdings war der Freitag sehr interessant, wir haben die Entscheidung für VMWare ESX als Betriebssystem für unsere neuen Server (jeder 2*Quad Core mit 14GB Ram) gemacht. Nach dem die Entscheidung gefallen war, haben wir den ersten Server mit VMWare ESX installiert (momentan nur als Trial). Die Einrichtung lief recht Problemlos, abgesehen von einem Tastatur und Bildschirmproblem. Wie bei vielen Linux Installationen, hab es Probleme auf unserer Console mit der Anzeige, so dass ein guter alter Monitor her musste. Bei der Tastatur haben wir es richtig getroffen. Wir haben an der Server Console Englisches Tastaturlayout, eigentlich ist das noch kein Problem, allerdings versucht mal eine Pipe einzugeben.

Nach der Installation wollten wir den ESX mit dem AD Verbinden, schließlich will keiner die Nutzer doppelt pflegen. Um den Rechner ins AD zu bekommen, haben wir folgende Schritte durchführen müssen:

1.       Auf dem DC: Rechneraccount in der Domaine anlegen und „Pre-Windows 2000 Computer“ setzen.

2.       Auf dem DC: KTPASS aus den Windows Support-Tools ausführen “ ktpass.exe -princ HOST/<DC>@<FQDN DOMAIN in Großschrift> -mapuser <NETBIOS DOMAIN>\<HOST>$ -crypto all -pass <PW> -ptype KRB5_NT_PRINCIPAL -out <FILE>”

3.       Im ESX: Remote SSL aktivieren. (bei uns für Root) Dazu muss man die /etc/ssh/sshd_conf editieren und „PermitRootLogin = yes“ setzen

4.       Im ESX: Restart SSH Dienst „service sshd restart“

5.       Im ESX: “esxcfg-auth --enablead --addomain=<DOMAIN> --addc=<FQDN DC>” noch einige Details gibt es hier.

6.       Im ESX: „Adduser<name>“

7.       Eventuell noch die Firewall auf dem ESX anpassen, das kann über die Virtual Infrastructure Console geschehen.

Was uns so nicht bewusst war, wir brauchen noch einen Windows Server um den Virtual Infrastructure Server aufzusetzen und wirklich die volle Funktionalität nutzen zu können. Ich denke mal, dazu nächste Woche mehr.

Nette ausführliche Anleitung und Tipps zur AD-Integration gibt es hier. Hier der Guide von VMWare. Hier auch noch eine Liste mit weiteren wichtigen Befehlen des ESX-Servers.

Für de nächsten 50 Tage haben wir so erst mal 2 ESX Server zum testen, vermutlich werden wir die Server danach mit dem Licencekey bestücken. Dann bis ich mehr von der VMWare Front habe.

Unsere neuen Server haben nur ein einziges Problem, wir haben keine ausreichende Klimaanlage, so dass Server nicht die ganze Zeit an bleiben dürfen, aber auch dafür werden wir eine Lösung finden. Ein Freund hatte mal bei seinem Rechner einen Ventilator daneben gestellt. Hat immerhin funktioniert. Vielleicht machen wir das auch noch ;)

Samstag, Januar 05, 2008

2 Foliensätze zu SVN/TRAC

Das Neue Jahr ist da und viel habe ich in der ersten Woche nicht viel an technischen News parat, habe die Woche viel Support gemacht. Ich habe die Woche für einige Kollegen einen Crashkurs zur Nutzung von SVN/TRAC gehalten. Für den Kurs habe ich als Intro einen alten Vortrag recycled. Hier die beiden Vorträge:

·         Subversion-Tortoise-Svn-Crashkurs

·         Trac-Svn-Vss

Ansonsten kann ich nächste Woche nur den Techtalk zum Thema Ajax empfehlen. Termin und Ort findet ihr auf der Microsoft Seite.

Ich bin die Woche auch Schritt-für-Schritt mit meinen Sharepoint Authentification-/Authorization-Problem weitergekommen. Irgendwas läuft in meinem Custom-Code, der bereits durch einen Kollegen umgeschrieben wurde immer noch schief. Wahrscheinlich werde ich alles wegschmeißen, googlen und alles neu machen.

Sonntag, Dezember 30, 2007

Jahresrückblick 2007

Dieses Jahr war mal wieder ein Jahr mit vielen technischen Themen. Größte Themenblog im 1. Halbjahr war der BizTalk Server 2006. Hier vor allem der elektronische Rechnungsdatenaustausch und die Entwicklung bei einem Kunden, ebenfalls zum Thema Rechnungsaustausch und EDI. Ich habe wirklich viele Erfahrungen mit dem BizTalk gewonnen. Das Thema BizTalk begleitete mich immer weiter durch das Jahr, wirklich abgeschlossen war es nicht, allerdings nicht mehr so massiv. Im ersten Quartal war außerdem noch Erfahrung sammeln und Erweitern einer Fahrzeugtracking-Komponente bzw. Tour-/Auftragsübermittlung. War wirklich spannend und man sieht mal, was alles so als Produkt vertrieben wird. Interessant ist Fahrzeugtracking eigentlich für jeden Fuhrpark.

Das 2. Halbjahr war eigentlich das Thema Sharepoint führend. Also Sharepoint-Technologien 2007 sind wesentlich netter und interessanter als die Vorgänger, allerdings immer noch teilweise sehr „spannend“ im Verhalten. Dieses Problem führte in der letzten Woche zur Verschiebung eines GoLives einer Applikation. Dennoch ist Sharepoint auch für Webseiten eine Interessante Alternative, hier mal einige Beispiele von diesem Jahr, www.smartpath.de, www.callparts.de, ersatzteile.callparts.de. Alle diese Seiten nutzen leider noch nicht den gesamten Funktionsumfang des Sharepoints, allerdings kann das alles noch kommen. Mit dem Sharepoint wurde teilweise auch der Einsatz von Ajax-Technologien verbunden. Was sich allerdings ohne das angekündigte Service Pack 1 für Sharepoint als Schwierig gestaltete

Ein anderes Thema, dass im Zweiten Halbjahr Erfolge feierte, war die Einführung von Subversion bei uns. Bei uns meinte ich jetzt SD&C und CapeVision, wir Entwickler nutzen das bei CapeVision bereits als Standard, allerdings wurden bisher nur Sourcen abgelegt. Nach der geleisteten Überzeugungsarbeit im ersten Halbjahr bei einem Projektleiter, war die Einführung nicht mehr ganz so schwer. Die Geschäftsführung musste allerdings noch überzeugt werden. Auch der zweite involvierte Projektleiter stimmte für Subversion. Was allerdings für eine breite Akzeptanz fehlte, war die einfache Möglichkeit Projekte anzulegen. Zu diesem Zweck habe ich mich an die Entwicklung einer Applikation (natürlich in der Freizeit) gemacht, die die Anforderung abbilden kann. Meine erste Idee war die Realisierung auf Basis der BizTalk Technologie und Sharepoint, diese Idee musste ich verwerfen, da es schwieriger war als gewünscht. ABER es gab das .NET Framework 3.0, welches Workflow Komponenten (Workflow Foundation - WF) und Service Hosting Komponenten (Window Communication Foundation - WCF) enthält. Außerdem kam für das Front-End eine Web-Applikation mit Ajax Unterstützung zum Einsatz. Letztendlich sorgt die Applikation dafür, dass das Projekt als Repository angelegt wird, die Basis-Struktur nach derzeitigem KM (Konfigurationsmanagement)-Stand erzeugt wird, Benutzerrechte definiert werden und das Projekt-Ticketsystem Trac angelegt wird. Nun werden alle Dokumente (außer VMs) in das Repository eingecheckt.

Eine Technologie, die sich durch das ganze Jahr zog war die Virtualisierung. Dabei kamen bei uns beide großen Systeme Microsoft Virtual PC/Virtual Server und VMWare Workstation/Server zum Einsatz. Allerdings verschob sich im Laufe des Jahres alles Richtung VMWare aufgrund der besseren Unterstützung von Peripherie.

Noch wichtig zu erwähnen, dass im November endlich Visual Studio 2008 und das .NET Framework 3.5 released wurden. Hier sind auf jeden Fall die ASP.NET 3.5 Extension zu empfehlen! Ach ja, ich hab nach über 2,5 Jahren endlich den MCAD komplettiert.

Eine weitere Technologie des Jahres ist aus meiner Sicht Instant Messageing. Endlich setzt sich IM auch in Unternehmen zu nehmend durch. Wir sind auf Jabber/XMPP umgestiegen, da es uns leichter und unabhängig ermöglicht einen Server zu betreiben. Wir nutzen Openfire als Server, der sehr einfach aufzusetzen ist und sehr gute Unterstützung bietet. Bei den Clients wählt jeder nach belieben. Zum einen nutze ich PSI, Kollegen nutzen Spark, Miranda oder auch Trilian.

Samstag, Dezember 22, 2007

Weihnacht ist da

Nun ist die Weihnachtszeit auch bei mir angekommen. Ich habe heute Morgen noch das Geschenk für meinen Bruder besorgt, was ich übrigens schon die ganze Woche machen wollte. Ich bin nun auf dem Weg zu meinen Eltern und versuche etwas Entspannung zu finden. ;) Mal einige alte Freunde wieder treffen wäre auch nicht schlecht, aber dazu muss erst ein Termin her.

Ich wünsche allen eine ruhige, friedliche und besinnliche Weihnachtszeit mit den Liebsten. Außerdem noch ein gutes Überstehen der Weihnachtsessen und Naschaktionen. Vielleicht klappt‘s ja auch mit einigen wenigen Schneeflocken dies Jahr. Hier in Finsterwalde ist übrigens schon einiges weiß, sogar die Straßen.

Sonntag, Dezember 16, 2007

Urlaub vorbei

Puuuh, also die Woche war noch mal etwas hecktischer, allerdings habe ich es so geschafft meine Gedanken an meine Ex zu reduzieren. War aber immer noch schrecklich, zumal ich wieder richtig schlecht schlafe. Montag habe ich, wie schon zu lesen war, endlich meinen MCAD fertig gemacht. Dazu musste ich am Sonntag mal einige Stunden missbrauchen um mich noch mal intensiv vorzubereiten. Dafür durfte ich dann am Montag Abend mal wieder Kinder hüten. War eigentlich ganz angenehm, außer dass man dann gar keine Ablenkung mehr hat, wenn die Kinder super schlafen.

Die nächsten 2 Tage war dann das Spielen an einer Webseite dran, wo ich auch einige neue Erfahrungen mit Lokalisierung erhalten hab. Nebenbei habe ich auch immer versucht eine Geschenkidee für meinen Bruder und seine Frau zu bekommen, aber ich habe immer noch den gleichen Stand. Die 2 Tage ASP.NET speilen hat sogar ein Ergebnis, dass nicht nur aus Wissen besteht.

Am Freitag war „großes“ Firmenmeeting, vorher noch eine kleine Abstimmungsrunde im .NET Bereich. Leider waren wir nur zu Zweit, so dass die Diskussionsrunde sich nur auf 2 begrenzt hat. Ich denke allerdings, dass es dadurch sehr produktiv war und auch einige gute Ziele und Vorgehen für kommende Events hat. Der Abend war auch recht nett und wurde richtig lang. Wir bekommen extrem viele neue Kollegen im nächsten Jahr, dass ist wirklich erschreckend. Leider verlässt uns auch eine Kollegin, allerdings auch gut verständlich, da diese immer weit wegfahren musste zum Arbeiten und das sich auch nicht mit ihrem Studium vertragen hat. Ich wünsche ihr aber viel Erfolg beim neuen Arbeitgeber und viel Spaß. Ansonsten hatte ich auch einige interessante, schockierende Aussagen gehört, die ich hier aber nicht posten werde. Gespräche mit den Chefs sind auch immer sehr Aufschlussreich. Zu dem hat jeder Mitarbeiter ein dickes Weihnachtsgeschenk in Form eines Candle Light Dinners bekommen. Ich habe blöderweise auch erfahren, dass aus unserem Testen viel weniger wird, weil ein Kollege nahezu die ganze Woche noch wo anders arbeitet. (aus 3*4PT sind nun noch 2*3,5PT geworden)

Mein Wochenende besteht aus dem spielen mit Windows 2008 und dem Warten auf das Service Pack für Vista. :) Am Montag gehe ich erst mal fleißig an Regressionstests. Am Mittwoch ist ein Jahresabschlussessen mit einigen alten Azubis. Ach und ich muss mein Fahrrad irgendwie reparieren. Es bremst immer am Hinterrad und ich hab keine Ahnung, was ich bei der selbsteinstellenden Bremse noch machen soll.

ASP.NET Localization

Ich hab in der letzten Woche bisschen an einer Webseite gefummelt. Dabei habe ich mal das Problem mit der Lokalisierung erneut angehen wollen. Wie bringe ich eine Webseite dazu die Sprache nach dem Nutzer auszurichten. Einige interessante Erkenntnisse sind mir dabei aufgefallen.

Der erste Schritt war es, dass Menü konfigurierbar zu machen. Das Menü ist mit Standard ASP.NET mitteln gebastelt, d. h. Sitemap, ASP-Menu und Breadcrumb. Nach einigem lesen bin ich hier schnell auf eine Lösung gefunden, die beeindruckend einfach ist. Das Sitemap file muss zu jedem Resourcen-Eintrag einen Resourcekey enthalten, mittels dem Resource-Key wird in der Resource-Datei nach dem Eintrag gesucht. Auf jeden Fall das Attribut „enableLocalization“ auf „true“ setzen.

<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" enableLocalization="true">

<siteMapNode url="/" title="Home" description="Startseite" resourceKey="Root">

<siteMapNode url="/Me/default.aspx" title="Über mich" resourceKey="MeRoot">

<siteMapNode url="/links.aspx" title="Links" resourceKey="Links"/>

</siteMapNode>

</siteMap>

Zu jedem Eintrag kann eine Resource angelegt werden. Die Resource muss den selben Namen wie die Datei haben und im Global-Resource-Folder abgelegt sein. So muss mindestens die Datei „Web.sitemap.resx“ (bei Standardkonfiguration) existieren, wird eine lokalisierte Resource benötigt, so muss der Name der Culture angegeben werden, so z. B. „Web.sitemap.de.resx“ oder „Web.sitemap.fr.resx“. Ich habe die Erfahrungen nur mit Neutral-Cultures gemacht, aber ich denke, dass es auch mit der Specific-Culture funktioniert. Die Einträge in der Datei bestehen immer aus dem Resource-Key und dem Attribute-Namen.

Links.description External links
Links.title Links
Root.description
Root.title Startseite

Dieser Mechanismus ermöglicht es auch eigene Attribute zu verwenden.

Der Kompliziertere Teil war die Lokalisierung der Seiteninhalte. Hier gibt es 2 Wege, der 1. Fällt mir gerade nicht ein, hat allerdings auch nicht funktioniert, wenn man die Sprache manuell verändern möchte. Der von mir gewählte Weg nutzt Literal-Controls und Dynamische Control-Expressions. Der Inhalt der Seite muss an allen Stellen, die mehrsprachig sein sollen mittels controls aufbereitet werden.

<h1><asp:Label ID="lblHeadline" runat="server"

Text="<%$ Resources:PageDefault, Headline %>"></asp:Label></h1>

<p><asp:Label ID="Label1" runat="server"

Text="<%$ Resources:PageDefault, IntroductionArticle %>"></asp:Label></p>

In der Resourcen Datei “ PageDefault.resx” sind die Einträge „Headline“ und „IntroductionArticle“ definiert. Hier wird für weitere Sprachen das gleiche Verhalten wie bereits bei der Sitemap verwendet, z. B. „PageDefault.de.resx“.

Der so vorhandene Mechanismus passt die Sprache immer an die Browser-Einstellungen des Benutzers an. (IE: Tools-->Internet Options-->Language)
IE Language Settings

Um nun die Einstellungen manuell setzen zu können, muss etwas Code (leider in jede Seite eingefügt werden). Im ersten Schritt aber erstmal das setzen. Dazu habe ich meiner MasterPage die Sprach-Buttons und das Event dazu definiert. Durch klicken auf den Button wird das Server-Event ausgelöst. Im einfachsten Fall könnte der Code so aussehen:

Session.Remove("lang");

Session.Add("lang", System.Globalization.CultureInfo.GetCultureInfo(btn.CommandArgument));

Server.Transfer(this.Request.Url.PathAndQuery, false);

Am Ende wird ein Server.Transfer gemacht. Der Grund für dieses Verhalten ist im Standardmechanismus des .NET-Fx. Hier ist mal der Code umd die Sprache tatsächlich zu setzen:

protected override void InitializeCulture()

{

object o = Session["lang"];

if (o != null)

{

System.Threading.Thread.CurrentThread.CurrentCulture =

System.Threading.Thread.CurrentThread.CurrentUICulture = (CultureInfo)o;

}

base.InitializeCulture();

}

InitializeCulture ist eine Standard-Methode innerhalb des .NET-FX, allerdings kann der Code nicht in der MasterPage eingefügt werden. Außerdem muss für die gewählte Lösung das Paging aktiviert werden.

Ich hoffe, ich habe nix vergessen und wünsche viel Spass beim Anpassen des Internets. :)

Montag, Dezember 10, 2007

Endlich MCAD

Nach dem ich die letzte Prüfung zum MCAD über 2,5 Jahre hinaus geschoben habe, habe ich die Prüfung vor wenigen Stunden bestanden. Ich bin endlich ein MCAD! Die Prüfung enthielt schon einige echt … Aufgaben, aber zum Glück auch typische Webservice-Fragen, so dass ich die Prüfung mit 920 Punkten geschafft habe.

Nächstes wird eine der beiden Upgrade-Prüfungen für den MCPD sein, entweder 70-551 für Web-App oder 70-552 für Windos-App sein. Mal schauen, aber vermutlich werde ich die Prüfung noch innerhalb der Gültigkeit des „Second Shot“ machen.

Donnerstag, Dezember 06, 2007

Zum Nikolaus was kleines

Eigentlich wollte ich nix schreiben, aber da Nikolaus ist, habe ich mich nun dazu durchgerungen etwas zu schreiben.

Ich habe fast nix zum Nikolaus bekommen. Fast, weil eine gute, alte (sieht attraktiv aus und ist jünger als ich) Freundin mir eine nette, lustige SMS geschrieben hat. Ich hätte auch gern jemanden einen schönen Nikolaus gewünscht, am liebsten auch was Kleines geschenkt. Leider habe ich versprochen sie nicht mehr zu belästigen und nun kann ich ihr nicht mal was schreiben. Dieses Schicksal wird mich noch 1 Monat bis Ende Januar begleiten. Ich will sie einfach nicht nerven. Ich war heute mal draußen, das ist deshalb so ungewöhnlich weil ich mich die letzten 3 Tage in meiner Wohnung verkrochen habe und nicht mal raus wollte.

Urlaub ist echt hart. Ich hab allerdings auch mal etwas Zeit, in der ich an was anderes denke, bzw. keine Zeit habe an sie zu denken. Meistens ist das, wenn ich CoD4 zocke. Leider kann ich mich da nicht länger als 2h am Stück vor hocken, weil ich sonst einen riesen Schädel habe. Ich werde morgen meinen Schädel weiter bearbeiten.

Montag, Dezember 03, 2007

Smart Client Software Factory Erfahrungen

Nun endlich mal was zu dem Thema SCSF.

Wer die SCSF installieren möchte, der sollte dafür am besten eine VM nutzen. Man benötigt einiges an Beta-Software für den Client. Unbedingt auch die Versionen beachten. Es könnte sonst passieren, dass nicht viel geht. Aktuell ist das Mai 2007 CTP Release, dazu benötigt man:

·         Guidance Automation Extensions

·         Guidance Automation Toolkit

·         Optional VS2005 Extensions für .NET 3.0

Gute Arbeit leistet aber der Dependency Checker, der bei der SCSF mitgeliefert wird. Alle notwendigen Downloads werden vom Checker geprüft und die Links zur Verfügung gestellt.

Wer eine Installation unter Visual Studio 2008 wagen möchte, der sollte mal im Blog von Ezequiel Jadib vorbeischauen. Der Post ist allerdings für Orca Beta 2, wer etwas Ahnung hat, der sollte sonst aber auch keine Probleme haben. Ich habe das nicht ausprobiert, da ich wie oben geschrieben hab, die Installation in einer VM durchgeführt habe.

Die Hands on Labs (HOL) sind leider auch noch in einer Beta Phase und noch nicht komplett, aber um einen Einstieg zu erhalten, sind sie super.

Als Anwendung bieten sich eigentlich alle Anwendungen an, die im Intranet eines Unternehmens ausgeführt werden. Durch die saubere, manchmal auch etwas aufwendigere, Aufteilung und Entkopplung können Module leicht auf Veränderungen reagieren. Die Entkopplung ist bereits in vielen anderen Factories enthalten und ist definitiv für eine verbesserte Wartbarkeit durchzuführen.

Dies ist jetzt mein 3. Oder 4. Anlauf, wenn ich die CAB-Versuche mit zähle, mich in die Materie und Verwendung einzuarbeiten. Man sollte sich dafür durchaus 20h Zeit nehmen und einfach die HOLs von vorn bis hinten durchgehen. Bevor danach die Arbeit losgeht, sollte man sich aber noch mal Gedanken, wie bei jedem Projekt, über die Module machen. Ebenso ist es wichtig die Aufteilung/Layout des SCSF-Workspace zu beachten.

Ich werde mich das nächste Jahr weiter mit verschiedenen Modulen beschäftigen, unter anderem ein Modul zum Bearbeiten einer SVN-Authz-Datei und zur besseren Pflege von Stammdaten in unserem Unternehmen. Die für mich interessanteren Stammdatenpflege-Module sind unsere Mitarbeiterkontakte und die Projektdaten. Wer jetzt schreit Kundendaten kann er auch noch machen, wenn er schon Mitarbeiterdaten entwickelt, der irrt aus meiner Sicht. Kundendaten sind wesentlich Komplexer und werden vermutlich in anderen/mehreren Datenquellen abgelegt. Mitarbeiter Informationen sollten alle aus dem Active Directory kommen. Natürlich muss man dafür das AD-Schema evtl. erweitern. Mal schauen, wie schwierig es wird alle Daten in das AD zu überführen. Allerdings bedarf es vor dem Beginn der Mitarbeiterpflege einiger Nachforschungen der Informationen der Mitarbeiter.

Ich werde den Service zum ändern der SVN-Authz-Datei, sobald er fertig ist hier zur Verfügung stellen. Momentan ist das Laden implementiert, dies ist allerdings noch nicht bis ins kleinste getestet, was auch noch eine Weile dauern wird. Momentan will ich es einfach zum Laufen bringen.