WRITELINE

Geek. Coder. Gamer. Bayern Munich Fan.

Visit my blog stream http://writeline.io

  • Dariusz quatscht

    Programming Twitter with WCF 3.5

    • 3 Comments

    Do you Twitter? If so, this could be of interest for you. If not, maybe you are interested in how to use the Twitter REST API to write own client applications.

    Imagine you could just use Twitter from your code like this:

       1: TwitterStatusProxy proxy = new TwitterStatusProxy( "username", "password" );
       2:  
       3: // retrieve friends timeline
       4: XElement timeline = proxy.GetFriendsTimeline();
       5:  
       6: // do whatever you want to do with the data

    I just wrote up a demo for a security talk I gave last friday, using the Twitter API from WCF 3.5. One interesting scenario using Twitter, beside its origin to update the current status of the user, is to integrate the pub/sub system with SMS capabilities into an application. Imagine, you have a bunch of field workers on the road and they could just update status information on ongoing business via the Twitter infrastructure or the way back from the central to the field workers. You receive status information via SMS and are up to date. This scenario is especially interesting in Countries where SMS costs are still high. You have up to 250 SMS per week when using Twitter (in the US, I think there is not this limit). Could be a huge amount of money to spare. Ok, there is of course one drawback, the reliability of the plattform. I have no idea how well it scales if it is under pressure and how often downtimes are. Meanwhile you have an API call to get informed about planned downtime slots.

    Anyway, I want to show you how to use Twitter with WCF 3.5. Here we go. Twitters API is almost an authenticated one, this means for most calls you have to authenticate yourself before calling into the API. Therefore I have chosen to always provide a username and password in the constructor of the proxy class. I decided also to use for each category an own proxy implementation. Of course, I created a base class to inherit (similar to ClientBase, less functionality) from and all proxies are using this class. My last decision was not to model data contracts or value objects. I decided just to leave it as an XElement, this has the advantage that anyone is free to provide own mapping objects on top of the proxy.

    Here is the generic base proxy class

       1: public abstract class TwitterProxyBase<T>
       2: {
       3:     protected T proxy;
       4:     protected readonly string twitterBaseUri = "https://twitter.com";
       5:  
       6:     protected TwitterProxyBase( string username, string password )
       7:     {
       8:         this.CreateProxy( username, password );
       9:     }
      10:  
      11:     protected void CreateProxy( string username, string password )
      12:     {
      13:         WebHttpBinding binding = new WebHttpBinding();
      14:         binding.Security.Mode = WebHttpSecurityMode.Transport;
      15:         binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
      16:  
      17:         ChannelFactory<T> channel = new ChannelFactory<T>(
      18:             binding,
      19:             this.twitterBaseUri );
      20:  
      21:         channel.Endpoint.Behaviors.Add( new WebHttpBehavior() );
      22:  
      23:         channel.Credentials.UserName.UserName = username;
      24:         channel.Credentials.UserName.Password = password;
      25:  
      26:         proxy = channel.CreateChannel();
      27:     }
      28: }

    No error handling in my code, as I just wrote that one for the demo, you should include Error-handling. From this base class you just have to inherit and write a little proxy helper. In general I'm using the WCF 3.5 WebGet and WebInvoke attributes to decorate the proxy interface. This is how the Status API interface of Twitter looks in WCF decorated. I just shortened the class for more clarity.

       1: [ServiceContract]
       2: public interface ITwitterStatusXml
       3: {
       4:     // serveral operations missing for clarity
       5:     
       6:     [OperationContract]
       7:     [WebGet( UriTemplate = "/statuses/friends_timeline.xml", 
       8:              BodyStyle = WebMessageBodyStyle.Bare, 
       9:              ResponseFormat = WebMessageFormat.Xml )]
      10:     XElement GetFriendsTimeline();
      11:  
      12:     [OperationContract]
      13:     [WebGet( UriTemplate = "/statuses/friends_timeline/{screenName}.xml", 
      14:              BodyStyle = WebMessageBodyStyle.Bare, 
      15:              ResponseFormat = WebMessageFormat.Xml )]
      16:     XElement GetFriendsTimelineByScreenName( string screenName );
      17:  
      18:     [OperationContract]
      19:     [WebInvoke( UriTemplate = "/statuses/update.xml?status={status}", 
      20:                 Method = "POST", 
      21:                 BodyStyle = WebMessageBodyStyle.Bare, 
      22:                 ResponseFormat = WebMessageFormat.Xml )]
      23:     XElement Update( string status );
      24: }

    Line 7-10 and 12-16 are demonstrating GET operations on the Twitter contract, where line 18-23 are showing a POST.

    Now the proxy inherits the base class and this interface.

       1: public class TwitterStatusProxy : TwitterProxyBase<ITwitterStatusXml>, ITwitterStatusXml
       2: {
       3:     public TwitterStatusProxy( string username, string password )
       4:         : base( username, password )
       5:     {
       6:     }
       7:  
       8:     #region ITwitterStatusXml Members
       9:  
      10:     // most operations not included for more clarity
      11:  
      12:     public XElement GetFriendsTimeline()
      13:     {
      14:         return proxy.GetFriendsTimeline();
      15:     }
      16:  
      17:     public XElement GetFriendsTimelineByScreenName( string screenName )
      18:     {
      19:         return proxy.GetFriendsTimelineByScreenName( screenName );
      20:     }
      21:  
      22:  
      23:     public XElement Update( string status )
      24:     {
      25:         string encodedStatus = AntiXss.HtmlEncode( status );
      26:         if( encodedStatus.Length > 160 )
      27:         {
      28:             throw new ArgumentException( "Status information may not exceed 160 characters" );
      29:         }
      30:         return proxy.Update( encodedStatus );
      31:     }
      32:  
      33:     #endregion
      34: }

    That's it

    Now you can use Twitter from your application like I showed in the beginning. For instance to update the users status is as easy as to write

       1: TwitterStatusProxy proxy = new TwitterStatusProxy( "username", "password" );
       2:  
       3: XElement result = proxy.Update( "currently testing twitter" );

    If you are interested into the interface declarations for the whole Twitter API, send me an email at dparys add microsoft dot com. I will send you the C# project. Why this way, why not sharing? Because I have not tested the complete API declaration. I wrote those API during a train ride with no internet access and had no chance to test. Its up to you. Feedback welcome!

  • Dariusz quatscht

    Objekte mittels ADO.NET Data Services publizieren

    • 2 Comments

    Die ADO.NET Data Services (ehemals Astoria) ist ein REST basierter Zugriffsdienst auf Daten. Daten werden im Form von ATOM oder JSON zur Verfügung gestellt und könen mit den HTTP Verben entsprechend modifziert und bearbeitet werden.

    Ein Haupteinsatzszenario ist die Nutzung der ADO.NET Data Services um ein Entity Modell zu publizieren.

       1: public class MyDataService : DataService< EntityModel >

    Doch was muss man eigentlich tun, um ein eigenes Objektmodell als ADO.NET Data Service zu veröffentlichen? Die Dokumentationen hierzu muss man sich mühselig aus verschiedenen Quellen zusammensuchen. Gerade die Dokumentation zu den ADO.NET Data Services in der VS 2008 SP1 Beta 1 ist wirklich nicht einfach zu finden. Googlen oder Liven bringt nichts, findet man nicht. Deshalb hier der Link:

    http://vs2008sp1docs.msdn.microsoft.com/en-us/ms452029.aspx

    Auf MSDN Online gibt es noch zwei weitere Dokumente für die ADO.NET Data Services, die allerdings noch mit den alten Objektmodell Namen arbeiten. Die Inhalte sind jedoch auch für das neue Release gültig. Um aber ein eigenes Datenmodell nicht nur lesend, sondern auch modifizierbar, über die Data Services zu publizieren muss man noch ein wichtiges Interface implementieren: IUpdatable. Die Dokumentation hierzu ist in den folgendem Satz zusammengefasst:

    
    
    Write/Update Support

    To enable create, update, and delete support on a CLR data model, the class that models the top-level resource sets must implement the IUpdatable interface. In reference to Example 2, CLR Objects to Astoria resources above, the Accounting.DataModel class would be required to implement the IUpdatable interface.

    <Sarkasmus>Exzellente Dokumtation!</Sarkasmus>

    Ein bißchen mehr findet man dann doch noch auf dem Astoria Blog – hier ist wenigstens noch die Interface Deklaration mit Kommentaren gepostet. Nach Beispielen habe ich dann auch gar nicht mehr gesucht, wäre wohl auch Hoffnungslos.

    Trotz all dieser Probleme (wir sind ja in der Beta Phase) habe ich es dann doch noch geschafft mein kleines Beispiel-Objektmodell als Data Service mit Update Semantik zu publizieren. Im folgenden möchte ich einfach die Schritte zeigen, die ich durchlaufen bin, um das zu erreichen.

    Das Objektmodell

    Mein Objektmodell bildet Spiele der kommenden Europameisterschaft 2008 ab. Es besteht aus einer Klasse (kann man dann überhaupt schon von einem Modell sprechen?), diese hat nur ein kleine Besonderheit:

       1: [DataServiceKey( "MatchID" )]
       2: public class Match
       3: {
       4:     public int MatchID
       5:     {
       6:         get;
       7:         set;
       8:     }
       9:  
      10:     public string Home
      11:     {
      12:         get;
      13:         set;
      14:     }
      15:  
      16:     public string Away
      17:     {
      18:         get;
      19:         set;
      20:     }
      21:  
      22:     public int GoalsHome
      23:     {
      24:         get;
      25:         set;
      26:     }
      27:  
      28:     public int GoalsAway
      29:     {
      30:         get;
      31:         set;
      32:     }
      33: }

    DataServiceKey! Der DataServiceKey deklariert einfach die Felder, an welchem das Objekt eindeutig zu identifizieren ist. In meinem Beispiel habe ich die Eigenschaft MatchID als Schlüssel genommen. Genauso gut hätte ich auch die Spielpaarung selbst als Schlüssel wählen können, wie zum Beispiel [DataServiceKey( “Home”, “Away” )].

    Allerdings muss man kombinierte Schlüssel auch dementsprechend in der URI angeben, insofern habe ich mich für eine kürzere Variante entschieden.

    Zugriff auf Resourcen mittels URI

    Genau dieses Objekt möchte ich nun über dei ADO.NET Data Services addressierbar machen. Die URI sollte folgendermaßen aussehen:

    http://localhost/Euro2008DataService.svc/Matches

    Um nun ein bestimmtes Match zu laden, gibt man nun einfach die Schlüssel des Objektes, in dem Beispiel also die MatchID an.

    http://localhost/Euro2008DataService.svc/Matches(1)

    Hätte ich nun als Schlüssel Home und Away definiert und möchte das Spiel Deutschland gegen Pole suchen, so würde der Zugriff folgendermaßen aussehen:

    http://localhost/Euro2008DataService.svc/Matches(Away=’Poland’,Home=’Germany’)

    Das eigene Data Model

    Die Defintion des Datenmodells fehlt uns, um das Match Objekt als Data Service Resource zur Verfügung zu stellen.

       1: namespace MyDataService
       2: {
       3:     public class Euro2008DataModel
       4:     {
       5:         public IQueryable<Match> Matches
       6:         {
       7:             get
       8:             {
       9:                 return MatchRepository.Instance.ListOfMatches.AsQueryable<Match>();
      10:             }
      11:         }
      12:     }
      13: }

    Das Datenmodell greift auf eine Singleton Klasse zu die eine Liste von Matches im Speicher bereit stellt. Hier die Definition:

       1: public class MatchRepository
       2: {
       3:     private static MatchRepository repository;
       4:  
       5:     private List<Match> listOfMatches;
       6:     private static object locker = new object();
       7:  
       8:     private MatchRepository()
       9:     {
      10:         listOfMatches = new List<Match>()
      11:         {
      12:             new Match
      13:             {
      14:                 MatchID = 1,
      15:                 Home = "Germany",
      16:                 Away = "Poland",
      17:                 GoalsHome = 2,
      18:                 GoalsAway = 0
      19:             },
      20:             new Match
      21:             {
      22:                 MatchID = 2,
      23:                 Home = "German",
      24:                 Away = "Croatia",
      25:                 GoalsHome = 4,
      26:                 GoalsAway = 1
      27:             },
      28:         new Match
      29:             {
      30:                 MatchID = 3,
      31:                 Home = "Austria",
      32:                 Away = "Germany",
      33:                 GoalsHome = 0,
      34:                 GoalsAway = 3
      35:             } 
      36:         };
      37:     }
      38:  
      39:     public static MatchRepository Instance
      40:     {
      41:         get
      42:         {
      43:             lock( locker )
      44:             {
      45:                 if( repository == null )
      46:                 {
      47:                     repository = new MatchRepository();
      48:                 }
      49:                 return repository;
      50:             }
      51:         }
      52:     }
      53:  
      54:     public List<Match> ListOfMatches
      55:     {
      56:         get
      57:         {
      58:             return this.listOfMatches;
      59:         }
      60:     }
      61: }

    Anmerkung: Die Spielstände sind nur meine EM Tipps für die deutschen Gruppenspiele.

    Das Datenmodell selbst muss nur noch über die DataService Klasse als REST Dienst publiziert werden.

       1: public class Euro2008DataService : DataService<Euro2008DataModel>
       2: {
       3:     public static void InitializeService( IDataServiceConfiguration config )
       4:     {
       5:         config.SetEntitySetAccessRule( "*", EntitySetRights.All );
       6:         config.SetServiceOperationAccessRule( "*", ServiceOperationRights.All );
       7:     }
       8: }

    Damit hat man nun schon das eigene Objektmodell per ADO.NET Data Services lesend der Außenwelt zur Verfügung gestellt. Ruft man nun die entsprechende URI http://localhost/Euro2008DataService.svc/Matches erhält man den folgenden ATOM Feed.

       1: <?xml version="1.0" encoding="utf-8" standalone="yes"?>
       2: <feed xml:base="http://localhost:1746/Euro2008DataService.svc/" 
       3:       xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" 
       4:       xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" 
       5:       xmlns="http://www.w3.org/2005/Atom">
       6:   <title type="text">Matches</title>
       7:   <id>http://localhost:1746/Euro2008DataService.svc/Matches</id>
       8:   <updated>2008-06-06T09:10:31Z</updated>
       9:   <link rel="self" title="Matches" href="Matches" />
      10:   <entry m:type="MyDataService.Match">
      11:     <id>http://localhost:1746/Euro2008DataService.svc/Matches(1)</id>
      12:     <title type="text"></title>
      13:     <updated>2008-06-06T09:10:31Z</updated>
      14:     <author>
      15:       <name />
      16:     </author>
      17:     <link rel="edit" title="Match" href="Matches(1)" />
      18:     <content type="application/xml">
      19:       <m:properties>
      20:         <d:MatchID m:type="Edm.Int32">1</d:MatchID>
      21:         <d:Home>Germany</d:Home>
      22:         <d:Away>Poland</d:Away>
      23:         <d:GoalsHome m:type="Edm.Int32">2</d:GoalsHome>
      24:         <d:GoalsAway m:type="Edm.Int32">0</d:GoalsAway>
      25:       </m:properties>
      26:     </content>
      27:   </entry>
      28:   <entry m:type="MyDataService.Match">
      29:     <id>http://localhost:1746/Euro2008DataService.svc/Matches(2)</id>
      30:     <title type="text"></title>
      31:     <updated>2008-06-06T09:10:31Z</updated>
      32:     <author>
      33:       <name />
      34:     </author>
      35:     <link rel="edit" title="Match" href="Matches(2)" />
      36:     <content type="application/xml">
      37:       <m:properties>
      38:         <d:MatchID m:type="Edm.Int32">2</d:MatchID>
      39:         <d:Home>German</d:Home>
      40:         <d:Away>Croatia</d:Away>
      41:         <d:GoalsHome m:type="Edm.Int32">4</d:GoalsHome>
      42:         <d:GoalsAway m:type="Edm.Int32">1</d:GoalsAway>
      43:       </m:properties>
      44:     </content>
      45:   </entry>
      46:   <entry m:type="MyDataService.Match">
      47:     <id>http://localhost:1746/Euro2008DataService.svc/Matches(3)</id>
      48:     <title type="text"></title>
      49:     <updated>2008-06-06T09:10:31Z</updated>
      50:     <author>
      51:       <name />
      52:     </author>
      53:     <link rel="edit" title="Match" href="Matches(3)" />
      54:     <content type="application/xml">
      55:       <m:properties>
      56:         <d:MatchID m:type="Edm.Int32">3</d:MatchID>
      57:         <d:Home>Austria</d:Home>
      58:         <d:Away>Germany</d:Away>
      59:         <d:GoalsHome m:type="Edm.Int32">0</d:GoalsHome>
      60:         <d:GoalsAway m:type="Edm.Int32">3</d:GoalsAway>
      61:       </m:properties>
      62:     </content>
      63:   </entry>
      64: </feed>

    IUpdatable implementieren

    Ein simpler WPF Client ist nun in der Lage die Daten zu visualisieren

    shot1

    Damit der WPF Client nun auch die Ergebnisse nicht nur anzeigen, sondern auch anpassen kann, muss die Klasse Euro2008DataModel noch das Interface IUpdatable implementieren. Das Interface selbst hat einige Methoden, doch um nur die Aktualisierung der Ergebnisse für diese kleine Beispiel zu ermöglichen langen die folgenden:

       1: public class Euro2008DataModel : IUpdatable
       2: {
       3:     public IQueryable<Match> Matches
       4:     {
       5:         get
       6:         {
       7:             return MatchRepository.Instance.ListOfMatches.AsQueryable<Match>();
       8:         }
       9:     }
      10:  
      11:     #region IUpdatable Members
      12:  
      13:     // Operations not implemented omitted for clarity
      14:  
      15:     public object GetResource( IQueryable query, string fullTypeName )
      16:     {
      17:         var result = Matches.Provider.CreateQuery( query.Expression );
      18:         foreach( var item in result )
      19:         {
      20:             return item;
      21:         }
      22:         return null;
      23:     }
      24:  
      25:     public object ResolveResource( object resource )
      26:     {
      27:         Match target = ( Match ) resource;
      28:         return Matches.Where( m => m.MatchID == target.MatchID ).First();
      29:     }
      30:  
      31:     public void SaveChanges()
      32:     {
      33:         // nothing to do here, as we can't rollback
      34:     }
      35:  
      36:     public void SetValue( object targetResource, string propertyName, object propertyValue )
      37:     {
      38:         Match target = ( Match ) targetResource;
      39:  
      40:         var foundMatch = Matches.Where( m => m.MatchID == target.MatchID ).First();
      41:  
      42:         PropertyInfo info = foundMatch.GetType().GetProperty( propertyName );
      43:         info.SetValue( foundMatch, propertyValue, null );
      44:     }
      45:  
      46:     #endregion
      47: }

    Die Methode GetResource() gibt den Parameter query vom Typ IQueryable hinein. Hier würde unter Umständen noch ein Mapping auf einen anderen Queryprovider durchgeführt werden, in diesem Fall muss ich nichts tun. Der übergebene Query Provider ist genau der gleiche den ich für die interne Implementierung benutze um auf die Daten zuzugreifen. Ich kann hier folgende Doku empfehlen die Erläutert wie man einen Provider implementiert und diesen entsprechend anpasst.

    Die Methode SaveChanges() muss nichts machen, da bereits bei SetValue() die Werte direkt in das Repository geschieben werden. Und wir erinnern uns, die Liste der Spiele wird im Speicher gehalten. Dementsprechend werden Properties auch gleich in das Original Objekt gesetzt. Hat man einen Datenbereich der Transaktionorientiert arbeitet oder mit einem Original – New-Value Ansatz, so würde man erst bei SaveChanges() letztlich den Commit machen.

    Ist das neue Datenmodell publiziert, so kann man auch per WPF Client die Ergebnisse ein wenig anpassen, vielleicht ist das dann doch ein wenig realistischer…

    shot2 

    Habe ich bereits erwähnt das Deutschland Europameister 2008 wird?

  • Dariusz quatscht

    Silverlight 2 Beta 2 und ADO.NET Data Services

    Seit Silverlight 2 Beta 2 draußen ist, kann ich endlich wieder an meinem Projekt weiterarbeiten. Ich schreibe eine kleine Anwendung die auf einen Datendienst zugreift, den ich mit den ADO.NET Data Services erstellt habe. Ich mußte feststellen das es drei wichtige Dinge zu beachten gilt:

    System.Data.Services.Client

    Dieses Assembly ist verantwortlich für die Integration des Proxy Codes in das Silverlight Projekt. Es muß referenziert werden damit der erstellte Proxy mittels DataSvcUtil entsprechend funktioniert.

    Asynchrone Aufrufe

    Möchte man nun auf Daten zugreifen, so muss dies immer asynchron geschehen. Synchrone Aufrufe werden in der aktuellen Beta nicht unterstützt.

    Versucht man synchron eine Abfrage gegen den Data Service mittels eines Proxies abzusetzen

       1: var query = from p in ctx.Products
       2:             select p;
       3:  
       4: foreach( var item in query )
       5: {
       6:     // do something
       7: }
     
    bekommt man eine NotImplementedMethodException . Man muss auf jeden Fall asynchron arbeiten. Die eigentliche Abfrage muss explizit in ein DataServiceQuery<T> umgewandelt werden. Folgender Code demonstriert die asynchrone Abfrage:
     
       1: var query = from p in ctx.Products
       2:             select p;
       3:  
       4: var dataQuery = ( DataServiceQuery<Product> ) query;
       5:  
       6: dataQuery.BeginExecute( OnLoadProductsComplete, dataQuery );
     
    Die Methode OnLoadProductsComplete letztlich, ist dafür verantwortlich die Ergebnisse zu verwerten. Der folgende Code zeigt wie man dann die Daten auslesen kann:
     
       1: private void OnLoadProductsComplete( IAsyncResult ar )
       2: {
       3:     var dataQuery = ( DataSeviceQuery<Product> ) ar.AsyncState;
       4:  
       5:     var query = dataQuery.EndExecute( ar );
       6:  
       7:     foreach( var item in query )
       8:     {
       9:         // to whatever has to be done
      10:     }
      11: }
     
    ADO.NET Data Service im gleichen Projekt
     
    Was nirgends dokumentiert ist und vermutlich ein Bug ist (ich konnte es noch nicht genauer verifizieren), ist die Tatsache, dass in der jetzigen Beta der Data Service relativ angesprochen werden muss. Sprich, dieser sollte im gleichen Projekt wie das Silverlight Web Projekt liegen. Alles andere hat bei mir auf der Maschine nur einen Fehler beim Aufruf vom Invoke des Proxies ergeben (callOpen error). Um den Proxy mit der relativen URI zu instanzieren nutzt man einen entsprechenden Konstruktor:
     
       1: var ctx = new ModelEntitiesProxy( new Uri( "test.svc", UriKind.Relative ) );
     
    Vielleicht gibt es ein Workaround für die absolute Adressierung, ausserhalb des Silverlight Web Projektes. Wenn jemand hier einen Link hat, ich wäre dankbar.
     
    So, nun konnte ich das Projekt an den Service anbinden und mit den Daten arbeiten. Subjektiv gesehen ist die Performance nicht optimal zwischen dem Silverlight Projekt und dem Data Service. Es kommt mir träge vor, ist allerdings nur ein Subjektiver Eindruck, nicht durch Zahlen belegt. Abschliessend bleibt noch zu sagen, das die Beta durchaus für eine Evaluation eingesetzt werden kann, wobei man die Performance mal ausser Acht lassen sollte. Hier wird sich mit Sicherheit im Hinblick auf das Release noch was tun.
  • Dariusz quatscht

    Einen Besuch Wert - Das .NET-Forum.de

    Letzte Woche bin ich auf eine Webseite hingewiesen worden. Das .NET-Forum.de. Neben einem Entwickler-Blog Aggregator gibt es auch ein Forum in welchem man sich zu Inhalten austauschen kann. Einfach mal vorbeischauen.

  • Dariusz quatscht

    Twitter WCF 3.5 API Library

    • 1 Comments

    I just published the API declaration library, even it is just experimental and has not been tested. I think it is still a time saver to get at least the declarations. If anyone has an improved version, I would be interested to be updated. You can find the library here and some more info here.

    The library just wraps the Twitter API described here.

  • Dariusz quatscht

    Virtualisierte Arbeitsumgebung

    • 3 Comments

    Nach langem überlegen und der Vielzahl an Updates die es in den diversen Beta Phasen verschiedener Entwicklungstools gibt, habe ich mich dazu entschlossen meine komplette Entwicklungsumgebung zu virtualisieren.

    Ich erhoffe mir jetzt ein einfacheres Handling von verschiedenen Produktupdates und vor allem die Möglichkeit mit mehreren Maschinen, ein und dieselben Entwicklungstools zu nutzen. Wie oft habe ich beim Wecheln einer Maschine festgestellt das mir hier und da ein Tool fehlt. Das Nachinstallieren ist einfach immer Zeitaufwendig und Nervend.

    Wie bin ich vorgegangen? Ich habe mich am Blogeintrag von Andrew Cornell orientiert: HOWTO: Use Virtual PC's Differencing Disks to your Advantage.

    Ich hatte allerdings am Anfang lange überlegt ob ich Virtual Server 2005 R2 SP1 nehme oder Virtual PC 2007 SP1. Ich habe mich dann für letzteres entschlossen. Virtual PC 2007 SP1 ist im Notfall auch mal schnell auf einer anderen Maschine installiert, während ich beim Server noch den IIS installieren muss. Auch werde ich nicht mehr als eine VM aktiv laufen haben. Insofern langt mir das VPC Produkt.

    Ein weiteres Problem das ich hatte war die Instabilität meiner externen USB Platten. Ich hatte bei größeren ISO Images öfters mal Lese Fehler während der Installation was das ganze recht mühselig gestaltet hat. Nach längerem hin und her habe ich eine Platte per FireWire angeschlossen und seither auch keine Probleme. Ich bin mir allerdings nicht sicher ob es nur Zufall ist das es jetzt tut, auf jeden Fall habe ich bisher nicht mehr das Problem gehabt.

    Abschliessend bleibt noch abzuwarten ob sich die Umstellung bewährt. Bisher sieht es Performance Technisch gut aus, selbst wenn man auf einigen Hosts weniger Speicher zur Verfügung hat (ok, ich habe überall mind. 2GB drinnen), scheint es sich nicht Grundlegend auf die Performance Auszuwirken. Ob ich allerdings mit dem Handling auf Dauer leben kann, immer eine externe Platte mit FireWire rumzuschleppen, das wird sich noch zeigen.

  • Dariusz quatscht

    Sysinternals Tools jederzeit direkt im Zugriff

    • 2 Comments

    Vorausgesetzt man hat eine Internet Verbindung, so kann man sich jetzt über http://live.sysinternals.com die einzelnen Tools, ohne großes Rumnavigieren, direkt runterladen. Auszug aus der Readme:

    What is this?

    This is a file share allowing access to all Sysinternals utilities. We have developed this to test an alternate distribution mechanism for our utilities.

    This will allow you to run these tools from any computer connected to the Internet without having to navigate to a webpage, download and extract the zip file.

    If you are unfamiliar with Microsoft Windows Sysinternals, it is highly recommended that you visit the website at http://technet.microsoft.com/sysinternals before using these tools.

    If you have any questions or comments on this file share, please email syssite@microsoft.com

    Regards,

    The Microsoft Windows Sysinternals Team

    Praktisch!

  • Dariusz quatscht

    Beta Release: Improving Web Services Security Guide

    Auf der 360° Security Roadshow habe ich bereits auf diesen Guide hingewiesen. Mittlerweile sind die einzelnen HTML Fragmente zu einem PDF zusammengefasst und noch ein wenig überarbeitet worden. Das ganze ist jetzt als Beta hier verfügbar:

    www.codeplex.com/wcfsecurity

Page 1 of 1 (8 items)