<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>A Technical Perspective</title>
	<atom:link href="http://maximelabelle.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://maximelabelle.wordpress.com</link>
	<description>Un site utilisant WordPress.com</description>
	<lastBuildDate>Wed, 10 Apr 2013 13:08:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='maximelabelle.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>A Technical Perspective</title>
		<link>http://maximelabelle.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://maximelabelle.wordpress.com/osd.xml" title="A Technical Perspective" />
	<atom:link rel='hub' href='http://maximelabelle.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Hosting BizTalk WCF Send Adapters in your Custom Application</title>
		<link>http://maximelabelle.wordpress.com/2013/04/10/hosting-biztalk-wcf-send-adapters-in-your-custom-application/</link>
		<comments>http://maximelabelle.wordpress.com/2013/04/10/hosting-biztalk-wcf-send-adapters-in-your-custom-application/#comments</comments>
		<pubDate>Wed, 10 Apr 2013 13:08:58 +0000</pubDate>
		<dc:creator>Maxime Labelle</dc:creator>
				<category><![CDATA[BizTalk]]></category>
		<category><![CDATA[Wcf]]></category>

		<guid isPermaLink="false">http://maximelabelle.wordpress.com/?p=652</guid>
		<description><![CDATA[The BizTalk Adapters for WCF is a collection of several adapters that are designed to make it easy to create BizTalk applications that communicate with WCF-based services or line-of-business applications. It ships with five physical adapters, corresponding to predefined WCF &#8230; <a href="http://maximelabelle.wordpress.com/2013/04/10/hosting-biztalk-wcf-send-adapters-in-your-custom-application/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&#038;blog=16599311&#038;post=652&#038;subd=maximelabelle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>The <a href="http://msdn.microsoft.com/en-us/library/bb259952.aspx">BizTalk Adapters for WCF</a> is a collection of several adapters that are designed to make it easy to create BizTalk applications that communicate with WCF-based services or line-of-business applications.</p>
<p>It ships with five physical adapters, corresponding to predefined WCF bindings (such as, BasicHttp, WsHttp, NetTcp, NetNamedPipe and NetMsmq). For more flexibility, it also ships with a custom adapter that can be configured with more control over WCF binding and behavior informations.</p>
<p>Also included with a BizTalk Server license, the <a Href="http://www.microsoft.com/en-us/biztalk/product-information/line-of-business-adapter-pack.aspx">Line of Business Adapter Pack</a> includes several adapters for communication with line-of-business applications or databases from common vendors.</p>
<p>Additionnaly, thanks to the <a href="http://msdn.microsoft.com/en-us/biztalk/bb905478.aspx">WCF LOB Adapter SDK</a>, one can build his custom connectors for enabling access to in-house or proprietary data sources in a streamlined way. Many commercial vendors offer additional adapters built this way to enable BizTalk Applications to communicate with and expanded choice of line-of-business systems.</p>
<p>As a matter of fact, adapters built with the WCF LOB Adapter SDK are exposed as plain WCF transport-level bindings and thus can be reused in your custom .net applications, or any application that can consume a WCF binding.</p>
<p>In this post, I will show you how simple it is to re-use adapters that ship with BizTalk, or custom adapters built with the WCF LOB Adapter SDK, and host them in your custom applications.</p>
<p><strong>Hosting Send Side WCF Adapters in your Custom Application</strong></p>
<p>Using a WCF binding from a C# application is quite straightforward. After all, <a href="http://msdn.microsoft.com/en-us/library/aa480190.aspx#introt_topic2">using WCF is as simple as ABC</a>, right ?</p>
<p>1. A stands from Address.</p>
<p>The address represents the location of the WCF endpoint. It is commonly represented as a Uniform Resource Locator (URL).</p>
<pre class="brush: csharp; title: ; notranslate">
var address = new EndpointAddress(&quot;mssql://localhost//SampleDb?&quot;);
</pre>
<p>2. B stands from Binding.</p>
<p>The binding is a collection of binding elements that gives the WCF runtime informations about the communication &#8220;stack&#8221; through which any given message passes through. A typical WCF communication stack can contain many channels, each of which is responsible for transforming and adapting the message so that it can be eventually transmitted to the target system. For this reason, the last channel in the stack is a transport-level channel.</p>
<p>Adapters build with the WCF LOB Adapter SDK are themselves transport-level WCF binding elements and therefore can be used directly in a communication stack. Those adapters, like any other bindings, are registered in the machine.config. For instance, here is the relevant snippet, corresponding to the WCF-SQL adapter:</p>
<pre class="brush: xml; title: ; notranslate">
      &lt;bindingElementExtensions&gt;
        &lt;!- ... --&gt;
        &lt;add name=&quot;sqlAdapter&quot; type=&quot;Microsoft.Adapters.Sql.SqlAdapterBindingElementExtensionElement, Microsoft.Adapters.Sql, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&quot; /&gt;
      &lt;/bindingElementExtensions&gt;
</pre>
<p>So, instantiating any given binding can be done very easily:</p>
<pre class="brush: csharp; title: ; notranslate">
// create binding element

var adapter = new Microsoft.Adapters.Sql.SqlAdapterBindingElementExtensionElement();
adapter.AllowIdentityInsert = false;
adapter.EnableBizTalkCompatibilityMode = false;

var bindingElement = (BindingElement) Activator.CreateInstance(adapter.BindingElementType);
...

// create custom binding

var binding = new CustomBinding();
binding.Elements.Add(bindingElement); // add transport-level binding element last

// configure binding

binding.OpenTimeout = TimeSpan.FromSeconds(30);
...
</pre>
<p>Adapters built using the WCF LOB Adapter SDK all have a binding class, such as <span style="font-family:'Courier New';">SqlAdapterBinding</span> for instance. This class be instantiated and configured directly, instead of using a <span style="font-family:'Courier New';">CustomBinding</span> class like I have shown in my example above. However, I&#8217;m not sure how to get to this class directly from the information stored in machine.config.</p>
<p>3. C stands for Contract.</p>
<p>The contract represents the set of methods, with their arguments and return types, that the line-of-business system exposes. In most C# application, the service contract is exposed as a C# interface. Since we are dealing with adapters, however, there is no specific interface that can be used.</p>
<p>Instead, we need to rely on the <a href="http://msdn.microsoft.com/en-us/library/ms729840.aspx">channel shape</a>, that corresponds to the most common communication exchange pattern used to access various systems, applications or databases.</p>
<p>Most adapters that ship with BizTalk support two-way communication. Therefore, the most sensible contract would be <span style="font-family:'Courier New';">IRequestChannel</span>. This contract allows an application to send and abitrary request, represented by a WCF <span style="font-family:'Courier New';">Message</span> object, and receive a response in return.</p>
<p>A Message is constructed with an Action, that makes sense to the adapter and a payload, supplied in the form of a class derived from <span style="font-family:'Courier New';">BodyWriter</span>.</p>
<pre class="brush: csharp; title: ; notranslate">
private static Message InvokeAdapterRequest(Binding sqlBinding, EndpointAddress sqlAddress, String action, BodyWriter bodyWriter)
{
    using (var message = Message.CreateMessage(MessageVersion.Default, action, bodyWriter))
        return InvokeAdapterRequest(sqlBinding, sqlAddress, message);
}

private static Message InvokeAdapterRequest(Binding sqlBinding, EndpointAddress sqlAddress, Message message)
{
    var channel = ChannelFactory&lt;IRequestChannel&gt;.CreateChannel(sqlBinding, sqlAddress);
    try
    {
        if (channel.State != CommunicationState.Opened)
            channel.Open();
        return channel.Request(message);
    }
    catch
    {
        channel.Abort();
    }
    finally
    {
        channel.Close();
    }
}
</pre>
<p>Here is, for instance, a simple way to call a stored procedure on SQL Server using the WCF-SQL Adapter:</p>
<pre class="brush: csharp; title: ; notranslate">
public class XmlBodyWriter : BodyWriter
{
    private readonly string body_;

    public XmlBodyWriter(string body)
        : base(true)
    {
        body_ = body;
    }

    protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
    {
        writer.WriteRaw(body_);
        writer.Flush();
    }
}


private static void Main(string[] args)
{
    var address = new EndpointAddress(&quot;mssql://localhost//SampleDb?&quot;);

    // create binding element

    var adapter = new Microsoft.Adapters.Sql.SqlAdapterBindingElementExtensionElement();
    adapter.AllowIdentityInsert = false;
    adapter.EnableBizTalkCompatibilityMode = false;

    var bindingElement = (BindingElement) Activator.CreateInstance(adapter.BindingElementType);

    // create custom binding

    var binding = new CustomBinding();
    binding.Elements.Add(bindingElement); // add transport-level binding element last

    // configure binding

    binding.OpenTimeout = TimeSpan.FromSeconds(30);

    const string action = &quot;TypedProcedure/dbo/usp_SelectRecords&quot;;
    var bodyWriter = new XmlBodyWriter(&quot;&lt;ns0:usp_SelectRecords xmlns:ns0='http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo' /&gt;&quot;);

    using (var response = InvokeAdapterRequest(binding, address, action, bodyWriter))
    {
        // use response message
        Console.WriteLine(response.ReadOuterXml());
    }
}
</pre>
<p><strong>Conclusion</strong></p>
<p>This post shows a simple way to re-use any WCF LOB Adapter SDK-based adapters, in your own custom applications.</p>
<p>You probably will not have a use for this very often. Be we, at <a href="http://www.moskitos.fr/index.html?lang=en">Moskitos</a>, are building a new generation EAI/ESB Platform available as a Cloud-based application and our custom adapters are based on the WCF LOB Adapter SDK. Additionnaly, if our clients want to use BizTalk on-premise as well, we can take advantage of the BizTalk Adapter pack to allow our solution to communicate with other line-of-business systems.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maximelabelle.wordpress.com/652/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maximelabelle.wordpress.com/652/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&#038;blog=16599311&#038;post=652&#038;subd=maximelabelle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maximelabelle.wordpress.com/2013/04/10/hosting-biztalk-wcf-send-adapters-in-your-custom-application/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/957e1e828557735f52843d3c69f29b1e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maximelabelle</media:title>
		</media:content>
	</item>
		<item>
		<title>Déployer une Machine Virtuelle SQL Server 2012 sur Windows Azure</title>
		<link>http://maximelabelle.wordpress.com/2013/01/21/deployer-une-machine-virtuelle-sql-server-2012-sur-windows-azure/</link>
		<comments>http://maximelabelle.wordpress.com/2013/01/21/deployer-une-machine-virtuelle-sql-server-2012-sur-windows-azure/#comments</comments>
		<pubDate>Mon, 21 Jan 2013 09:53:02 +0000</pubDate>
		<dc:creator>Maxime Labelle</dc:creator>
				<category><![CDATA[Windows Azure]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[IaaS]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">http://maximelabelle.wordpress.com/?p=603</guid>
		<description><![CDATA[This article has been written in an effort by the Windows Azure France team to coordinate the writing of tutorials and how-to guides for various Windows Azure features and technologies. This guide is a direct translation in french of the &#8230; <a href="http://maximelabelle.wordpress.com/2013/01/21/deployer-une-machine-virtuelle-sql-server-2012-sur-windows-azure/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&#038;blog=16599311&#038;post=603&#038;subd=maximelabelle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><em>This article has been written in an effort by the Windows Azure France team to coordinate the writing of tutorials and how-to guides for various Windows Azure features and technologies. This guide is a direct translation in french of the &#8216;<a href="http://www.windowsazure.com/en-us/manage/windows/common-tasks/install-sql-server/">Provisioning a SQL Server Virtual Machine on Windows Azure</a>&#8216; guide, available on MSDN</em></p>
<p>La galerie de machines virtuelles Windows Azure contient des<br />
images virtuelles prêtes à l’emploi, parmi lesquelles on trouve une<br />
installation complète de SQL Server 64 bits sur Windows Server 2008 R2, Service<br />
Pack 1 (64 bits). Après avoir choisi l’une des images disponibles, il vous est<br />
possible, en quelques clics, de mettre en œuvre un environnement complet sur<br />
Windows Azure.</p>
<p>Si vous voulez utiliser votre propre image virtuelle en lieu<br />
et place de celles mises à disposition sur la galerie, veuillez consulter l’un<br />
des articles officiels, référencés à la fin de ce guide. </p>
<p>Ce guide a pour objectif de vous accompagner dans la mise en<br />
œuvre d’un environnement SQL Server complet sur Windows Azure. </p>
<h2>Mettre en œuvre un environnement à partir d’une image virtuelle de la galerie Windows Azure</h2>
<p>La mise en œuvre d’un environnement virtuel sur Windows<br />
Azure nécessite une souscription. Si vous n’avez pas de compte Windows Azure,<br />
vous pouvez souscrire à la version d’évaluation de Windows Azure, qui vous<br />
offre la possibilité d’essayer le service pendant 90 jours à un tarif<br />
préférentiel.</p>
<p>1. Se connecter au Portail Windows Azure, situé à l’emplacement suivant:<br />
<a href="//manage.windowsazure.com">http://manage.windowsazure.com</a></p>
<p><img border="0" width="605" height="397" src="http://maximelabelle.files.wordpress.com/2013/01/windows_azure_portal_iaas.png?w=605&#038;h=397"></p>
<p>2. Dans le bandeau situé à gauche de l’écran, sélectionner l’option «&nbsp;<b>ORDINATEURS<br />
VIRTUELS</b>&nbsp;». Cliquer sur <b>+ CRÉER UNE IMAGE</b>, puis sur <b>ORDINATEUR<br />
VIRTUELS</b> et enfin sur <b>À PARTIR DE LA GALERIE</b>.</p>
<p style="text-align:center;"><img border="0" width="604" height="338" src="http://maximelabelle.files.wordpress.com/2013/01/windows_azure_portal_add_virtual_machine.png?w=604&#038;h=338"></p>
<p>3. Dans l’assistant de création d’un ordinateur virtuel, sélectionne<br />
l’image virtuelle correspondant à la version d’évaluation de SQL Server 2012<br />
(64 bits).</p>
<p style="text-align:center;"><img border="0" width="605" height="435" src="http://maximelabelle.files.wordpress.com/2013/01/windows_azure_portal_create_virtual_machine_step_1_os_selection.png?w=605&#038;h=435"></p>
<p><b>Avertissement</b>&nbsp;: la version d’évaluation de SQL<br />
Server 2012 est mise à disposition gratuitement à des fins de tests. Cette<br />
version ne peut pas être mise à jour vers une version complète ultérieurement.</p>
<p>4. Sur l’écran «&nbsp;Configuration de l’ordinateur virtuel&nbsp;», préciser les<br />
éléments suivants&nbsp;:</p>
<p>· Préciser le <b>NOM DE L’ORDINATEUR VIRTUEL</b>, par exemple<br />
«&nbsp;TestSQLServer2k12&nbsp;».</p>
<p>· Préciser le <b>NOUVEAU MOT DE PASSE</b>, en choisissant un mot de<br />
passe répondant aux critères de sécurité de SQL Server 2012. Les critères sont<br />
précisés à l’emplacement suivant : <a href="//msdn.microsoft.com/en-us/library/ms161962.aspx&ldquo;,&rdquo;">http://msdn.microsoft.com/en-us/library/ms161962.aspx</a></p>
<p>· <b>CONFIRMER LE MOT DE PASSE</b>, en le saisissant de nouveau.</p>
<p>· Choisir ensuite une <b>TAILLE</b> appropriée pour la machine<br />
virtuelle.</p>
<p><img border="0" width="604" height="434" src="http://maximelabelle.files.wordpress.com/2013/01/windows_azure_portal_create_virtual_machine_step_2_vm_config.png?w=604&#038;h=434"></p>
<p><b>Note</b>&nbsp;: Voici quelques considérations pour<br />
choisir la taille de la machine virtuelle.</p>
<p>· La taille Moyenne est la taille minimum recommandée pour un usage<br />
en production.</p>
<p>· Sélectionner l’une des tailles Grande ou Très Grande si vous<br />
utilisez l’Édition Entreprise de SQL Server.</p>
<p>· La taille sélectionnée limite le nombre de disques que vous<br />
pouvez configurés (à partir de Moyenne &lt;=4, Grande &lt;=8 ou Très Grande<br />
&lt;= 16).</p>
<p>5.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Cliquer<br />
sur la flèche située en bas à droite pour continuer.</p>
<p>6. Sur l’écran «&nbsp;Mode de l’ordinateur virtuel&nbsp;», préciser les éléments<br />
suivants&nbsp;:</p>
<p>· Sélectionner un <b>ORDINATEUR VIRTUEL AUTONOME</b>.</p>
<p>· Choisir une portion de <b>NOM DNS</b>, de façon à composer un nom<br />
complet de la forme «&nbsp;<i>nomdns</i>.cloudapp.net&nbsp;».</p>
<p>· Choisir la <b>RÉGION/GROUPE D’AFFINITÉS/RÉSEAU VIRTUEL</b> où<br />
sera hébergée la machine virtuelle.</p>
<p>7. Cliquer sur la flèche située en bas à droite pour continuer.</p>
<p style="text-align:center;"><img border="0" width="604" height="435" src="http://maximelabelle.files.wordpress.com/2013/01/windows_azure_portal_create_virtual_machine_step_3_vm_mode.png?w=604&#038;h=435"></p>
<p>8. Sur l’écran «&nbsp;Options de l’ordinateur virtuel&nbsp;», laisser les<br />
options par défaut. Lire et accepter les conditions d’utilisation.</p>
<p style="text-align:center;"><img border="0" width="605" height="435" src="http://maximelabelle.files.wordpress.com/2013/01/windows_azure_portal_create_virtual_machine_step_4_high_availability.png?w=605&#038;h=435"></p>
<p>9. Cliquer sur l’icône de validation située en bas à droite pour terminer.</p>
<p>Une fois ces informations saisies, attendre que la machine<br />
virtuelle soit déployée sur l’environnement Windows Azure.</p>
<p style="text-align:center;"><img border="0" width="605" height="195" src="http://maximelabelle.files.wordpress.com/2013/01/windows_azure_portal_vm_deployment_progress.png?w=605&#038;h=195"></p>
<p>Les étapes par lesquelles le statut de la machine virtuelle<br />
est reporté sont les suivantes :</p>
<ul>
<li>Démarrage en cours (Déploiement)</li>
<li>En cours d’exécution (Déploiement)</li>
<li>En cours d’exécution</li>
</ul>
<p>La machine virtuelle est désormais hébergée sur<br />
l’environnement Windows Azure. Il reste à finaliser l’installation avant<br />
qu’elle soit disponible à l’utilisation. Pour cela, il est nécessaire de se<br />
connecter à distance à la machine virtuelle.</p>
<h2>Se connecter à l’environnement distant pour finaliser l’installation</h2>
<p>1. Une fois le déploiement d’une machine virtuelle effectué, cliquer sur le<br />
nom de votre machine virtuelle pour afficher le TABLEAU DE BORD. Cliquer sur <b>CONNECTER</b>,<br />
en bas de la page.</p>
<p style="text-align:center;"><img border="0" width="604" height="417" src="http://maximelabelle.files.wordpress.com/2013/01/connect_to_remote_sql_server_2k12_database2.png?w=604&#038;h=417"></p>
<p>2. Accepter le téléchargement et ouvrir le fichier .rdp à l’aidre du<br />
programme de Connexion de Bureau à Distance (%windir%\system32\mstsc.exe).</p>
<p style="text-align:center;"><img border="0" width="604" height="89" src="http://maximelabelle.files.wordpress.com/2013/01/download_virutal_machine_rdp.png?w=604&#038;h=89"></p>
<p>3. Dans la boîte de dialogue de Sécurité, taper le mot de passe du compte <b>Administrator</b>, préciser lors de la configuration de la machine virtuelle. Si une fenêtre d’avertissement s’affiche, cliquer sur OK<br />
pour ignorer ou accepter le certificat.</p>
<p>Lors de la première connexion à la machine virtuelle,<br />
plusieurs étapes se succèdent pour finaliser l’installation de l’environnement.<br />
Ceci inclut l’installation du bureau, Windows Updates et la finalisation des<br />
tâches de configuration de la machine virtuelle (SysPrep).</p>
<p>Une fois ces étapes terminées, le programme d’installation<br />
de SQL Server finalise les tâches de configuration. Ces tâches prennent un<br />
certain temps, pendant lequel la commande SQL «&nbsp;SELECT @@SERVERNAME&nbsp;»<br />
risque de ne pas retourner une valeur correcte. Tout rentre dans l’ordre une<br />
fois ces tâches de configuration terminées. </p>
<p>Une fois connectée à l’aide de la Connexion de Bureau à<br />
Distance, la machine virtuelle se comporte en tout point comme n’importe quel<br />
autre ordinateur. Il est possible de se connecter localement à l’instance par<br />
défaut de SQL Server à l’aide du programme «&nbsp;SQL Server Management<br />
Studio&nbsp;», installé préalablement sur la machine virtuelle.</p>
<h2>Compléter la configuration de SQL Server pour<br />
permettre la connexion à la base de données depuis un autre ordinateur</a> </h2>
<p>Par défaut, l’installation de SQL Server configure une base<br />
de données qui n’est pas exposée à distance. Avant de pouvoir se connecter à<br />
l’instance SQL via Internet, il est nécessaire de procéder à la configuration<br />
de l’accès à distance en suivant les étapes suivantes&nbsp;:</p>
<ul>
<li>Créer un point de terminaison TCP pour l’accès à la machine virtuelle.</li>
<li>Ouvrir les ports TCP sur le Pare-feu Windows de la machine virtuelle.</li>
<li>Configurer le service SQL Server pour activer l’écoute sur le protocole TCP.</li>
<li>Configurer SQL Server de façon à accepter le mode d’authentification SQL Server.</li>
<li>Créer les <i>logins</i> pour la connexion à SQL Server.</li>
</ul>
<p>Ces étapes sont décrites ci-après dans la suite de ce guide.</p>
<h3>Créer un point de terminaison TCP pour l’accès à la machine virtuelle</h3>
<p>Par défaut, les machines virtuelles déployées sur Windows<br />
Azure ne sont pas configurées pour accepter des connexions réseau. Pour établir<br />
une connexion, il est donc nécessaire d’établir un canal de communication TCP<br />
en créant un &#8220;point de terminaison&#8221; (<i>endpoint</i>).</p>
<p>Cette étape de la configuration permettra de rediriger le<br />
trafic réseau vers un port TCP accessible à la machine virtuelle.</p>
<p>1. Dans le Portail Windows Azure, cliquer sur <b>ORDINATEURS VIRTUELS</b>, dans le<br />
bandeau situé sur le côté gauche, puis cliquer sur le nom de la machine<br />
virtuelle concernée. Le <b>TABLEAU DE BORD</b> de la machine virtuelle est<br />
alors affiché.</p>
<p>2. Dans la portion supérieure de la fenêtre, cliquer sur l’option <b>POINTS DE<br />
TERMINAISON</b>, puis cliquer sur <b>AJOUTER</b>.</p>
<p>3. Sur la page <b>AJOUTER UN POINT DE TERMINAISON</b>, laisser l’option sélectionnée<br />
par défaut et cliquer sur la flèche, situé en bas à droite, pour continuer.</p>
<p style="text-align:center;"><img border="0" width="604" height="433" src="http://maximelabelle.files.wordpress.com/2013/01/add_tcp_endpoint_step1.png?w=604&#038;h=433"></p>
<p>4. Sur la page qui s’affiche, préciser les éléments suivants&nbsp;:</p>
<p>· Saisir un <b>NOM</b> pour le point de terminaison.</p>
<p>· Choisir le <b>PROTOCOLE</b> de communication <b>TCP</b>.</p>
<p>· Dans la zone <b>PORT PUBLIC</b>, choisir un numéro de port TCP,<br />
par exemple <b>1433</b>. Il s’agit du port qui recevra le trafic réseau depuis<br />
Internet. Le numéro 1433 est typiquement utilisé par SQL Server pour les<br />
communications TCP et il s’agit de la valeur par défaut utilisée par la console<br />
SQL Server Management Studio. Étant donné qu’il peut être la cible d’attaques<br />
malveillantes, de nombreuses organisations choisissent un numéro de port<br />
différent.</p>
<p>· Dans la zone <b>PORT PRIVÉ</b>, saisir 1433. Tout autre numéro de<br />
port peut également convenir.</p>
<p style="text-align:center;"><img border="0" width="605" height="431" src="http://maximelabelle.files.wordpress.com/2013/01/add_tcp_endpoint_step2.png?w=605&#038;h=431"></p>
<p>5. Cliquer sur l’icône de validation, située en bas à droite, pour<br />
continuer.</p>
<p>Le point de terminaison est ainsi créé.</p>
<h3>Ouvrir les ports TCP sur le Pare-feu Windows de la<br />
machine virtuelle</h3>
<p>Lancer la console de configuration avancée du Pare-feu<br />
Windows. Dans le Menu Démarrer, choisir &#8220;Start&#8221;, taper<br />
&#8220;WF.msc&#8221;, puis ENTER.</p>
<p style="text-align:center;"><img border="0" width="430" height="293" src="http://maximelabelle.files.wordpress.com/2013/01/start_windows_firewall.png?w=430&#038;h=293"></p>
<p>1. Dans la console de configuration du Pare-feu,<br />
sélectionner sur &#8220;<b>Inbound Rules</b>&#8220;,<br />
puis cliquer avec le bouton droit de la souris sur &#8220;<b>Inbound<br />
Rules</b>&#8221; et choisir l’option &#8220;<b>New<br />
Rule…</b>&#8220;.</p>
<p style="text-align:center;"><img border="0" width="605" height="386" src="http://maximelabelle.files.wordpress.com/2013/01/fw_sql_server_inbound_rule.png?w=605&#038;h=386"></p>
<p>2. Dans la boîte de dialogue &#8220;<b>New<br />
Inbound Rule Wizard</b>&#8220;, sélectionner &#8220;<b>Port</b>&#8220;<br />
puis cliquer sur &#8220;<b>Next</b>&#8220;.</p>
<p style="text-align:center;"><img border="0" width="456" height="365" src="http://maximelabelle.files.wordpress.com/2013/01/new_inbound_rule_wizard_step_1_rule_type.png?w=456&#038;h=365"></p>
<p>4. À l’étape&nbsp;«&nbsp;<b>Protocol and Ports</b>&nbsp;», sélectionner le<br />
protocole TCP, choisir l’option «&nbsp;<b>Specific local ports</b>&nbsp;»<br />
et saisir le numéro de port «&nbsp;<b>1433</b>&nbsp;» dans la zone de texte<br />
correspondante. Cliquer sur «&nbsp;<b>Next</b>&nbsp;» pour continuer.</p>
<p style="text-align:center;"><img border="0" width="458" height="366" src="http://maximelabelle.files.wordpress.com/2013/01/new_inbound_rule_wizard_step_2_protocol_and_ports.png?w=458&#038;h=366"></p>
<p>5. À l’étape «&nbsp;Action&nbsp;», choisir l’option «&nbsp;<b>Allow the connection</b>&nbsp;», puis cliquer sur «&nbsp;<b>Next</b>&nbsp;».</p>
<p style="text-align:center;"><img border="0" width="427" height="341" src="http://maximelabelle.files.wordpress.com/2013/01/new_inbound_rule_wizard_step_3_action.png?w=427&#038;h=341"></p>
<p><b>Avertissement de</b> <b>sécurité</b>&nbsp;: sélectionner<br />
l’option «&nbsp;<b>Allow the connection if it is secure</b>&nbsp;»<br />
procure une meilleure sécurité pour la connexion. Choisir cette option pour<br />
configurer des paramètres additionnels permettant de renforcer la sécurité de<br />
votre environnement.</p>
<p>6.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
À l’étape «&nbsp;<b>Profile</b>&nbsp;»,<br />
sélectionner l’option «&nbsp;<b>Public</b>&nbsp;», puis<br />
cliquer sur «&nbsp;<b>Next</b>&nbsp;».</p>
<p style="text-align:center;"><img border="0" width="435" height="348" src="http://maximelabelle.files.wordpress.com/2013/01/new_inbound_rule_wizard_step_4_profile.png?w=435&#038;h=348"></p>
<p><b>Avertissement</b>&nbsp;: sélectionner l’option «&nbsp;<b>Public</b>&nbsp;»<br />
autorise tout accès à la machine virtuelle depuis Internet. À chaque fois que<br />
c’est possible, choisir une option de sécurité plus forte.</p>
<p>7. À la dernière étape «&nbsp;<b>Name</b>&nbsp;»,<br />
saisir un nom en clair et, éventuellement, une courte description pour la règle<br />
du Pare-feu, puis cliquer sur «&nbsp;<b>Finish</b>&nbsp;»<br />
pour terminer.</p>
<p style="text-align:center;"><img border="0" width="456" height="365" src="http://maximelabelle.files.wordpress.com/2013/01/new_inbound_rule_wizard_step_5_name.png?w=456&#038;h=365"></p>
<h3>Configurer SQL Server pour activer l’écoute sur le protocole TCP</h3>
<p>De même qu’une machine virtuelle n’est pas configurée par<br />
défaut pour accepter le trafic réseau depuis Internet, le service d’écoute SQL<br />
Server doit être configuré pour permettre l’utilisation du protocole TCP.</p>
<p>Il est possible que cette étape soit déjà effectuée.</p>
<p>1. Une fois connecté à la machine virtuelle via la Connexion de Bureau à<br />
Distance, lancer le programme <b>SQL Server Configuration Manager</b>, depuis<br />
le Menu Démarrer. S’il n’apparaît pas dans le menu, choisir <b>All Programs</b>,<br />
<b>Microsoft SQL Server 2012</b>, puis <b>SQL Server Configuration Manager</b>.</p>
<p style="text-align:center;"><img border="0" width="605" height="289" src="http://maximelabelle.files.wordpress.com/2013/01/protocols_for_mssqlserver.png?w=605&#038;h=289"></p>
<p>2. Dans la console de configuration <b>SQL Server Configuration Manager</b>,<br />
développer le nœud <b>SQL Server Network Configuration</b>, puis cliquer sur <b>Protocols for MSSQLSERVER</b>.</p>
<p>3. Dans la zone de détail, si nécessaire, cliquer avec le bouton droit de la souris sur<br />
le protocole <b>TCP/IP</b>, puis sélectionner <b>Enable</b>.</p>
<p>Un redémarrage du service SQL Server peut être nécessaire,<br />
mais cette opération peut être différée à l’étape suivante.</p>
<h3>Configurer SQL Server pour accepter le mode<br />
d’authentification SQL Server</h3>
<p>Le moteur de base de données SQL Server ne peut pas utiliser<br />
l’authentification Windows en l’absence d’un domaine. Pour permettre la<br />
connexion à SQL Server depuis un autre ordinateur, il est nécessaire de<br />
configurer également le mode d’authentification propre à SQL Server.</p>
<p><b>Précision</b>&nbsp;: la configuration de ce mode<br />
d’authentification n’est pas strictement nécessaire si vous avez déjà configuré<br />
un réseau privé virtuel Windows Azure, c’est-à-dire que vos machines virtuelles<br />
Windows Azure ont été ajoutées à votre domaine d’entreprise.</p>
<p>4. Une fois connecté à la machine virtuelle via la Connexion de Bureau à<br />
Distance, lancer le programme <b>SQL Server Management Studio</b>, depuis le<br />
Menu Démarrer. S’il n’apparaît pas dans le menu, choisir <b>All Programs</b>, <b>Microsoft<br />
SQL Server 2012</b>, puis <b>SQL Server Management Studio</b>.</p>
<p>Le lancement initial de la console de gestion SQL Server<br />
peut prendre un certain temps, durant lequel l’environnement utilisateur est<br />
créé.</p>
<p>5. Dans la boîte de dialogue <b>Connect to Server</b>, vérifier<br />
que le nom de la machine virtuelle est renseigné dans la zone de texte <b>Server name</b>. À défaut du nom du serveur, il est possible<br />
de saisir la valeur <b>(local)</b> ou tout simplement le caractère ‘<b>.</b>’<br />
(point). Vérifier que le mode d’authentification sélectionné est <b>Windows Authentication</b>. Dans ce mode, le nom d’utilisateur est grisé et possède sa valeur par défaut, sous la forme <i>nom_de_la_machine\Administrator</i>.<br />
Cliquer sur <b>Connect</b>.</p>
<p>6. Dans le panneau <b>Object Explorer</b>, situé sur le côté gauche, cliquer avec le<br />
bouton droit de la souris sur le nom de l’instance SQL Server par défaut – qui<br />
correspond au nom de la machine virtuelle – puis sélectionner <b>Properties</b>.</p>
<p style="text-align:center;"><img border="0" width="187" height="373" src="http://maximelabelle.files.wordpress.com/2013/01/sql_server_properties.png?w=187&#038;h=373"></p>
<p>7. Dans la boîte de dialogue «&nbsp;<b>Server Properties</b>&nbsp;»,<br />
sélectionner la page «&nbsp;Security&nbsp;». Puis, dans la rubrique «&nbsp;<b>Server Authentication</b>&nbsp;», choisir l’option «&nbsp;<b>SQL Server and Windows Authentication mode</b>&nbsp;». Puis<br />
cliquer sur <b>OK</b>.</p>
<p style="text-align:center;"><img border="0" width="406" height="365" src="http://maximelabelle.files.wordpress.com/2013/01/sql_server_properties_security.png?w=406&#038;h=365"></p>
<p>Suite à ce changement, un redémarrage du service SQL Server<br />
est nécessaire. Une boîte de dialogue de confirmation s’affiche à cet effet.<br />
Cliquer sur <b>OK</b>.</p>
<p>8. Dans Object Explorer, cliquer avec le bouton droit de la souris sur le<br />
nom de l’instance SQL Server par défaut, puis sélectionner <b>Restart</b>, pour<br />
redémarrer le service. Si l’agent SQL Server est en cours d’exécution, il doit<br />
également être redémarré.</p>
<p>Dans la boîte de dialogue, cliquer sur <b>Yes</b><br />
pour confirmer le redémarrage du service SQL Server.</p>
<h3>Créer les <i>logins</i> de connexion à SQL Server</h3>
<p>La connexion à SQL Server depuis un autre connecteur<br />
nécessite au minimum un <i>login</i> d’authentification.</p>
<p>1. Dans la console de gestion <b>SQL Server Management Studio</b>, développer le nœud<br />
correspondant à l’instance par défaut SQL Server, dans laquelle créer un <i>login</i><br />
d’authentification.</p>
<p>2. Cliquer avec le bouton droit de la souris sur le nœud <b>Security</b>, puis sélectionner <b>New</b>|<b>Login…</b>.</p>
<p style="text-align:center;"><img border="0" width="269" height="326" src="http://maximelabelle.files.wordpress.com/2013/01/sql_server_new_login.png?w=269&#038;h=326"></p>
<p>1. Dans la boîte de dialogue <b>Login – New</b>, sélectionner<br />
la page <b>General</b>, puis saisir le nom de l’utilisateur<br />
dans la zone de texte <b>Login name</b>.</p>
<p>2. Sélectionner le mode d’authentification <b>SQL Server authentication</b>.</p>
<p>3. Dans la zone de texte <b>Password</b>, saisir un mot de<br />
passe pour le nouvel utilisateur. Confirmer le mot de passe dans la zone de<br />
texte <b>Confirm Password</b>.</p>
<p>4. Pour renforcer la sécurité, il est recommandé d’opter pour le respect des règles de<br />
complexité du mot de passe. Sélectionner l’option <b>Enforce<br />
password policy</b>. Cette option est sélectionnée par défaut lorsque le<br />
mode d’authentification SQL Server est choisi.</p>
<p>5. Pour limiter les risques, il est recommandé de changer fréquemment le mot de passe<br />
associé à un utilisateur SQL Server. Pour cela, sélectionner l’option <b>Enforce password expiration</b>. Cette option est<br />
sélectionnée par défaut lorsque le mode d’authentification SQL Server est<br />
choisi.</p>
<p>6. Pour forcer l’utilisateur à changer son mot de passe lors de la première connexion,<br />
sélectionner l’option <b>User must change password at next<br />
login</b>. Il est recommandé d’utiliser cette option si le <i>login</i><br />
est destiné à un autre utilisateur. Cette option est sélectionnée par défaut<br />
lorsque le mode d’authentification SQL Server est choisi.</p>
<p>7. Dans la liste <b>Default database</b>, sélectionner une base<br />
de données par défaut pour le <i>login</i>. La base de données sélectionnée par<br />
défaut est <b>master</b>.</p>
<p>8. Dans la liste <b>Default language</b>, laisser la valeur <b>&lt;default&gt;</b> renseignée par défaut.</p>
<p><img border="0" width="441" height="396" src="http://maximelabelle.files.wordpress.com/2013/01/sql_server_login_general.png?w=441&#038;h=396"></p>
<p>9. S’il s’agit du premier <i>login</i> créé, il peut être opportun de<br />
désigné ce <i>login</i> en tant qu’administrateur SQL Server. Pour cela,<br />
sélectionner la page <b>Server Roles</b>, puis cocher<br />
la case <b>sysadmin</b>.</p>
<p><b>Avertissement de sécurité</b>&nbsp;: les membres du rôle<br />
de serveur <b>sysadmin</b> ont un contrôle complet sur le moteur de base de<br />
données. L’appartenance à ce rôle doit être restreinte et évaluée avec soin.</p>
<p>10. Cliquer sur <b>OK</b> pour terminer.</p>
<p><b>Félicitations</b>&nbsp;: la machine virtuelle est prête à<br />
l’emploi et la connexion à SQL Server est correctement configurée. Vous pouvez<br />
désormais vous connecter à la base de données depuis un autre ordinateur ou une<br />
application.</p>
<h1>Se connecter à SQL Server depuis un autre ordinateur</h1>
<h2>Déterminer le nom DNS de la machine virtuelle</h2>
<p>Pour se connecter à la base de données, il est important de<br />
connaître le nom DNS de la machine virtuelle. Il s’agit du nom enregistré<br />
auprès des serveurs Internet pour identifier la machine virtuelle. Bien qu’il<br />
soit possible d’utiliser l’adresse IP de la machine virtuelle, celle-ci peut<br />
changer à tout moment lorsque Windows Azure réorganise ses ressources à des<br />
fins de redondance ou de maintenance. Il est donc recommandé d’utiliser le nom<br />
DNS de la machine, qui est stable car il peut être redirigé lorsque l’adresse<br />
IP change.</p>
<p>1.Dans le Portail Windows Azure, cliquer sur <b>ORDINATEURS VIRTUELS</b>,<br />
dans le bandeau situé sur le côté gauche, puis cliquer sur le nom de la machine<br />
virtuelle concernée. Le <b>TABLEAU DE BORD</b> de la machine virtuelle est<br />
alors affiché.</p>
<p style="text-align:center;"><img border="0" width="605" height="431" src="http://maximelabelle.files.wordpress.com/2013/01/windows_azure_portal_virtual_machine_dashboard.png?w=605&#038;h=431"></p>
<p>2. Dans la rubrique <b>aperçu rapide</b>, située en bas à droite de la<br />
page, repérer et copier le nom DNS dans le presse-papier. Il s’agit d’un nom de<br />
la forme <i>nom_de_la_machine</i>.cloudapp.net.</p>
<h2>Se connecter à l’aide de SQL Server Management<br />
Studio</h2>
<p>1. Sur un ordinateur connecté à Internet, lancer la console de gestion SQL Server<br />
Management Studio, </p>
<p>2. Dans la boîte de dialogue <b>Connect to Server</b> ou <b>Connect to Database Engine</b>, saisir ou coller, dans la zone de texte <b>Server name</b>, le nom DNS déterminé<br />
précédemment. Ne pas inclure de préfixe <a href="http://" rel="nofollow">http://</a>. Si le numéro du port TCP<br />
public choisi pour le point de terminaison est différent de 1433, il doit être<br />
précisé dans la zone de texte, précédé d’une virgule. Le nom complet est donc<br />
de la forme&nbsp;: <i>nom_de_la_machine</i>.cloudapp.net,<i>numero_de_port_tcp</i>.</p>
<p style="text-align:center;"><img border="0" width="338" height="256" src="http://maximelabelle.files.wordpress.com/2013/01/connect_to_remote_sql_server_2k12_database.png?w=338&#038;h=256"></p>
<p>3. Sélectionner le mode d’authentification <b>SQL Server Authentication</b>.</p>
<p>4. Dans la zone de texte <b>Login</b>, saisir le nom<br />
d’utilisateur créé précédemment.</p>
<p>5. Dans la zone de texte <b>Password</b>, saisir le mot de<br />
passe choisi lors de la création du <i>login</i>.</p>
<p>6. Enfin, cliquer sur <b>Connect</b> pour se connecter à la base<br />
de données.</p>
<p><b>Félicitations</b>&nbsp;: vous êtes maintenant connecté à<br />
votre environnement SQL Server hébergé sur Windows Azure.</p>
<h2>Se connecter depuis une application</h2>
<p>Si la connexion à SQL Server hébergé sur Windows Azure a pu<br />
être établie avec succès depuis la console <b>SQL Server Management Studio</b>,<br />
vous devriez être en mesure de connecter vos applications en utilisant une<br />
chaîne de connexion de la forme&nbsp;:</p>
<p>connectionString=&quot;Server=<i>nom_dns.cloudapp.net,numéro_de_port_tcp</i>;Integrated<br />
Security=false;User Id=<i>login</i>;Password=<i>mot_de_passe</i>;&quot;</p>
<h1>Pour aller plus loin</h1>
<p>Les étapes optionnelles suivantes peuvent vous permettre de<br />
tirer le meilleur parti de votre nouvel environnement virtuel hébergé sur<br />
Windows Azure.</p>
<h2>Migrer une base de données existante</h2>
<p>Votre base de données SQL Server peut être déplacée sur votre<br />
nouvel environnement Windows Azure en utilisant l’une des méthodes<br />
suivantes&nbsp;:</p>
<ul>
<li>Copier le fichier de sauvegarde de la base de données sur la<br />
machine virtuelle, puis effectuer une restauration. Pour plus d’informations,<br />
se reporter à la documentation, située à l’emplacement&nbsp;:<br />
<a href="http://msdn.microsoft.com/en-us/library/ms187048(SQL.90).aspx">Back Up and Restore of SQL Server Databases</a>.</li>
<li>Copier les fichiers de base de données portant les extensions <b>mdf</b>,<br />
<b>ndf</b> et <b>ldf</b> dans un dossier de la machine virtuelle, puis attacher<br />
la base de données. Pour plus d’informations, se reporter à la documentation,<br />
située à l’emplacement&nbsp;:<br />
<a href="http://msdn.microsoft.com/en-us/library/ms190209.aspx">Attach a Database</a>.</li>
<li>Créer un script de création de la base de données source, puis<br />
exécuter ce script à partir de la nouvelle instance SQL Server hébergée sur<br />
Windows Azure. Pour plus d’informations, se reporter à la documentation, située<br />
à l’emplacement&nbsp;:<br />
<a Href="http://msdn.microsoft.com/en-us/library/bb895179.aspx">Generate and Publish Scripts Wizard</a>.</li>
<li>Utiliser l’assistant de copie de bases de données, dans la<br />
console de gestion SQL Server Management Studio. Pour plus d’informations, se<br />
reporter à la documentation, située à l’emplacement&nbsp;:<br />
<a Href="http://msdn.microsoft.com/en-us/library/ms188664.aspx">Copy Database Wizard</a>.</li>
<li>En utilisant une application <i>Data-tier</i> (DAC). Déployer l’application en n’utilisant que le schéma<br />
de la base de données, ou bien importer une base de données en utilisant le<br />
fichier de sauvegarde BACPAC. Pour plus d’information, se reporter à la<br />
documentation, située à l’emplacement&nbsp;:<br />
<a Href="http://msdn.microsoft.com/en-us/library/ee210569.aspx">Deploy a Data-tier Application</a><br />
<a Href="http://social.technet.microsoft.com/wiki/contents/articles/2639.how-to-use-data-tier-application-import-and-export-with-windows-azure-sql-database-en-us.aspx">How to Use Data-Tier Application Import and Export with SQL Azure (en-US)</a></li>
</ul>
<h2>Copier des fichiers sur la machine virtuelle</h2>
<p>De petits fichiers (sauvegardes de base de données, fichiers<br />
BACPAC, etc.) peuvent être copiés directement sur la machine virtuelle en<br />
utilisant le mécanisme copier/coller du presse-papier à travers la Connexion de<br />
Bureau à Distance.</p>
<p>Pour transférer des fichiers plus volumineux, utiliser l’une<br />
des options suivantes&nbsp;:</p>
<ul>
<li>Charger le fichier dans un BLOB, à l’aide d’un compte de stockage<br />
Windows Azure située sur le même centre de données que celui sur lequel est<br />
hébergée la machine virtuelle. Utiliser la Connexion de Bureau à Distance pour<br />
télécharger ce fichier depuis le BLOB.</li>
<li>Transférer le fichier sur un disque de partage réseau et<br />
configurer un réseau privé virtuel Windows Azure. Pour plus d’information,<br />
consulter la page suivante&nbsp;:<br />
<a href="http://www.windowsazure.com/fr-fr/home/features/networking/">Vue d’ensemble de la Mise en Réseau Windows Azure</a>.</li>
<li>Transférer le fichier en utilisant FTP. Plusieurs étapes sont<br />
requises pour activer le transfert FTP sur la machine virtuelle, notamment,<br />
configurer IIS, créer un compte FTP, configurer un certificat SSL, etc. Pour<br />
plus d’informations, se reporter à la documentation Windows:<br />
<a href="http://www.iis.net/downloads/microsoft/ftp">FTP Publishing Service</a>.</li>
<li>Utiliser un navigateur internet et télécharger une base de<br />
données d’exemple, telle que <a href="http://msftdbprodsamples.codeplex.com/">AdventureWorks depuis CodePlex</a>, par exemple.</li>
</ul>
<h2>Désactiver le cache d’écriture disque</h2>
<p>Pour des raisons de performances, le moteur de base de<br />
données nécessite que le cache d’écriture soit désactivé pour les disques – à<br />
la fois pour les données et le système d’exploitation.</p>
<p>Par défaut, le cache est désactivé pour un disque de<br />
données, à la fois pour les opérations de lecture et d’écriture. En revanche,<br />
le cache est activé par défaut pour un disque système.</p>
<p>Les nouveaux utilisateurs qui souhaitent évaluer les<br />
performances d’un système SQL Server composé d’un seul disque – comme la<br />
machine virtuelle hébergée sur Windows Azure – doivent au préalable désactiver<br />
le cache du disque système pour les opérations d’écriture.</p>
<p>Utiliser PowerShell et les <i>CmdLet</i> <b>Set-AzureOSDisk</b> et <b>Set-AzureDataDisk</b>.</p>
<h2>Créer des utilisateurs de base de données supplémentaires</h2>
<p>Pour permettre l’accès à une base de données, les<br />
utilisateurs dont le <i>login</i> n’est pas membre du rôle de serveur <b>sysadmin</b><br />
doivent être associés à une base de données et à un schéma. Pour ce faire,<br />
créer un utilisateur supplémentaire dans la base de données.</p>
<p>Pour plus d’informations, se reporter à la documentation,<br />
située à l’emplacement&nbsp;:</p>
<p>Créer un compte de connexion<br />
<a href="//msdn.microsoft.com/fr-fr/library/aa337562.aspx&ldquo;,&rdquo;">http://msdn.microsoft.com/fr-fr/library/aa337562.aspx</a></p>
<h2>Ajouter des instances de base de données supplémentaires</h2>
<p>Le disque d’installation de SQL Server est disponible sur la<br />
machine virtuelle dans un dossier situé à l’emplacement <span style="font-family:'Courier New';">C:\SqlServer11.0Full.</span></p>
<p>Exécuter le programme d’installation pour ajouter ou<br />
supprimer des fonctionnalités, ajouter ou réparer des instances, etc.</p>
<h1>Ressources</h1>
<p>Ce guide a été écrit dans le cadre d’un travail mené par<br />
l’équipe Windows Azure France pour mettre en œuvre la création ou le relais de<br />
tutoriaux pour la communauté francophone. Il est directement inspiré de <a href="http://www.windowsazure.com/en-us/manage/windows/common-tasks/install-sql-server/">la<br />
documentation officielle</a>.</p>
<p>Par ailleurs, les ressources suivantes ont également été<br />
utilisées pour la rédaction de ce guide&nbsp;:</p>
<p>[1] <a>Windows<br />
Azure Virtual Machines</a></p>
<p>[2]<br />
<a Href="http://www.windowsazure.com/fr-fr/pricing/details/#header-3">Tarifs pour le service Machines Virtuelles Windows sur Windows Azure</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maximelabelle.wordpress.com/603/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maximelabelle.wordpress.com/603/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&#038;blog=16599311&#038;post=603&#038;subd=maximelabelle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maximelabelle.wordpress.com/2013/01/21/deployer-une-machine-virtuelle-sql-server-2012-sur-windows-azure/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/957e1e828557735f52843d3c69f29b1e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maximelabelle</media:title>
		</media:content>

		<media:content url="http://maximelabelle.files.wordpress.com/2013/01/windows_azure_portal_iaas.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2013/01/windows_azure_portal_add_virtual_machine.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2013/01/windows_azure_portal_create_virtual_machine_step_1_os_selection.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2013/01/windows_azure_portal_create_virtual_machine_step_2_vm_config.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2013/01/windows_azure_portal_create_virtual_machine_step_3_vm_mode.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2013/01/windows_azure_portal_create_virtual_machine_step_4_high_availability.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2013/01/windows_azure_portal_vm_deployment_progress.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2013/01/connect_to_remote_sql_server_2k12_database2.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2013/01/download_virutal_machine_rdp.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2013/01/add_tcp_endpoint_step1.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2013/01/add_tcp_endpoint_step2.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2013/01/start_windows_firewall.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2013/01/fw_sql_server_inbound_rule.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2013/01/new_inbound_rule_wizard_step_1_rule_type.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2013/01/new_inbound_rule_wizard_step_2_protocol_and_ports.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2013/01/new_inbound_rule_wizard_step_3_action.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2013/01/new_inbound_rule_wizard_step_4_profile.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2013/01/new_inbound_rule_wizard_step_5_name.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2013/01/protocols_for_mssqlserver.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2013/01/sql_server_properties.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2013/01/sql_server_properties_security.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2013/01/sql_server_new_login.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2013/01/sql_server_login_general.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2013/01/windows_azure_portal_virtual_machine_dashboard.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2013/01/connect_to_remote_sql_server_2k12_database.png" medium="image" />
	</item>
		<item>
		<title>Microsoft® MVP Integration 2013</title>
		<link>http://maximelabelle.wordpress.com/2013/01/02/microsoft-mvp-integration-2013/</link>
		<comments>http://maximelabelle.wordpress.com/2013/01/02/microsoft-mvp-integration-2013/#comments</comments>
		<pubDate>Wed, 02 Jan 2013 08:10:39 +0000</pubDate>
		<dc:creator>Maxime Labelle</dc:creator>
				<category><![CDATA[Non classé]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Integration]]></category>
		<category><![CDATA[MVP]]></category>

		<guid isPermaLink="false">http://maximelabelle.wordpress.com/?p=597</guid>
		<description><![CDATA[It is with great honor and pleasure that I have been awarded Microsoft Most Valuable Professional for the third consecutive year. This year marks the change in name from my previous expertise around &#8220;BizTalk&#8221;, to a more broad and general &#8230; <a href="http://maximelabelle.wordpress.com/2013/01/02/microsoft-mvp-integration-2013/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&#038;blog=16599311&#038;post=597&#038;subd=maximelabelle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>
It is with great honor and pleasure that I have been awarded Microsoft Most Valuable Professional for the third consecutive year.</p>
<p style="text-align:center;"><img src="http://maximelabelle.files.wordpress.com/2011/01/mvp_logo.png?w=640&#038;h=200" height="200" /></p>
<p>This year marks the change in name from my previous expertise around &#8220;BizTalk&#8221;, to a more broad and general expertise in &#8220;Integration&#8221;.
<p>
In second part of last year, I have accompanied the creation of a <a Href="http://www.moskitos.fr/index.html?lang=en">new startup</a>, where I have been working full time on designing, architecting and building the next generation EAI/ESB platform on the Cloud.</p>
<p>
This year, I will strive to build a strong expertise around Windows Azure and the Cloud Computing, in order to complete my knowledge around integration.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maximelabelle.wordpress.com/597/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maximelabelle.wordpress.com/597/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&#038;blog=16599311&#038;post=597&#038;subd=maximelabelle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maximelabelle.wordpress.com/2013/01/02/microsoft-mvp-integration-2013/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/957e1e828557735f52843d3c69f29b1e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maximelabelle</media:title>
		</media:content>

		<media:content url="http://maximelabelle.files.wordpress.com/2011/01/mvp_logo.png" medium="image" />
	</item>
		<item>
		<title>Prise en Main du Cache sous Windows Azure</title>
		<link>http://maximelabelle.wordpress.com/2012/12/19/prise-en-main-du-cache-sous-windows-azure/</link>
		<comments>http://maximelabelle.wordpress.com/2012/12/19/prise-en-main-du-cache-sous-windows-azure/#comments</comments>
		<pubDate>Wed, 19 Dec 2012 07:04:28 +0000</pubDate>
		<dc:creator>Maxime Labelle</dc:creator>
				<category><![CDATA[Windows Azure]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Cache]]></category>
		<category><![CDATA[Caching]]></category>

		<guid isPermaLink="false">http://maximelabelle.wordpress.com/?p=573</guid>
		<description><![CDATA[This article has been written in an effort by the Windows Azure France team to coordinate the writing of tutorials and how-to guides for various Windows Azure features and technologies. This guide is a direct translation in french of the &#8230; <a href="http://maximelabelle.wordpress.com/2012/12/19/prise-en-main-du-cache-sous-windows-azure/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&#038;blog=16599311&#038;post=573&#038;subd=maximelabelle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><em>This article has been written in an effort by the Windows Azure France team to coordinate the writing of tutorials and how-to guides for various Windows Azure features and technologies. This guide is a direct translation in french of the &#8216;<a href="http://www.windowsazure.com/en-us/develop/net/how-to-guides/cache/">How to Use Windows Azure Caching</a>&#8216; guide, available on MSDN</em></p>
<h1>Introduction</h1>
<p>« Windows Azure Caching », est une nouvelle fonctionnalité de mémoire cache distribuée disponible pour vos applications Windows Azure.</p>
<p>Elle apporte une amélioration des performances de vos applications Windows Azure, en permettant le stockage en mémoire d&#8217;informations provenant de différentes sources de données, telles que des bases de données, par exemple. En stockant en mémoire les informations fréquemment utilisées en provenance d&#8217;une base de données, il est possible de réduire le nombre de transactions effectuées, améliorant d&#8217;autant la capacité de l&#8217;application à pouvoir monter en charge, par exemple.</p>
<p>Le Cache sous Windows Azure supporte l&#8217;enregistrement de tout objet .Net persistant (<em>serialisable</em>) et inclut un fournisseur de session et d&#8217;enregistrement du rendu des pages ASP.Net préconfigurés, permettant l&#8217;accélération des applications web sans modification.</p>
<p>Un modèle de développement unique, que ce soit pour le déploiement d&#8217;applications sur Windows Azure ou AppFabric 1.1 for Windows Server, permet d&#8217;exploiter la mise en cache.</p>
<p><strong>Avertissement</strong> : le Cache sous Windows Azure remplace avantageusement une fonctionnalité similaire, « Windows Azure AppFabric Caching », qui s&#8217;appuie sur une infrastructure mutualisée. Celle-ci devient obsolète et il est recommandé de ne plus l&#8217;utiliser.</p>
<p>Au contraire, « Windows Azure Caching » introduit un nouveau modèle pour la mise en cache, en utilisant une portion de la mémoire des machines virtuelles sur lesquelles les instances de rôles s&#8217;exécutent.</p>
<p>En comparaison, l&#8217;utilisation des instances de rôles pour la mise en cache offre les avantages suivants :</p>
<ul>
<li>Des options de déploiement plus souples, sans limites de taille ni quota de restrictions.</li>
<li>Pas de coût supplémentaire pour l&#8217;utilisation des ressources de mise en cache.</li>
<li>Un contrôle et un niveau d&#8217;isolation plus fins.</li>
<li>Une capacité à suivre la charge de l&#8217;application, en adaptant la taille du cache au nombre d&#8217;instances s&#8217;exécutant pour un rôle. La mémoire disponible pour le cache est effectivement augmentée ou réduite au fur et à mesure que des instances de rôle sont ajoutées ou supprimées.</li>
<li>Des performances améliorées.</li>
</ul>
<p>En outre, une expérience du débogage proche du fonctionnement en production est également proposée, avec un service d&#8217;émulation du cache sur le poste de développement.</p>
<p>Ce guide de prise en main offre un aperçu rapide de la fonctionnalité de mise en cache de la mémoire sous Windows Azure. Les fonctionnalités démontrées dans ce guide sont les suivantes :</p>
<ul>
<li>Configuration d&#8217;un <em>cache cluster</em> pour mise à disposition d&#8217;un cache d&#8217;application.</li>
<li>Configuration d&#8217;un rôle client du cache.</li>
<li>Ajout et récupération d&#8217;objets dans le cache.</li>
<li>Enregistrement du cache des sessions ASP.Net dans le cache Windows Azure.</li>
<li>Activation du cache pour le rendu des pages ASP.Net.</li>
</ul>
<p>Pour une référence plus détaillée du Cache sous Windows Azure, n&#8217;hésitez pas à vous reporter à l&#8217;un des articles officiels, référencés à la fin de ce guide.</p>
<h1>Premiers pas</h1>
<p>Comme indiqué, le Cache sous Windows Azure utilise la mémoire des machines virtuelles associées aux instances de rôle pour fournir un espace de mémoire cache. Les instances de rôle qui contribuent à fournir de l&#8217;espace au cache forment collectivement le <strong><em>cache cluster</em></strong>.</p>
<p>Le <em>cache cluster</em> doit être configuré au préalable à la mise à disposition aux clients du cache.</p>
<h2>Configuration du <em>cache cluster</em></h2>
<p>Le Cache sous Windows Azure peut être déployé selon deux topologies de mise en cache qui se distinguent par l&#8217;utilisation ou non de rôles existants :</p>
<ul>
<li><strong>Cache colocalisé</strong> : l&#8217;utilisation de rôles existants pour la fourniture du cache mutualise les ressources – en particulier, la mémoire vive – utilisées pour l&#8217;exécution de vos applications.</li>
<li><strong>Cache dédié</strong> : la création de rôles dédiés à la fourniture du cache permet l&#8217;utilisation de l&#8217;intégralité des ressources associées aux machines virtuelles qui forment le <em>cache cluster</em>.</li>
</ul>
<p>La configuration d&#8217;un cache colocalisé se fait en spécifiant un pourcentage d&#8217;utilisation de la mémoire disponible pour chaque instance d&#8217;un rôle. Pour ce faire, afficher les propriétés d&#8217;un rôle existant et sélectionner la rubrique « Cache » d&#8217;application :</p>
<p style="text-align:center;"><img alt="" src="http://maximelabelle.files.wordpress.com/2012/12/121912_0704_1.png?w=640" /></p>
<p>L&#8217;activation du cache sur un rôle existant crée, par défaut, un <em>cache cluster</em> colocalisé qui tire parti de 30% de la mémoire associée à chacune des instances. Un cache par défaut est également configuré automatiquement, mais il est possible de créer d&#8217;autres espaces de cache logiques si nécessaire.</p>
<p>Un <em>cache cluster</em> doit maintenir les données de configuration et synchroniser sont état de fonctionnement entre les différentes machines virtuelles qui contribuent au cache. C&#8217;est pourquoi il est nécessaire de préciser un compte de stockage Windows Azure valide à cet effet.</p>
<p style="text-align:center;"><img alt="" src="http://maximelabelle.files.wordpress.com/2012/12/121912_0704_2.png?w=640" /></p>
<p><strong>Avertissement</strong> : si aucun compte de stockage n&#8217;est configuré, le rôle ne pourra pas démarrer.</p>
<p>La configuration d&#8217;un cache dédié peut se faire via l&#8217;ajout d&#8217;un projet de rôle « Cache Worker Role » à la solution:</p>
<p style="text-align:center;"><img alt="" src="http://maximelabelle.files.wordpress.com/2012/12/121912_0704_3.png?w=640" /></p>
<p>La création d&#8217;un rôle dédié au cache créé un rôle sans implémentation particulière et auquel il est recommandé de ne rien ajouter, sous peine d&#8217;impacter négativement les performances du cache.</p>
<p style="text-align:center;"><img alt="" src="http://maximelabelle.files.wordpress.com/2012/12/121912_0704_4.png?w=640" /></p>
<p>De même que précédemment, ne pas oublier de préciser un compte de stockage Windows Azure valide pour le maintien et la synchronisation de l&#8217;état de fonctionnement du cache.</p>
<p>Dans tous les cas, la taille exacte du cache résulte d&#8217;une combinaison de facteurs, parmi lesquels :</p>
<ul>
<li>Le caractère colocalisé ou dédié du <em>cache cluster</em>.</li>
<li>La taille des machines virtuelles associées au rôle.</li>
<li>Le nombre d&#8217;instances configurées.</li>
</ul>
<p>La taille et le nombre d&#8217;instances configurées pour l&#8217;exécution d&#8217;un rôle sont accessibles dans les propriétés de configuration de chacun des rôles :</p>
<p style="text-align:center;"><img alt="" src="http://maximelabelle.files.wordpress.com/2012/12/121912_0704_5.png?w=640" /></p>
<p>Pour référence, la taille totale pour la mémoire allouée aux machines virtuelles est listée ci-après. Cette mémoire est partagée entre l&#8217;exécution du système d&#8217;exploitation, le processus de gestion et les données du cache, ainsi que, dans le cas de la colocalisation, de vos applications. En tout état de cause, la taille disponible pour le cache lui-même peut-être inférieure.</p>
<ul>
<li><strong>Small</strong> : 1,75 Go.</li>
<li><strong>Medium</strong> : 3,5 Go.</li>
<li><strong>Large</strong> : 7 Go.</li>
<li><strong>Extra Large</strong> : 14 Go.</li>
</ul>
<p>À noter que le cache n&#8217;est pas supporté sur des machines dont la taille est configurée à <strong>Extra Small</strong>.</p>
<h2>Configuration des rôles clients du cache</h2>
<p>Les rôles clients du cache doivent être situés dans le même déploiement que celui dans lequel est configuré le <em>cache cluster</em>.</p>
<p>Dans le cas d&#8217;un cache dédié, les rôles clients du cache sont tout simplement les autres rôles hébergés dans le service. Si le cache est colocalisé, il peut s&#8217;agir de n&#8217;importe quels rôles hébergés dans le service, y compris ceux destinés à l&#8217;exécution du service de cache.</p>
<p>La configuration de chaque rôle client du cache peut être effectuée via l&#8217;installation d&#8217;un package NuGet « Microsoft.WindowsAzure.Caching » qui peut être directement installé à l&#8217;aide du gestionnaire de packages dans Visual Studio :</p>
<p>Avec le bouton droit de la souris, cliquer sur le projet de rôle auquel ajouter l&#8217;accès au cache, et sélectionner « <strong>Manage NuGet Packages… </strong>». Dans la boîte de dialogue qui s&#8217;affiche, sélectionner le package « <strong>Windows Azure Caching</strong> », cliquer sur <strong>Install</strong> puis sur <strong>I accept</strong>.</p>
<p>Si le package n&#8217;apparaît pas dans la liste, utiliser la zone de texte <strong>Search Online (Ctrl+E)</strong> pour effectuer une recherche sur « <strong>WindowsAzure Caching</strong> ».</p>
<p style="text-align:center;"><img alt="" src="http://maximelabelle.files.wordpress.com/2012/12/121912_0704_6.png?w=640" /></p>
<p>Le package NuGet effectue les actions suivantes ; il modifie le fichier de configuration du rôle, ajoute un paramètre de niveau de diagnostique pour le client du cache au fichier ServiceConfiguration.csfg associée à l&#8217;application Windows Azure, et ajoute les références d&#8217;<em>assembly</em> appropriées.</p>
<p>De plus, pour un web rôle ASP.Net, le package NuGet ajoute deux sections au fichier web.config ; la première concerne le paramétrage du cache de session ASP.Net et la seconde active la mise en cache du rendu des pages ASP.Net. Ces deux fonctionnalités sont expliquées plus bas dans ce guide.</p>
<p>Les références d&#8217;<em>assembly</em> suivantes sont nécessaires pour l&#8217;accès au cache :</p>
<ul>
<li>Microsoft.ApplicationServer.Caching.Client.dll</li>
<li>Microsoft.ApplicationServer.Caching.Core.dll</li>
<li>Microsoft.WindowsFabric.Common.dll</li>
<li>Microsoft.WindowsFabric.Data.Common.dll</li>
<li>Microsoft.ApplicationServer.Caching.AzureCommon.dll</li>
<li>Microsoft.ApplicationServer.Caching.AzureClientHelper.dll</li>
</ul>
<p>Dans le cas d&#8217;un web rôle ASP.Net, la référence d&#8217;<em>assembly</em> suivante est également ajoutée :</p>
<ul>
<li>Microsoft.Web.DistributedCache.dll.</li>
</ul>
<p>La configuration du rôle est modifiée lors de l&#8217;installation du package NuGet. Deux nouveaux éléments, <strong>dataCacheClients</strong> et <strong>cacheDiagnostics</strong>, sont ajoutés au fichier web.config ou app.config, dans la section de configuration <strong>configSections</strong>. S&#8217;il n&#8217;y avait pas d&#8217;élément <strong>configSections</strong> dans le fichier, il est initialement créé en tant qu&#8217;enfant de l&#8217;élément <strong>configuration</strong>.</p>
<pre class="brush: xml; title: ; notranslate">
 &lt;configuration&gt;
 &lt;configSections&gt;
 ...
 &lt;section name=&quot;dataCacheClients&quot;
 type=&quot;Microsoft.ApplicationServer.Caching.DataCacheClientsSection, Microsoft.ApplicationServer.Caching.Core&quot;
 allowLocation=&quot;true&quot; allowDefinition=&quot;Everywhere&quot;
 /&gt;

 &lt;section name=&quot;cacheDiagnostics&quot;
 type=&quot;Microsoft.ApplicationServer.Caching.AzureCommon.DiagnosticsConfigurationSection, Microsoft.ApplicationServer.Caching.AzureCommon&quot;
 allowLocation=&quot;true&quot; allowDefinition=&quot;Everywhere&quot;
 /&gt;
 &lt;/configSections&gt;
</pre>
<p>Ces deux sections font référence à deux nouveaux éléments, respectivement, <strong>dataCacheClients</strong> et <strong>cacheDiagnostics</strong>, tous deux également ajoutés sous l&#8217;élément <strong>configuration</strong>.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;dataCacheClients&gt;
    &lt;dataCacheClient name=&quot;default&quot;&gt;
      &lt;autoDiscover isEnabled=&quot;true&quot; identifier=&quot;[cache cluster role name]&quot; /&gt;
      &lt;!--
     &lt;localCache isEnabled=&quot;true&quot;
              sync=&quot;TimeoutBased&quot;
              objectCount=&quot;100000&quot;
              ttlValue=&quot;300&quot; /&gt;
     --&gt;
    &lt;/dataCacheClient&gt;
  &lt;/dataCacheClients&gt;
  &lt;cacheDiagnostics&gt;
    &lt;crashDump dumpLevel=&quot;Off&quot; dumpStorageQuotaInMB=&quot;100&quot; /&gt;
  &lt;/cacheDiagnostics&gt;
</pre>
<p>Une fois la configuration ajoutée, modifier l&#8217;emplacement réservé <strong>[cache cluster role name]</strong> par le nom du rôle configuré pour l&#8217;exécution du <em>cache cluster</em>.</p>
<p><strong>Avertissement</strong> : à défaut, une exception <strong>TargetInvocationException</strong> sera levée au moment de l&#8217;exécution. Sa propriété <strong>InnerException</strong> renverra un objet <strong>DatacacheException</strong> avec le message « <span style="color:#666666;font-family:Segoe UI;font-size:10pt;">No such role exists.</span> »</p>
<p>L&#8217;installation du package NuGet ajoute également un paramètre <strong>ClientDiagnosticLevel</strong> à la section <strong>ConfigurationSettings</strong> associée au rôle client du cache dans le fichier ServiceConfiguration.csfg. À titre d&#8217;exemple, voici une section correspondante du fichier ServiceConfiguration.csfg :</p>
<pre class="brush: xml; title: ; notranslate">
  &lt;Role name=&quot;WebRole1&quot;&gt;
    ...
    &lt;ConfigurationSettings&gt;
    ...
    &lt;Setting name=&quot;Microsoft.WindowsAzure.Plugins.Caching.ClientDiagnosticLevel&quot;
             value=&quot;1&quot; /&gt;
    &lt;/ConfigurationSettings&gt;
  &lt;/Role&gt;
</pre>
<p>Le Cache sur Windows Azure est sensible à la fois au niveau de diagnostic du cache cluster et à celui du ou des rôles clients du cache. Le niveau de diagnostic est un paramètre utilisé pour filtrer le niveau d&#8217;informations collectées lors de l&#8217;exécution du cache. Sa valeur par défaut est 1.</p>
<p>Une fois le rôle client du cache correctement configuré, se reporter aux techniques décrites dans les sections suivantes pour la manipulation du cache.</p>
<h1>Manipulation du cache</h1>
<h2>Instanciation d&#8217;un objet DataCache de manipulation du cache</h2>
<p>Afin de pouvoir interagir avec le cache, il est nécessaire d&#8217;y faire référence, en ajoutant l&#8217;espace de nommage suivant parmi le groupe des instructions <em>using </em>situées en haut de chaque fichier source dans lequel il est nécessaire d&#8217;accéder au cache.</p>
<pre class="brush: csharp; title: ; notranslate">
using Microsoft.ApplicationServer.Caching;
</pre>
<p>Si Visual Studio ne reconnaît pas l&#8217;instruction <em>using</em>, même après avoir installé le package NuGet « Windows Azure Caching » qui ajoute les références d&#8217;<em>assembly</em> appropriées, s&#8217;assurer que la cible du projet est correctement configurée à .Net Framework 2.0 ou ultérieure, à l&#8217;exception des profils affublés de la mention « <strong>Client Profile</strong> ». Se reporter à la section précédente relative à la configuration des rôles clients du cache pour obtenir des instructions plus précises.</p>
<p>Un premier moyen pour instancier un objet <strong>DataCache</strong> est tout simplement de créer une nouvelle instance en passant le nom du cache logique en paramètre du constructeur. Il est ensuite possible d&#8217;ajouter des objets dans le cache ou de récupérer des objets depuis le cache en suivant les instructions décrites dans la section suivante de ce guide.</p>
<pre class="brush: csharp; title: ; notranslate">
DataCache dataCache = new DataCache(&quot;default&quot;);
</pre>
<p>Un autre moyen pour instancier un objet <strong>DataCache</strong> est d&#8217;utiliser l&#8217;objet <strong>DataCacheFactory</strong> dans votre application. L&#8217;utilisation du constructeur par défaut force l&#8217;utilisation des paramètres figurant dans le fichier de configuration.</p>
<p>Appeler, sur l&#8217;instance <strong>DataCacheFactory</strong>, la méthode <strong>GetDefaultCache</strong> ou bien la méthode <strong>GetCache</strong> en précisant le nom du cache logique. Ces deux méthodes renvoient un objet <strong>DataCache</strong> avec lequel il est possible d&#8217;utiliser le cache comme indiqué dans la prochaine section.</p>
<pre class="brush: csharp; title: ; notranslate">
// cache client configured by settings in configuration file

DataCacheFactory cacheFactory = new DataCacheFactory();
DataCache cache = cacheFactory.GetDefaultCache();

// or select named cache 
//DataCache cache = cacheFactory.GetCache(&quot;MyCache&quot;);

// cache can now be used to add, retrieve or remove items 
</pre>
<h2>Ajout et récupération d’objets dans le cache</h2>
<p>Pour ajouter un élément dans le cache, l’une des méthodes <strong>Add</strong> ou <strong>Put</strong> peut être utilisée. La méthode <strong>Add</strong> ajoute l’objet spécifié en l’associant à une clé, précisée par la valeur du paramètre key. Si un objet possédant la même clé est déjà enregistré dans le cache, une exception de type <strong>DataCacheException</strong> sera levée au moment de l’exécution, avec le message suivant :</p>
<p><span style="color:gray;">ErrorCode:SubStatus: An attempt is being made to create an object with a Key that already exists in the cache. Caching will only accept unique Key values for objects.</span></p>
<pre class="brush: csharp; title: ; notranslate">
// adds the string &quot;value&quot; to the cache, keyed by &quot;item&quot;
string value = &quot;value&quot;;
cache.Add(&quot;item&quot;, value);
</pre>
<p>La méthode <strong>Put</strong> ajoute également un élément dans le cache, en utilisant la clé précisée. Si un objet possédant la même clé est déjà présent dans le cache, il est remplacé par le nouvel élément spécifié lors de l&#8217;appel de cette méthode.</p>
<pre class="brush: csharp; title: ; notranslate">
// adds or replaces the string keyd by &quot;item&quot; in the cache
string newValue = &quot;newValue&quot;;
cache.Put(&quot;item&quot;, newValue);
</pre>
<p>Pour récupérer un élément enregistré dans le cache, utiliser la méthode <strong>Get</strong>. Cette méthode retourne l&#8217;objet spécifié s&#8217;il existe. Dans le cas contraire, cette méthode retourne null.</p>
<pre class="brush: csharp; title: ; notranslate">
string value = String.Empty;

// retrieves an item from the cache, keyed by &quot;item&quot;
object result = cache.Get(&quot;item&quot;);
if (result == null)
{
    // &quot;item&quot; not in cache. Obtain it from specified data source
    // and add it to the cache for later retrieval
    value = GetItemValue(...);
    cache.Add(&quot;item&quot;, value);
}
else
{
    // &quot;item&quot; is in cache, cast result to correct type.
    System.Diagnostics.Debug.Assert(result is string);
    value = result as String;
}
</pre>
<h2>Gestion du délai d&#8217;expiration des éléments du cache</h2>
<p>Par défaut, les éléments placés dans le cache expirent, et sont supprimés du cache, au bout de 10 minutes. Ce délai est précisé par la valeur du paramètre <strong>Time to Live (min)</strong> associée au cache nommé dans les propriétés du rôle qui héberge le <em>cache cluster</em>.</p>
<p><img alt="" src="http://maximelabelle.files.wordpress.com/2012/12/121912_0704_7.png?w=640" /></p>
<p>Il y a trois façons de préciser le délai d&#8217;expiration d&#8217;un objet dans le cache, en sélectionnant le paramètre <strong>Expiration Type</strong> associé au cache nommé.</p>
<p>Par défaut, le délai d&#8217;expiration est exprimé de manière absolue. Le délai d&#8217;expiration d&#8217;un élément commence dès qu&#8217;il est placé dans le cache. Une fois le délai écoulé, l&#8217;élément expire et est supprimé du cache. Cela correspond au réglage <strong>Absolute</strong>. Placé sur <strong>Sliding Window</strong>, le délai d&#8217;expiration d&#8217;un élément est remis à zéro à chaque fois qu&#8217;une tentative de récupérer ou mettre à jour cet élément est effectuée dans le cache. L&#8217;élément n&#8217;expire que si aucun accès n&#8217;y est fait pendant toute la durée du délai d&#8217;expiration. Enfin, si le paramètre est placé à la valeur <strong>None</strong>, le délai d&#8217;expiration doit avoir pour valeur 0. Les éléments placés dans le cache n&#8217;expirent jamais et restent valides tant qu&#8217;ils sont dans le cache.</p>
<p>Si un délai d&#8217;expiration différent de celui configuré dans les propriétés du rôle est nécessaire, il est possible de préciser une valeur spécifique au moment de l&#8217;ajout ou de la mise à jour d&#8217;un élément du cache en utilisant les surcharges des méthodes <strong>Add</strong> et <strong>Put</strong> qui acceptent un paramètre de type <strong>TimeSpan</strong>. À titre d&#8217;exemple, voici comment préciser un délai de trente minutes :</p>
<pre class="brush: csharp; title: ; notranslate">
// adds the string &quot;value&quot; to the cache, keyed by &quot;item&quot;
string value = &quot;value&quot;;
cache.Add(&quot;item&quot;, value, TimeSpan.FromMinutes(30));
</pre>
<p>Pour obtenir le délai d&#8217;expiration d&#8217;un élément particulier dans le cache, la méthode <strong>GetCacheItem</strong> permet d&#8217;obtenir un objet <strong>DataCacheItem</strong> qui contient certaines informations relatives à l&#8217;élément placé dans le cache, y compris le temps restant jusqu&#8217;à expiration :</p>
<pre class="brush: csharp; title: ; notranslate">
// obtain a DataCacheItem containing informations about a cache item.
// if no object keyed &quot;item&quot; exists, then null is returned.
DataCacheItem item = cache.GetCacheItem(&quot;item&quot;);
if (item != null)
{
    TimeSpan remaining = item.Timeout
    ...
}
</pre>
<h2>Enregistrement du cache de session ASP.Net dans le cache</h2>
<p>Le Cache sur Windows Azure inclut un fournisseur ASP.Net pour l&#8217;enregistrement de l&#8217;état de session dans le cache, plutôt que directement en mémoire ou dans une base de données SQL. Pour utiliser ce fournisseur, s&#8217;assurer au préalable d&#8217;avoir correctement configuré le cache cluster et le web rôle en tant que client du cache en suivant les étapes décrites plus haut dans ce guide.</p>
<p>L&#8217;installation du package NuGet ajoute une section commentée dans le fichier web.config. Cette section contient tout le paramétrage nécessaire à l&#8217;utilisation du fournisseur d&#8217;enregistrement de l&#8217;état de session pour la Cache sur Windows Azure.</p>
<pre class="brush: xml; title: ; notranslate">
    &lt;!-- Windows Azure Caching session state provider --&gt;
    &lt;!--&lt;sessionState mode=&quot;Custom&quot; customProvider=&quot;AFCacheSessionStateProvider&quot;&gt;
      &lt;providers&gt;
        &lt;add name=&quot;AFCacheSessionStateProvider&quot;
type=&quot;Microsoft.Web.DistributedCache.DistributedCacheSessionStateStoreProvider, Microsoft.Web.DistributedCache&quot;
                cacheName=&quot;default&quot;
                dataCacheClientName=&quot;default&quot;
                applicationName=&quot;AFCacheSessionState&quot;/&gt;
      &lt;/providers&gt;
    &lt;/sessionState&gt;--&gt;
</pre>
<p>Si le fichier web.config ne contient pas cette section commentée, s&#8217;assurer que la version la plus à jour du gestionnaire de packages NuGet est installée. Au besoin, supprimer puis ré-installer le package NuGet « Windows Azure Caching » pour que le fichier web.config soit correctement mis à jour.</p>
<p>Pour activer l&#8217;utilisation du fournisseur d&#8217;enregistrement de session, supprimer simplement les commentaires autour de la section correspondante dans le fichier web.config. Dans l&#8217;exemple ci-dessus, le cache par défaut est utilisé. Pour utiliser un autre cache nommé, préciser simplement son nom dans l&#8217;attribut <strong>cacheName</strong>.</p>
<p>Pour plus d&#8217;information sur l&#8217;utilisation du fournisseur d&#8217;enregistrement de l&#8217;état de session ASP.Net, se reporter aux liens officiels qui figurent en ressources à la fin de ce guide.</p>
<h2>Activation du cache pour le rendu des pages ASP.Net</h2>
<p>Le Cache sur Windows Azure inclut également un fournisseur ASP.Net pour l&#8217;enregistrement du rendu des pages web dans le cache. Ce fournisseur est spécifiquement conçu pour l&#8217;enregistrement de réponses http complètes – ce qui correspond à des pages entières. Le fournisseur tire parti du nouveau mécanisme d&#8217;extension des fournisseurs d&#8217;enregistrement du rendu des pages introduit avec ASP.Net 4.</p>
<p>Pour utiliser ce fournisseur, s&#8217;assurer au préalable d&#8217;avoir correctement configuré le cache cluster et le web rôle en tant que client du cache en suivant les étapes d&#8217;installation du package NuGet décrites plus haut dans ce guide.</p>
<p>L&#8217;installation du package NuGet « Windows Azure Caching » ajoute une section commentée dans le fichier web.config. Cette section contient tout le paramétrage nécessaire à l&#8217;utilisation du fournisseur d&#8217;enregistrement du rendu des pages en cache dans Windows Azure.</p>
<pre class="brush: xml; title: ; notranslate">
    &lt;!-- Windows Azure Caching output caching provider --&gt;
    &lt;!--&lt;caching&gt;
      &lt;outputCache defaultProvider=&quot;AFCacheOutputCacheProvider&quot;&gt;
        &lt;providers&gt;
          &lt;add name=&quot;AFCacheOutputCacheProvider&quot;
type=&quot;Microsoft.Web.DistributedCache.DistributedCacheOutputCacheProvider, Microsoft.Web.DistributedCache&quot;
                cacheName=&quot;default&quot;
                dataCacheClientName=&quot;default&quot;
                applicationName=&quot;AFCacheOutputCache&quot; /&gt;
        &lt;/providers&gt;
      &lt;/outputCache&gt;
    &lt;/caching&gt;--&gt;
</pre>
<p>Si le fichier web.config ne contient pas cette section commentée, s&#8217;assurer que la version la plus à jour du gestionnaire de packages NuGet est installée. Au besoin, supprimer puis ré-installer le package NuGet « Windows Azure Caching » pour que le fichier web.config soit correctement mis à jour.</p>
<p>Pour activer l&#8217;enregistrement du rendu des pages ASP.Net en cache, supprimer simplement les commentaires autour de la section correspondante dans le fichier web.config. Dans l&#8217;exemple ci-dessus, le cache par défaut est utilisé. Pour utiliser un autre cache nommé, préciser simplement son nom dans l&#8217;attribut <strong>cacheName</strong>.</p>
<p>Ajouter ensuite une directive <strong>OutputCache</strong> en en-tête de chacune des pages qui doivent être mises en cache.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;%@ OutputCache Duration=&quot;60&quot; VaryByParam=&quot;*&quot; %&gt;
</pre>
<p>Dans cet exemple, les données de page mises en cache le seront pendant 60 secondes. Une version différente de la page sera également mise en cache pour chaque combinaison de paramètres.</p>
<p>Pour plus d&#8217;information sur l&#8217;utilisation du fournisseur d&#8217;enregistrement de l&#8217;état de session ASP.Net, se reporter aux liens officiels qui figurent en ressources à la fin de ce guide.</p>
<h1>Autres ressources</h1>
<p>Ce guide a été écrit dans le cadre d&#8217;un travail mené par l&#8217;équipe Windows Azure France pour mettre en œuvre la création ou le relais de tutoriaux pour la communauté francophone. Il est directement inspiré du tutorial officiel, situé à l&#8217;emplacement suivant :</p>
<p><span style="font-size:10pt;">[1] How to Use Windows Azure Caching<br />
<a href="http://www.windowsazure.com/en-us/develop/net/how-to-guides/cache/">http://www.windowsazure.com/en-us/develop/net/how-to-guides/cache/</a><br />
</span></p>
<p>Les ressources suivantes ont également été utilisées, en partie, pour la rédaction de ce guide de prise en main :</p>
<p><span style="font-size:10pt;">[2] <a href="http://msdn.microsoft.com/en-us/library/hh914161">Overview of Windows Azure Caching</a></span></p>
<p><span style="font-size:10pt;">[3] <a href="http://msdn.microsoft.com/en-us/library/hh914142">Windows Azure Caching FAQ</a></span></p>
<p><span style="font-size:10pt;">[4] <a href="http://msdn.microsoft.com/en-us/library/hh914129.aspx">Capacity Planning Considerations for Windows Azure Caching</a></span></p>
<p><span style="font-size:10pt;">[5] <a href="http://msdn.microsoft.com/en-us/library/windowsazure/gg185668.aspx">Session State Provider for Windows Azure Caching</a></span></p>
<p><span style="font-size:10pt;">[6] <a href="http://msdn.microsoft.com/en-us/library/windowsazure/gg185662.aspx">Output Cache Provider for Windows Azure Caching</a></span></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maximelabelle.wordpress.com/573/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maximelabelle.wordpress.com/573/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&#038;blog=16599311&#038;post=573&#038;subd=maximelabelle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maximelabelle.wordpress.com/2012/12/19/prise-en-main-du-cache-sous-windows-azure/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/957e1e828557735f52843d3c69f29b1e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maximelabelle</media:title>
		</media:content>

		<media:content url="http://maximelabelle.files.wordpress.com/2012/12/121912_0704_1.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2012/12/121912_0704_2.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2012/12/121912_0704_3.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2012/12/121912_0704_4.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2012/12/121912_0704_5.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2012/12/121912_0704_6.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2012/12/121912_0704_7.png" medium="image" />
	</item>
		<item>
		<title>My Review of the Microsoft Surface for Windows RT</title>
		<link>http://maximelabelle.wordpress.com/2012/11/01/my-review-of-the-microsoft-surface-for-windows-rt/</link>
		<comments>http://maximelabelle.wordpress.com/2012/11/01/my-review-of-the-microsoft-surface-for-windows-rt/#comments</comments>
		<pubDate>Thu, 01 Nov 2012 10:25:15 +0000</pubDate>
		<dc:creator>Maxime Labelle</dc:creator>
				<category><![CDATA[Non classé]]></category>
		<category><![CDATA[Surface]]></category>
		<category><![CDATA[Windows8]]></category>
		<category><![CDATA[WindowsRT]]></category>

		<guid isPermaLink="false">http://maximelabelle.wordpress.com/?p=519</guid>
		<description><![CDATA[Ever since Windows 8 has been announced to the world back in September 2011, I have been very excited and interested in the direction that Microsoft is taking, in order to virtually regain a foothold in the mobile industry – &#8230; <a href="http://maximelabelle.wordpress.com/2012/11/01/my-review-of-the-microsoft-surface-for-windows-rt/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&#038;blog=16599311&#038;post=519&#038;subd=maximelabelle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Ever since Windows 8 has been announced to the world back in September 2011, I have been very excited and interested in the direction that Microsoft is taking, in order to virtually regain a foothold in the mobile industry – a market that has been taken over by competitors such as Apple and Google for so long.</p>
<p>And ever since Microsoft announced the line of Surface Tablet computing devices back in June, I have been doubly excited and knew I would be one of the first to purchase one when available.</p>
<span class='embed-youtube' style='text-align:center; display: block;'><iframe class='youtube-player' type='text/html' width='560' height='315' src='http://www.youtube.com/embed/dpzu3HM2CIo?version=3&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;wmode=transparent' frameborder='0'></iframe></span>
<p>I’ve been using Windows 8 virtually from day one, on a Samsung Tablet – the one that has been given to every <a href="http://channel9.msdn.com/Events/BUILD/BUILD2011">//build/</a> attendee, back in September 2011 – using each and every publicly available iteration of the system – from the Developer Preview, the Consumer Preview, the Release Preview, the RTM version and finally the Generally Available version that everybody can use now, with a vastly optimized system, slightly updated or enhanced built-in Apps and a substantially larger number of Windows Store Apps to choose from.</p>
<p>Most of you know that, by now, Windows 8 has launched and is available for purchase. What&#8217;s more interesting however, is the availability of new hardware accompanying the operating system, most noticeably new tablets of which Microsoft Surface for Windows RT is but the first available.</p>
<p>In the recent weeks leading up to the launch of Surface, I have seen mostly mixed and even negative reviews. But I always had a feeling the authors of these reviews either did not fully grasp what Windows RT is about or, most probably, did not have the chance to use and touch the tablet for real before writing their review.</p>
<p>Since I have been using Windows RT for a little less than a week, now is therefore a good time for a fair an honest review.</p>
<p>Here goes.</p>
<p><span style="font-family:Tahoma;font-weight:bold;">Evaluating the Hardware</span></p>
<p style="text-align:center;"><img alt="Surface for Windows RT Packaging" src="http://maximelabelle.files.wordpress.com/2012/11/surface-for-windows-rt.png?w=420" width="420" /></p>
<p>Out of the box, the Surface for Windows RT <em>feels</em> heavy, in a sturdy and solid sort of way. Its boasts this distinctive industrial design that is the hallmark of any great product. Looking at the specs, it’s actually just a teeny bit 28-grams heavier than the current-generation iPad, so that’s more of an impression.</p>
<p>One of the distinguishing features of the Surface is its kickstand. Why didn’t anybody ever think of this before? Its primary use, together with the included keyboard cover, is to make the tablet look like a laptop. But you can use it to show off pictures and slideshows during family events.</p>
<p>The Touch Cover is brilliant. Its serves as a protecting cover with a rough scratch-resilient and spill-resistant finish. It “clicks-in” automagically to its intended position and doubles as a multi-touch keyboard. The keyboard has a decent size and each key is where it should be – with the odd omission of the F<em>n</em>-keys usually found on the upper row of any standard keyboard. It sure beats using the on-screen keyboard for more than casual editing and you can rest your fingers on the keyboard without fear of inadvertent typing.</p>
<p>However, typing on the Touch Cover is not an entirely satisfying experience because there is no feedback and one needs to constantly check for any typo. You also need to dose the applied pressure for typing and that certainly takes a certain amount of getting used to. My guess is that this situation will improve a bit over time – as will the speed of typing – as the habit sinks in.</p>
<p>In terms of connectivity, the tablet boasts a full-size USB connector that allows you to plug a wide range of peripherals. I’ve been able to insert thumb drives and a couple of wireless mouse dongles that have been instantly recognized. Key scenarios for using the USB port is to allow file transfer, accessing pictures from a digital camera and, of course, making the device a laptop-like productivity tablet with a mouse and Microsoft Office.</p>
<p>The Surface also has a micro-SD slot located just beneath the kickstand which is a welcome addition and gives us yet more options for expansion.</p>
<p>The micro-HDMI connector <a href="http://www.winsupersite.com/article/windows8/microsoft-surface-video-144651">allows for full-HD video output</a> on a secondary monitor, which makes the prospect of using the including Microsoft Office Suite much more appealing. But why on earth does Microsoft think you need a set or proprietary adapters – whose retail price starts at 40€ in the Microsoft Store – is beyond me.</p>
<p>On a final note, I was slightly disappointed to observe that the stylus that comes with the //build/ tablet does not work on the Surface RT screen. I’m told that any capacitive stylus should work just fine, but I find this confusing at this stage.</p>
<p>Likewise, the lack of GPS and NFC chipsets in the Surface RT disappoints the geek in me. But, to be honest, I had them on my //build/ tablet and actually never used them – perhaps due to a lack of software. Without capabilities to access 3G/4G mobile broadband networks, the Surface RT is primarily positioned for home use so that’s a point worth bearing in mind when evaluating which tablet to purchase.</p>
<p>One of the most touted feature found on competitor’s tablets is their <em>obscenely high™</em> resolution display. Well, clearly, at only 1366&#215;768, the Surface for Windows RT is way behind in terms of raw spec. However, watching movies and working on Word documents this week has been entirely satisfying so that’s not something that will have a noticeable impact in everyday use. Sure, it would have been nice for a 2012-ish tablet to match the current state of the competition, though.</p>
<p><span style="font-family:Tahoma;font-weight:bold;">Evaluating the Software</span></p>
<p>As its name suggest, Surface for Windows RT runs a special-purpose, modified version of Windows 8 primarily dedicated to running on low power devices equipped with an ARM processor. It is important to stress that Windows RT is different enough from Windows 8 in that it does not run Win32 applications but only Apps available from the Windows Store. This limitation is to make sure the system stays responsive and the performances do not degrade over time.</p>
<p>That said, Windows RT includes nonetheless a desktop version of Microsoft Office that has been ported to the ARM architecture. Currently, Microsoft Office is the only piece of desktop software running on Windows RT and it is not possible for anyone outside Microsoft to write desktop applications for Windows RT.        </p>
<p>Just after joining a WiFi network and setting up a user account, one of the first things to do is performing a system update and downloading latest versions of the built in Apps. This left me a capacity of around 45 Gb for a maximum of 54 Gb – which is the capacity seen by Windows for the advertised 64 Gb storage. This is quite a substantial loss for the remaining capacity. That probably explains why the Surface RT is not available with 16 Gb of storage capacity.</p>
<p>However, the micro-SD slot offers cheap storage expansion and, while it’s not possible to make use of this extra space for installing applications, it’s certainly possible to use it for storing extra documents and media. Although it&#8217;s not supported to bring this added space in your Windows Libraries &#8211; because it comes from removable storage &#8211; there are ways to circumvent this by making directory junctions, using the mklink.exe command-line utility which is present on the tablet. So you can definitely take advantage of this extra space and make it appear to be part of your Documents, Pictures, Music and Videos folders.</p>
<p>The ability to setup multiple user accounts makes sharing the tablet with other members of the family straightforward and secure, with the built in parental control. This, to me, is one of the killer features of Windows, not seen as far as I know on any other competitor’s device.</p>
<p>On the subject of security, the tablet comes with an enhanced version of its antivirus and malware prevention software called Windows Defender – formerly called Microsoft Security Essentials. The software is setup to be updated automatically and protects the tablet in real-time. No regular security scans are planned though, since this would consume power and mostly make sense after having installed third-party software, which is not possible here. But you can still perform security scans, either scheduled or on-demand if you receive suspicious attachments or transfer files from unknown or unreliable sources.</p>
<p>On the Modern UI side – the new Start Screen – everything is exactly the same as in Windows 8. It provides a host for all Windows Store immersive Apps, pinned sites and live tiles as well as shortcuts to favorite desktop apps – most notably Microsoft Office applications. This is where you’ll spend most of your time using the tablet, consuming contents and enjoying a “fast and fluid” experience. There are currently thousands of Apps in the Store and – if sources are to be trusted &#8211; many more are coming in the next few months.</p>
<p>Most applications launch in a few seconds but need to perform network synchronization in the background upon start, so it can take up a tiny bit of extra time before being fully usable. After that, you can switch between all open applications very quickly. Mind you, the tablet being a mobile device, you&#8217;re not supposed to &#8220;close&#8221; an application and it is best to let Windows manage the lifetime of each application. It will take care of killing least used applications when memory is at a premium and will ensure the system always stays responsive over time.    </p>
<p>The Modern UI Start Screen is very pleasant to use, with is vibrant colors and live tiles. But the desktop is still there, should you need it for advanced tweaking or productivity work.</p>
<p>Microsoft Office Home and Student 2013 Preview is there and, what to say? This in itself is probably the number one argument in favor of purchasing a Windows RT powered tablet. At this stage, I haven’t had the time to use it extensively but the experience appears to be identical to that of using Office on Windows 8 – apart from the obvious differences between editions and the expected omission of macros and support for ActiveX components. There seems to be confusion, though, over whether this edition of Office can be used in a business or commercial way. But my understanding is that your company must have a valid license of Microsoft Office already for this to permitted. In my view, that does not constitute a realistic problem since virtually every company I’ve ever worked with or for does indeed have a valid license of Microsoft Office.</p>
<p>Let’s not forget that this tablet targets home users and students. Therefore, Outlook is missing. But that can easily be replaced with the browser-based Outlook Web App or the built in, albeit simpler, Mail App.</p>
<p>There was a slight but noticeable latency when typing in Microsoft Word, until I realized that I was still using the preview version that was installed in the factory. Oddly enough, the final version of Office did not update automatically when I first set the device up because it was not considered an &#8220;important&#8221; update. After downloading and installing the required update, I found Word performing quickly and efficiently as it always should have. So, if you purchase the Surface, make doubly sure that Office is up to date before using it.</p>
<p>Another major application on the desktop is Internet Explorer 10. By and large, IE 10 is designed around a plugin-free browsing experience in favour of a more modern hardware-accelerated HTML5 and JavaScript powered web sites.</p>
<p>With the notable exception of Adobe Flash, which works in most – as in, “approved by Microsoft” – websites, including YouTube.</p>
<p>It’s interesting to note that, on full Windows 8, « Desktop IE » is the elder brother to the Modern UI App on the Start Screen and is there mostly to play legacy websites. Those requiring ActiveX and Silverlight plugins obviously, but also all those Adobe Flash powered websites not on the whitelist. This means that “Desktop IE” on Windows 8 displays more of the web than its Modern UI brethren.</p>
<p>However, sources at Microsoft confirm that, on Windows RT, both “Desktop IE” and the Modern UI IE are subject to the whitelist of approved web sites for which Adobe Flash content will be played. That’s a point worth mentioning for people trying to list differences between (the shared portions of) Windows RT and Windows 8.</p>
<p>To be honest, the web is already moving on from Flash – in no small part, thanks to the stance taken by Apple against this technology. But pragmatism at Microsoft makes it so that YouTube works so, what’s there to complain about?</p>
<p>On the desktop, the list of other software is meagre, but that is to be expected on a tablet not able to run (any arbitrary) Win32 applications. I would have welcomed little tools, though, such as the Journal application, Sticky Notes, and several others usually found on touched-enabled versions of Windows and which would have made sense on this tablet. Conversely, there’s an XPS viewer which, at first glance, seems redundant with the Modern UI Reader App.</p>
<p>To be complete, Windows Media Player is not there but would have been of no use in my opinion, since it almost always requires additional codecs to fully play popular videos. I think the built in Video App is better suited for this task on a mobile device anyway.</p>
<p>Please note, however, that the following software is present:</p>
<ul>
<li>Voice Recognition – I don’t know what this is worth but it might be interesting to find out what is the quality and usefulness of this application on the Surface RT.</li>
<li>Windows Powershell – for the geeks? If it is included, there might be interesting things to do. Again, might be interesting to find out exactly.</li>
</ul>
<p>In closing, I would like to address a few points worth considering, to make it clear where Windows RT sits exactly in the Windows universe.</p>
<p><span style="font-family:Tahoma;font-weight:bold;">Where does the Surface for Windows RT sit in the Windows 8 ecosystem?</span></p>
<p>In terms of capabilities, <em><strong>the Microsoft Surface for Windows RT tablet is a direct competitor to the Apple iPad</strong></em>. And one that, objectively, has the potential to be more capable than the iPad.</p>
<p>Given the recent growth to the number of available apps in the Windows Store – which went from about 5000 <a href="http://www.winappupdate.com/windows-store-taking-inventory-at-launch/">to more than 9000 apps</a> in a matter of three to four days – it is safe to say that, given the right set of Apps, the iPad does virtually nothing that the Surface for Windows RT can’t do.</p>
<p>Conversely, there are a lot of things that the Surface does out of the box, that aren’t readily possible on the iPad.</p>
<p>What about gaming and entertainment? Just plug an XBox-compatible game controller and you have access to hardware-accelerated <a href="https://developer.nvidia.com/windows-8">current generation</a> games. You can even connect the tablet to an external monitor or TV and there you go! You have what essentially amounts to a game console.</p>
<p>Someone said : &#8220;if Angry Birds does not run on your system, you don’t have a platform&#8221;. Well <a href="http://apps.microsoft.com/webpdp/fr-fr/app/angry-birds-space/8ece2571-91e0-4f2f-b7e5-b0b7944ced2d">Angry Birds</a> is there… </p>
<p>The truth is, <a href="http://blogs.windows.com/windows/b/windowsexperience/archive/2012/08/31/first-wave-of-xbox-games-for-windows-8-unveiled.aspx">a fairly large selection of games</a> are available since launch, and more are coming along the way.</p>
<p>Mapping a network folder is also a good scenario, whereby a user will be able to quickly access his or her content, stored on another home computer or network drive.</p>
<p>Even though the “Surface RT” is intended to be used by casual users and students, in this day and age of “BYOD” – <em>Bring your own device</em> – a lot of people would want to make use of their tablet for business purposes while on the go.</p>
<p>What, for instance, if you receive a ZIP file, containing slides for a business presentation that you need to make last-minute adjustments to? Just save the ZIP attachment somewhere on the file system, drop to the Desktop and fire up PowerPoint. You can make edits and modifications using the integrated Touch Cover all you want, no problem there… How about trying that on an iPad?</p>
<p>For more advanced usage, you can use any of the included remote desktop clients – on the Desktop or as a Modern UI App – and have access to virtually all corporate workstations and servers. </p>
<p>Out of the box.</p>
<p><span style="font-family:Tahoma;font-weight:bold;">So, who is Windows RT for?</span></p>
<p>So is it for everybody? Let’s put it this way : is a single product for everybody? It never is, that’s a fact of life. In that same way, Windows RT is probably not for everybody.</p>
<p>But, my view is that all the different versions of <em><strong>“Windows 8” and all the different hardware combinations it runs on have a vastly greater intended audience than any of their competitors</strong></em>.</p>
<p>Is the iPad for everyone? Its price alone makes it a premium product, which, by definition, is not for everyone. Some want more expansion ports or connectivity options. Some want more compatibility with standards or existing hardware products – Lightning Connector, anyone?</p>
<p>Again, is an Android tablet for everyone? Perhaps not. Some want a more streamlined and homogeneous user interface. Some do not tolerate even a slight lag when swiping user interface elements.</p>
<p>The truth is, <em><strong>Windows 8 is not a single product</strong></em>. It’s actually many different products, all sharing the same central, touch-based, Windows Store-distributed, Modern UI “fast and fluid” immersive Apps. And each one of these different products is targeting a different segment of the market.</p>
<p>With Windows 8 and Windows RT, chances are you’ll find one combination that’s right for you.</p>
<p>So, there you have it. A quick review of the last few days using the Surface for Windows RT. I have strived to give you a fair and balanced point of view. Please, leave comments, suggestions for improvements or requests for thing I may have missed. But please, keep the comments polite and civilized. </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maximelabelle.wordpress.com/519/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maximelabelle.wordpress.com/519/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&#038;blog=16599311&#038;post=519&#038;subd=maximelabelle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maximelabelle.wordpress.com/2012/11/01/my-review-of-the-microsoft-surface-for-windows-rt/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/957e1e828557735f52843d3c69f29b1e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maximelabelle</media:title>
		</media:content>

		<media:content url="http://maximelabelle.files.wordpress.com/2012/11/surface-for-windows-rt.png" medium="image">
			<media:title type="html">Surface for Windows RT Packaging</media:title>
		</media:content>
	</item>
		<item>
		<title>IISConfigurator stopped working</title>
		<link>http://maximelabelle.wordpress.com/2012/10/08/iisconfigurator-stopped-working/</link>
		<comments>http://maximelabelle.wordpress.com/2012/10/08/iisconfigurator-stopped-working/#comments</comments>
		<pubDate>Mon, 08 Oct 2012 07:56:35 +0000</pubDate>
		<dc:creator>Maxime Labelle</dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Windows Azure]]></category>

		<guid isPermaLink="false">http://maximelabelle.wordpress.com/?p=503</guid>
		<description><![CDATA[In the past few months, I&#8217;ve worked on a large project involving the design and implementation of a SaaS offering powered by Windows Azure. The learning curve was quite steep but I think I have become more confortable over time &#8230; <a href="http://maximelabelle.wordpress.com/2012/10/08/iisconfigurator-stopped-working/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&#038;blog=16599311&#038;post=503&#038;subd=maximelabelle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>In the past few months, I&#8217;ve worked on a large project involving the design and implementation of a SaaS offering powered by Windows Azure. The learning curve was quite steep  but I think I have become more confortable over time and can now make sensible choices for my design and architectures.</p>
<p>Anyways, using Windows Server 2012 and Visual Studio 2012 exclusively for the past few weeks, one of the first error I encountered was an unexpected crash when starting a Cloud Service in the Development Environment. Even though the role instances start and execute successfully, there&#8217;s always this nagging error below:</p>
<p style="text-align:center;"><img src="http://maximelabelle.files.wordpress.com/2012/10/iisconfigurator_crash.png?w=640"></p>
<p>As it turns out, this seems to be a rather <a Href="http://flummox-engineering.blogspot.fr/2012/07/iisconfiguratorexe.html">known error</a>, due to the ASP.Net application expecting IIS 7.0 instead of the new IIS 8.0 version that ships with Windows Server 2012. The solution is rather simple, as you need to install the IIS Management Console feature to make this error go away.</p>
<pre style="font-family:'Courier New', 'Consolas';background-color:#012456;color:White;">
PS&gt; Add-WindowsFeature Web-Mgmt-Console

Success Restart Needed Exit Code      Feature Result
------- -------------- ---------      --------------
True    No             Success        {IIS Management Console, Management Tools}
PS&gt;
</pre>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maximelabelle.wordpress.com/503/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maximelabelle.wordpress.com/503/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&#038;blog=16599311&#038;post=503&#038;subd=maximelabelle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maximelabelle.wordpress.com/2012/10/08/iisconfigurator-stopped-working/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/957e1e828557735f52843d3c69f29b1e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maximelabelle</media:title>
		</media:content>

		<media:content url="http://maximelabelle.files.wordpress.com/2012/10/iisconfigurator_crash.png" medium="image" />
	</item>
		<item>
		<title>Creating Strongly-Typed C# Event Tracing for Windows (ETW) Assemblies with Visual Studio</title>
		<link>http://maximelabelle.wordpress.com/2012/09/05/creating-strongly-typed-c-event-tracing-for-windows-etw-assemblies-with-visual-studio/</link>
		<comments>http://maximelabelle.wordpress.com/2012/09/05/creating-strongly-typed-c-event-tracing-for-windows-etw-assemblies-with-visual-studio/#comments</comments>
		<pubDate>Wed, 05 Sep 2012 11:34:22 +0000</pubDate>
		<dc:creator>Maxime Labelle</dc:creator>
				<category><![CDATA[ETW]]></category>
		<category><![CDATA[Event]]></category>
		<category><![CDATA[EventLog]]></category>
		<category><![CDATA[Tracing]]></category>

		<guid isPermaLink="false">http://maximelabelle.wordpress.com/?p=466</guid>
		<description><![CDATA[The Event Tracing for Windows (ETW) Framework is a high-performance logging subsystem of Windows available to kernel-mode and user-mode developers for instrumenting mission critical and large scale applications. Starting with Windows Vista, ETW is the foundation for instrumenting many components &#8230; <a href="http://maximelabelle.wordpress.com/2012/09/05/creating-strongly-typed-c-event-tracing-for-windows-etw-assemblies-with-visual-studio/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&#038;blog=16599311&#038;post=466&#038;subd=maximelabelle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>The <a href="http://msdn.microsoft.com/en-us/magazine/cc163437.aspx" title="Event Tracing for Windows (ETW)">Event Tracing for Windows</a> (ETW) Framework is a high-performance logging subsystem of Windows available to kernel-mode and user-mode developers for instrumenting mission critical and large scale applications.</p>
<p>Starting with Windows Vista, ETW is the foundation for instrumenting many components of Windows, including the Windows Event Log.</p>
<p>For this reason, ETW is primarily meant to be used from native code and the support tools and associated APIs are geared towards C++ developers. For a long time, there was no easy or straightforward way to instrument ones&#8217;s own managed application for ETW. However, things are starting to change.</p>
<p>The <a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.eventing(v=vs.100).aspx" title="The System.Diagnostics.Eventing Namespace">System.Diagnostics.Eventing</a> namespace in the .Net 3.5 Framework has brought developers basic support for using ETW by wrapping core structures and APIs. With this support, it&#8217;s relatively easy to build a managed wrapper around logging and tracing. However, one still needs to declare and maintain the event structures themselves in an XML instrumentation manifest file. Surely, things will get even easier with and improved and streamlined support in the upcoming 4.5 version of the .Net framework.</p>
<p>If you ever wanted to add ETW support to your application, you might have stumbled upon <a href="http://www.atrevido.net/blog/2008/02/28/Writing+Events+With+SystemDiagnosticsEventing.aspx" title="Writing ETW Events from Managed Code">this post</a> where the author has made some efforts to bridge the gap between the native way and the .net way of using the tooling necessary to make use of ETW. And you might have walked away and reverted to using plain old vanilla Trace.WriteLine statements in your code&#8230; I know I nearly have !</p>
<p>Fear not ! In this post, I would like to walk you through a quick and easy way for using ETW in your managed application directly from Visual Studio. The solution involves using the proper tooling in an automated and integrated way so as to make it a very streamlined operation from the developer&#8217;s standpoint.</p>
<p><span style="font-family:Tahoma;font-weight:bold;">A Quick Recap</span></p>
<p>But, first, let&#8217;s recap what needs to be done for proper usage of ETW:</p>
<p><strong>a) At design-time:</strong></p>
<ul>
<li>First, you need to declare and maintain the event and message structures in an <em><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd996930(v=vs.85).aspx">Instrumentation Manifest</a></em> file. This is cumbersome but, in fact, quite easy, thanks to the Manifest Generator (ecmangen.exe) authoring utility from the Windows SDK.
<li>Second, you need to create a C# managed class for wrapping those event and message structures in your code. Again, this is straightforward, since the Message Compiler (mc.exe) tool includes a couple of switches to generated a C# source-code file for this purpose.
<li>Third, you need to embed a binary representation of the Instrumentation Manifest, known as a Message File, as a Win32 resource in your assembly. This requires, yet again, the use of the Message Compiler (mc.exe) tool &#8211; in order to produce a Resource Script (.rc) file &#8211; followed by the Resource Compiler (rc.exe) tool in order to create a Win32 resource (.res) file. This, in turn, gets embedded in a managed assembly by specifying the resource file in the project properties and tweaking the compiler switches in order to allow the compilation of unsafe code.
</ul>
<p>In fact, these are a lot of steps, but, once you have created and authored the Instrumentation Manifest file, all of them can be automated. This is what I&#8217;m going to show you now.</p>
<p><span style="font-family:Tahoma;font-weight:bold;">Creating a Managed Wrapper Visual Studio Project</span></p>
<p>In essence, Visual Studio C# Project (.csproj) files are MSBuild-based XML files. This means that we can leverage the extensibility of MSBuild to perform the necessary steps by slightly modifying the project files. As an added bonus, such modified projects can also be built from the command-line or from a TFS build server.</p>
<p><img src="http://maximelabelle.files.wordpress.com/2012/09/managed_visual_studio_etw_wrapper_project.png?w=640" alt="Managed ETW Wrapper Project in Visual Studio" /></p>
<p>In my proposal, a developer creates a regular C# project and includes the Instrumentation Manifest XML file. Then, the developer needs to perform a one-time modification to the project, that consists in changing the build action associated with the manifest to <em>InstrumentationManifest</em> and add an import statement, at the end of the project file, referring to an external .targets MSBuild file in which all the required logic will be centralized.</p>
<p>In practice, here how it looks like, in Visual Studio:</p>
<pre style="border:#cecece 1px solid;background-color:#fbfbfb;width:100%;font-family:consolas, 'Courier New', courier, monospace;font-size:12px;margin:0;padding:5px 1em;">
A regular C# project file that has been modified to include support for
compiling an ETW Instrumentation Manifest file.
</pre>
<p>In fact, adding an import statement at the end of the file is the only manual modification required, for it will point to an external MSBuild .targets file where the custom <em>InstrumentationManifest</em> Build Action is registered. So, associating the Instrumentation Manifest to the appropriate Build Action can be done within Visual Studio when the project file is reloaded.</p>
<p>Once that&#8217;s done, the project behaves just like any regular C# project. It produces a managed assembly. It understands the Build, ReBuild and Clean actions. It even takes advantage of incremental compilation, in order to only perform the necessary actions when required. Finally, it can be referenced from other projects without any side effects. For all intents and purposes, it <em>is</em> a regular C# project file.</p>
<p><span style="font-family:Tahoma;font-weight:bold;">A Custom MSBuild Project for Supporting ETW from Managed Code</span></p>
<p>Here, I will show the structure and content of a custom MSBuild .targets Project that can be imported into any regular C# project file in order to include support for compiling ETW Instrumentation Manifest files into a strongly-typed C# managed wrapper:</p>
<pre style="border:#cecece 1px solid;background-color:#fbfbfb;width:100%;font-family:consolas, 'Courier New', courier, monospace;font-size:12px;margin:0;padding:5px 1em;">
<span style='color:blue;'>&lt;</span><span style='color:maroon;'>Project</span><span style='color:blue;'> </span><span style='color:red;'>InitialTargets</span><span style='color:blue;'>=</span><span>&quot;<span style='color:blue;'>_InitialTarget</span>&quot;<span style='color:blue;'> </span><span style='color:red;'>xmlns</span><span style='color:blue;'>=</span>&quot;<span style='color:blue;'>http://schemas.microsoft.com/developer/msbuild/2003</span>&quot;<span style='color:blue;'>&gt;</span></span>

<span style='color:blue;'><span> </span>&lt;!--</span><span style='color:green;'> Compiling ETW Instrumentation Manifest files requires Windows SDKtools </span><span style='color:blue;'>--&gt;</span>
<span style='color:blue;'><span> </span>&lt;</span><span style='color:maroon;'>PropertyGroup</span><span style='color:blue;'>&gt;</span>
<span style='color:blue;'><span>   </span>&lt;</span><span style='color:maroon;'>WindowsSdkDir</span><span style='color:blue;'> </span><span style='color:red;'>Condition</span><span style='color:blue;'>=</span><span>&quot;<span style='color:blue;'>'$(WindowsSdkDir)'=='' </span>&quot;<span style='color:blue;'>&gt;</span>C:\ProgramFiles (x86)\Microsoft SDKs\Windows\v7.0A\<span style='color:blue;'>&lt;/</span><span style='color:maroon;'>WindowsSdkDir</span><span style='color:blue;'>&gt;</span></span>
<span style='color:blue;'><span>   </span>&lt;</span><span style='color:maroon;'>RootNamespace</span><span style='color:blue;'> </span><span style='color:red;'>Condition</span><span style='color:blue;'>=</span><span>&quot;<span style='color:blue;'>'$(RootNamespace)'=='' </span>&quot;<span style='color:blue;'>&gt;</span>$(AssemblyName)<span style='color:blue;'>&lt;/</span><span style='color:maroon;'>RootNamespace</span><span style='color:blue;'>&gt;</span></span>
<span style='color:blue;'><span> </span>&lt;/</span><span style='color:maroon;'>PropertyGroup</span><span style='color:blue;'>&gt;</span>

<span style='color:blue;'><span> </span>&lt;!--</span><span style='color:green;'> _InitialTarget </span><span style='color:blue;'>--&gt;</span>
<span style='color:blue;'><span> </span>&lt;!--</span>
<span style='color:green;'><span> </span></span>
<span style='color:green;'><span>       </span>Normalizes the $(WindowsSdkDir) variable and retrieves the path tovarious SDK tools and dependent files.</span>
<span style='color:green;'><span>       </span></span>
<span style='color:green;'><span>       </span>Inputs:</span>
<span style='color:green;'><span>       </span>=======</span>
<span style='color:green;'><span>       </span>(none)</span>
<span style='color:green;'><span>       </span></span>
<span style='color:green;'><span>       </span>Outputs:</span>
<span style='color:green;'><span>       </span>========</span>
<span style='color:green;'><span>       </span>$(Win32MessageCompiler) : path to the Message Compiler (mc.exe) SDKutility</span>
<span style='color:green;'><span>       </span>$(Win32ResourceCompiler) : path to the Resource Compiler (rc.exe) SDKutility</span>
<span style='color:green;'><span>       </span>$(Win32InstrumentationMetadata) : path to the core ETW metadatadefinitions (winmeta.xml)</span>
<span style='color:green;'><span>       </span></span>
<span style='color:green;'><span> </span></span><span style='color:blue;'>--&gt;</span>
<span style='color:blue;'><span> </span>&lt;</span><span style='color:maroon;'>Target</span><span style='color:blue;'> </span><span style='color:red;'>Name</span><span style='color:blue;'>=</span><span>&quot;<span style='color:blue;'>_InitialTarget</span>&quot;<span style='color:blue;'>&gt;</span></span>
<span style='color:blue;'><span>   </span>&lt;</span><span style='color:maroon;'>PropertyGroup</span><span style='color:blue;'>&gt;</span>
<span style='color:blue;'><span>     </span>&lt;</span><span style='color:maroon;'>WindowsSdkDir</span><span style='color:blue;'> </span><span style='color:red;'>Condition</span><span style='color:blue;'>=</span><span>&quot;<span style='color:blue;'>!HasTrailingSlash('$(WindowsSdkDir)') </span>&quot;<span style='color:blue;'>&gt;</span>$(WindowsSdkDir)\<span style='color:blue;'>&lt;/</span><span style='color:maroon;'>WindowsSdkDir</span><span style='color:blue;'>&gt;</span></span>
<span style='color:blue;'><span>     </span>&lt;</span><span style='color:maroon;'>Win32MessageCompiler</span><span style='color:blue;'> </span><span style='color:red;'>Condition</span><span style='color:blue;'>=</span><span>&quot;<span style='color:blue;'>Exists('$(WindowsSdkDir)bin\mc.exe') </span>&quot;<span style='color:blue;'>&gt;</span>$(WindowsSdkDir)bin\mc.exe<span style='color:blue;'>&lt;/</span><span style='color:maroon;'>Win32MessageCompiler</span><span style='color:blue;'>&gt;</span></span>
<span style='color:blue;'><span>     </span>&lt;</span><span style='color:maroon;'>Win32ResourceCompiler</span><span style='color:blue;'> </span><span style='color:red;'>Condition</span><span style='color:blue;'>=</span><span>&quot;<span style='color:blue;'>Exists('$(WindowsSdkDir)bin\rc.exe') </span>&quot;<span style='color:blue;'>&gt;</span>$(WindowsSdkDir)bin\rc.exe<span style='color:blue;'>&lt;/</span><span style='color:maroon;'>Win32ResourceCompiler</span><span style='color:blue;'>&gt;</span></span>
<span style='color:blue;'><span>     </span>&lt;</span><span style='color:maroon;'>Win32InstrumentationMetadata</span><span style='color:blue;'> </span><span style='color:red;'>Condition</span><span style='color:blue;'>=</span><span>&quot;<span style='color:blue;'>Exists('$(WindowsSdkDir)include\winmeta.xml') </span>&quot;<span style='color:blue;'>&gt;</span>$(WindowsSdkDir)include\winmeta.xml<span style='color:blue;'>&lt;/</span><span style='color:maroon;'>Win32InstrumentationMetadata</span><span style='color:blue;'>&gt;</span></span>
<span style='color:blue;'><span>   </span>&lt;/</span><span style='color:maroon;'>PropertyGroup</span><span style='color:blue;'>&gt;</span>
<span style='color:blue;'><span> </span>&lt;/</span><span style='color:maroon;'>Target</span><span style='color:blue;'>&gt;</span>

</pre>
<p>
First, some bookkeeping. Compiling ETW Intrumentation Manifests requires tools from the Windows SDK, so references to the various tools are established into a set of corresponding properties. The <em>_InitialTarget</em> is run first, in order to setup those properties before any other processing.</p>
<p><pre style="border:#cecece 1px solid;background-color:#fbfbfb;width:100%;font-family:consolas, 'Courier New', courier, monospace;font-size:12px;margin:0;padding:5px 1em;">
<span style='color:blue;'><span> </span>&lt;!--</span><span style='color:green;'> _ComputeIntrumentationManifestResource </span><span style='color:blue;'>--&gt;</span>
<span style='color:blue;'><span> </span>&lt;!--</span>
<span style='color:green;'><span> </span></span>
<span style='color:green;'><span>       </span>Calculates the paths (location) to the resulting .res resource file andassociated strongly-typed .cs file.</span>

<span style='color:green;'><span>       </span>Input ItemGroup:</span>
<span style='color:green;'><span>       </span>================</span>
<span style='color:green;'><span>       </span>@(InstrumentationManifest) : path to the XML Instrumentation Manifest(.man) file</span>
<span style='color:green;'><span>       </span></span>
<span style='color:green;'><span>       </span>Output ItemGroups:</span>
<span style='color:green;'><span>       </span>==================</span>
<span style='color:green;'><span>       </span>@(InstrumentationManifestResource) : path to the resulting compiledwin32 resource (.res) file</span>
<span style='color:green;'><span>       </span>@(EventProviderSource) : path to the resulting strongly-typed managedwrapper class (.cs) file</span>
<span style='color:green;'><span> </span></span>
<span style='color:green;'><span> </span></span><span style='color:blue;'>--&gt;</span>
<span style='color:blue;'><span> </span>&lt;</span><span style='color:maroon;'>Target</span><span style='color:blue;'> </span><span style='color:red;'>Name</span><span style='color:blue;'>=</span><span>&quot;<span style='color:blue;'>_ComputeInstrumentationManifestResource</span>&quot;<span style='color:blue;'>&gt;</span></span>
<span style='color:blue;'><span>   </span>&lt;</span><span style='color:maroon;'>ItemGroup</span><span style='color:blue;'>&gt;</span>
<span style='color:blue;'><span>     </span>&lt;</span><span style='color:maroon;'>InstrumentationManifestResource</span><span style='color:blue;'> </span><span style='color:red;'>Remove</span><span style='color:blue;'>=</span><span>&quot;<span style='color:blue;'>@(InstrumentationManifestResource)</span>&quot;<span style='color:blue;'> /&gt;</span></span>
<span style='color:blue;'><span>     </span>&lt;</span><span style='color:maroon;'>InstrumentationManifestResource</span><span style='color:blue;'> </span><span style='color:red;'>Include</span><span style='color:blue;'>=</span><span>&quot;<span style='color:blue;'>@(InstrumentationManifest-&gt;'$(IntermediateOutputPath)res\%(Filename).res')</span>&quot;<span style='color:blue;'> /&gt;</span></span>
<span style='color:blue;'><span>   </span>&lt;/</span><span style='color:maroon;'>ItemGroup</span><span style='color:blue;'>&gt;</span>
<span style='color:blue;'><span>   </span>&lt;</span><span style='color:maroon;'>ItemGroup</span><span style='color:blue;'>&gt;</span>
<span style='color:blue;'><span>     </span>&lt;</span><span style='color:maroon;'>EventProviderSource</span><span style='color:blue;'> </span><span style='color:red;'>Remove</span><span style='color:blue;'>=</span><span>&quot;<span style='color:blue;'>@(EventProviderSource)</span>&quot;<span style='color:blue;'> /&gt;</span></span>
<span style='color:blue;'><span>     </span>&lt;</span><span style='color:maroon;'>EventProviderSource</span><span style='color:blue;'> </span><span style='color:red;'>Include</span><span style='color:blue;'>=</span><span>&quot;<span style='color:blue;'>@(InstrumentationManifest-&gt;'%(RootDir)%(Directory)%(Filename).cs')</span>&quot;<span style='color:blue;'> /&gt;</span></span>
<span style='color:blue;'><span>   </span>&lt;/</span><span style='color:maroon;'>ItemGroup</span><span style='color:blue;'>&gt;</span>
<span style='color:blue;'><span> </span>&lt;/</span><span style='color:maroon;'>Target</span><span style='color:blue;'>&gt;</span>
<span style='color:blue;'><span>  </span></span>
<span style='color:blue;'><span> </span>&lt;!--</span><span style='color:green;'> _CreateInstrumentationManifestResource </span><span style='color:blue;'>--&gt;</span>
<span style='color:blue;'><span> </span>&lt;!--</span>
<span style='color:green;'><span> </span></span>
<span style='color:green;'><span>       </span>Compiles the resulting .res resource file.</span>
<span style='color:green;'><span>       </span>The win32 resource (.res) file is located in an intermediate outputpath.</span>
<span style='color:green;'><span>       </span>Leverages incremental compilation (i.e. only performs compilation ifrequired.)</span>

<span style='color:green;'><span>       </span>Inputs:</span>
<span style='color:green;'><span>       </span>================</span>
<span style='color:green;'><span>       </span>@(InstrumentationManifest) : path to the XML Instrumentation Manifest(.man) file</span>
<span style='color:green;'><span>       </span></span>
<span style='color:green;'><span>       </span>Outputs</span>
<span style='color:green;'><span>       </span>==================</span>
<span style='color:green;'><span>       </span>@(InstrumentationManifestResource) : path to the resulting compiledwin32 resource (.res) file</span>
<span style='color:green;'><span> </span></span>
<span style='color:green;'><span> </span></span><span style='color:blue;'>--&gt;</span>
<span style='color:blue;'><span> </span>&lt;</span><span style='color:maroon;'>Target</span><span style='color:blue;'> </span><span style='color:red;'>Name</span><span style='color:blue;'>=</span><span>&quot;<span style='color:blue;'>_CreateInstrumentationManifestResource</span>&quot;<span style='color:blue;'> </span><span style='color:red;'>Inputs</span><span style='color:blue;'>=</span>&quot;<span style='color:blue;'>@(InstrumentationManifest)</span>&quot;<span style='color:blue;'> </span><span style='color:red;'>Outputs</span><span style='color:blue;'>=</span>&quot;<span style='color:blue;'>@(InstrumentationManifest-&gt;'$(IntermediateOutputPath)res\%(Filename).res')</span>&quot;<span style='color:blue;'>&gt;</span></span>
<span style='color:blue;'><span>   </span>&lt;</span><span style='color:maroon;'>MakeDir</span><span style='color:blue;'> </span><span style='color:red;'>Condition</span><span style='color:blue;'>=</span><span>&quot;<span style='color:blue;'>!Exists('$(IntermediateOutputPath)res') </span>&quot;<span style='color:blue;'> </span><span style='color:red;'>Directories</span><span style='color:blue;'>=</span>&quot;<span style='color:blue;'>$(IntermediateOutputPath)res</span>&quot;<span style='color:blue;'> /&gt;</span></span>
<span style='color:blue;'><span>   </span>&lt;</span><span style='color:maroon;'>Exec</span><span style='color:blue;'> </span><span style='color:red;'>Command</span><span style='color:blue;'>=</span><span>&quot;<span style='color:red;'>&amp;quot;</span><span style='color:blue;'>$(Win32MessageCompiler)</span><span style='color:red;'>&amp;quot;</span><span style='color:blue;'> -W </span><span style='color:red;'>&amp;quot;</span><span style='color:blue;'>$(Win32InstrumentationMetadata)</span><span style='color:red;'>&amp;quot;</span><span style='color:blue;'> </span><span style='color:red;'>&amp;quot;</span><span style='color:blue;'>@(InstrumentationManifest)</span><span style='color:red;'>&amp;quot;</span><span style='color:blue;'> -h </span><span style='color:red;'>&amp;quot;</span><span style='color:blue;'>$(IntermediateOutputPath)res</span><span style='color:red;'>&amp;quot;</span><span style='color:blue;'> -r </span><span style='color:red;'>&amp;quot;</span><span style='color:blue;'>$(IntermediateOutputPath)res</span><span style='color:red;'>&amp;quot;</span>&quot;<span style='color:blue;'> /&gt;</span></span>
<span style='color:blue;'><span>   </span>&lt;</span><span style='color:maroon;'>Exec</span><span style='color:blue;'> </span><span style='color:red;'>Command</span><span style='color:blue;'>=</span><span>&quot;<span style='color:red;'>&amp;quot;</span><span style='color:blue;'>$(Win32ResourceCompiler)</span><span style='color:red;'>&amp;quot;</span><span style='color:blue;'> -nologo -r </span><span style='color:red;'>&amp;quot;</span><span style='color:blue;'>@(InstrumentationManifest-&gt;'$(IntermediateOutputPath)res\%(Filename).res')</span><span style='color:red;'>&amp;quot;</span>&quot;<span style='color:blue;'> /&gt;</span></span>
<span style='color:blue;'><span> </span>&lt;/</span><span style='color:maroon;'>Target</span><span style='color:blue;'>&gt;</span>

<span style='color:blue;'><span> </span>&lt;!--</span><span style='color:green;'> _CreateEventProviderSourceFile </span><span style='color:blue;'>--&gt;</span>
<span style='color:blue;'><span> </span>&lt;!--</span>
<span style='color:green;'><span> </span></span>
<span style='color:green;'><span>       </span>Generates the resulting strongly-typed managed EventProvider wrapper.</span>
<span style='color:green;'><span>       </span>The strongly-typed C# managed wrapper class (.cs) file is located at the root of the project.</span>
<span style='color:green;'><span>       </span>Leverages incremental compilation (i.e. only performs generation if required.)</span>

<span style='color:green;'><span>       </span>Inputs:</span>
<span style='color:green;'><span>       </span>================</span>
<span style='color:green;'><span>      </span><span> </span>@(InstrumentationManifest) : pathto the XML Instrumentation Manifest (.man) file</span>
<span style='color:green;'><span>       </span></span>
<span style='color:green;'><span>       </span>Outputs</span>
<span style='color:green;'><span>       </span>==================</span>
<span style='color:green;'><span>       </span>@(EventProviderSource) : path to the resulting strongly-typed managed wrapper class (.cs) file</span>
<span style='color:green;'><span> </span></span>
<span style='color:green;'><span> </span></span><span style='color:blue;'>--&gt;</span>
<span style='color:blue;'><span> </span>&lt;</span><span style='color:maroon;'>Target</span><span style='color:blue;'> </span><span style='color:red;'>Name</span><span style='color:blue;'>=</span><span>&quot;<span style='color:blue;'>_CreateEventProviderSourceFile</span>&quot;<span style='color:blue;'> </span><span style='color:red;'>Inputs</span><span style='color:blue;'>=</span>&quot;<span style='color:blue;'>@(InstrumentationManifest)</span>&quot;<span style='color:blue;'> </span><span style='color:red;'>Outputs</span><span style='color:blue;'>=</span>&quot;<span style='color:blue;'>@(InstrumentationManifest-&gt;'%(RootDir)%(Directory)%(Filename).cs')</span>&quot;<span style='color:blue;'>&gt;</span></span>
<span style='color:blue;'><span>   </span>&lt;</span><span style='color:maroon;'>Exec</span><span style='color:blue;'> </span><span style='color:red;'>Command</span><span style='color:blue;'>=</span><span>&quot;<span style='color:red;'>&amp;quot;</span><span style='color:blue;'>$(Win32MessageCompiler)</span><span style='color:red;'>&amp;quot;</span><span style='color:blue;'> -cs $(RootNamespace) </span><span style='color:red;'>&amp;quot;</span><span style='color:blue;'>@(InstrumentationManifest)</span><span style='color:red;'>&amp;quot;</span><span style='color:blue;'> -r </span><span style='color:red;'>&amp;quot;</span><span style='color:blue;'>$(IntermediateOutputPath)res</span><span style='color:red;'>&amp;quot;</span>&quot;<span style='color:blue;'> /&gt;</span></span>
<span style='color:blue;'><span> </span>&lt;/</span><span style='color:maroon;'>Target</span><span style='color:blue;'>&gt;</span>

</pre>
<p>
Then, three simple targets, each one associated with a single responsibility.</p>
<p>The <em>_ComputeInstrumentationManifestResource</em> target creates some meaningful ItemGroup created as part of the processing below. This simplifies writing subsequent targets. As you see, the resulting Win32 resource (.res) file is created under a res subdirectory of the intermediate output path and has the same base file name as the Instrumentation Manifest. Likewise, the EventProvider source file has the same base file name as the Manifest and is created in the project root.</p>
<p>The <em>_CreateInstrumentationManifestResource</em> target runs the Message Compiler (mc.exe) and Resource Compiler (rc.exe) tools in sequence, in order to create a binary representation of the manifest as a Win32 resource (.res) file.</p>
<p>The <em>_CreateEventProviderSourceFile</em> target runs the Message Compiler (mc.exe) tool in order to create a strongly-types C# managed wrapper class for an ETW EventProvider object.</p>
<p>Both targets take advantage of MSBuild support for incremental compilation. By comparing the timestamps of the generated artifacts relative to that of the Instrumentation Manifest, the processing only happens when necessary. Those targets are specified as dependencies of the <em>BeforeCompile</em> target, shown below, in order to trigger the actual custom processing.</p>
<p><pre style="border:#cecece 1px solid;background-color:#fbfbfb;width:100%;font-family:consolas, 'Courier New', courier, monospace;font-size:12px;margin:0;padding:5px 1em;">
<span style='color:blue;'><span> </span>&lt;!--</span><span style='color:green;'> BeforeCompile </span><span style='color:blue;'>--&gt;</span>
<span style='color:blue;'><span> </span>&lt;!--</span>
<span style='color:green;'><span> </span></span>
<span style='color:green;'><span>       </span>Overrides the BeforeCompile MSBuild extension point in order to generated files and alter compiler flags.</span>
<span style='color:green;'><span> </span></span>
<span style='color:green;'><span> </span></span><span style='color:blue;'>--&gt;</span>
<span style='color:blue;'><span> </span>&lt;</span><span style='color:maroon;'>Target</span><span style='color:blue;'> </span><span style='color:red;'>Name</span><span style='color:blue;'>=</span><span>&quot;<span style='color:blue;'>BeforeCompile</span>&quot;<span style='color:blue;'> </span><span style='color:red;'>DependsOnTargets</span><span style='color:blue;'>=</span>&quot;<span style='color:blue;'>_ComputeInstrumentationManifestResource;_CreateInstrumentationManifestResource;_CreateEventProviderSourceFile</span>&quot;<span style='color:blue;'>&gt;</span></span>
<span style='color:blue;'><span>   </span>&lt;</span><span style='color:maroon;'>Message</span><span style='color:blue;'> </span><span style='color:red;'>Text</span><span style='color:blue;'>=</span><span>&quot;<span style='color:blue;'>Createstrongly-typed ETW assembly from specified instrumentation manifest...</span>&quot;<span style='color:blue;'> /&gt;</span></span>
<span style='color:blue;'><span>   </span>&lt;</span><span style='color:maroon;'>PropertyGroup</span><span style='color:blue;'>&gt;</span>
<span style='color:blue;'><span>     </span>&lt;</span><span style='color:maroon;'>AllowUnsafeBlocks</span><span style='color:blue;'>&gt;</span><span>true<span style='color:blue;'>&lt;/</span><span style='color:maroon;'>AllowUnsafeBlocks</span><span style='color:blue;'>&gt;</span></span>
<span style='color:blue;'><span>     </span>&lt;</span><span style='color:maroon;'>Win32Resource</span><span style='color:blue;'>&gt;</span><span>@(InstrumentationManifestResource-&gt;'%(Identity)')<span style='color:blue;'>&lt;/</span><span style='color:maroon;'>Win32Resource</span><span style='color:blue;'>&gt;</span></span>
<span style='color:blue;'><span>   </span>&lt;/</span><span style='color:maroon;'>PropertyGroup</span><span style='color:blue;'>&gt;</span>
<span style='color:blue;'><span>   </span>&lt;</span><span style='color:maroon;'>ItemGroup</span><span style='color:blue;'>&gt;</span>
<span style='color:blue;'><span>     </span>&lt;</span><span style='color:maroon;'>Compile</span><span style='color:blue;'> </span><span style='color:red;'>Include</span><span style='color:blue;'>=</span><span>&quot;<span style='color:blue;'>@(EventProviderSource-&gt;'%(Identity)')</span>&quot;<span style='color:blue;'> /&gt;</span></span>
<span style='color:blue;'><span>   </span>&lt;/</span><span style='color:maroon;'>ItemGroup</span><span style='color:blue;'>&gt;</span>
<span style='color:blue;'><span>   </span>&lt;</span><span style='color:maroon;'>Message</span><span style='color:blue;'> </span><span style='color:red;'>Text</span><span style='color:blue;'>=</span><span>&quot;<span style='color:blue;'>@(Compile)</span>&quot;<span style='color:blue;'> /&gt;</span></span>
<span style='color:blue;'><span> </span>&lt;/</span><span style='color:maroon;'>Target</span><span style='color:blue;'>&gt;</span>

</pre>
<p>The MSBuild <em>BeforeCompile</em> target is then overridden and performs the following actions:</p>
<ul>
<li>Its dependencies trigger the custom generation of the C# EventProvider source file and compilation of the win32 binary resource, shown above.
<li>The <em>@(Compile)</em> ItemGroup is modified to include the newly generated EventProvider source file.
<li>The <em>/unsafe</em> compiler switches is turned on, in order to allow the compilation of unsafe code.
<li>The <em>/win32res</em> compiler flag is specified with the location of the generated binary Win32 resource Message File.
</ul>
<pre style="border:#cecece 1px solid;background-color:#fbfbfb;width:100%;font-family:consolas, 'Courier New', courier, monospace;font-size:12px;margin:0;padding:5px 1em;">
<span style='color:blue;'><span> </span>&lt;!--</span><span style='color:green;'> AfterClean </span><span style='color:blue;'>--&gt;</span>
<span style='color:blue;'><span> </span>&lt;!--</span>
<span style='color:green;'><span> </span></span>
<span style='color:green;'><span>       </span>Overrides the AfterClean MSBuild extension point in order to clean generated files.</span>
<span style='color:green;'><span> </span></span>
<span style='color:green;'><span> </span></span><span style='color:blue;'>--&gt;</span>
<span style='color:blue;'><span> </span>&lt;</span><span style='color:maroon;'>Target</span><span style='color:blue;'> </span><span style='color:red;'>Name</span><span style='color:blue;'>=</span><span>&quot;<span style='color:blue;'>AfterClean</span>&quot;<span style='color:blue;'> </span><span style='color:red;'>DependsOnTargets</span><span style='color:blue;'>=</span>&quot;<span style='color:blue;'>_ComputeInstrumentationManifestResource</span>&quot;<span style='color:blue;'>&gt;</span></span>
<span style='color:blue;'><span>   </span>&lt;</span><span style='color:maroon;'>RemoveDir</span><span style='color:blue;'> </span><span style='color:red;'>Condition</span><span style='color:blue;'>=</span><span>&quot;<span style='color:blue;'>Exists('@(InstrumentationManifestResource-&gt;'%(RootDir)%(Directory)')') </span>&quot;<span style='color:blue;'> </span><span style='color:red;'>Directories</span><span style='color:blue;'>=</span>&quot;<span style='color:blue;'>@(InstrumentationManifestResource-&gt;'%(RootDir)%(Directory)')</span>&quot;<span style='color:blue;'> /&gt;</span></span>
<span style='color:blue;'><span>   </span>&lt;</span><span style='color:maroon;'>Delete</span><span style='color:blue;'> </span><span style='color:red;'>Condition</span><span style='color:blue;'>=</span><span>&quot;<span style='color:blue;'>Exists('@(EventProviderSource)') </span>&quot;<span style='color:blue;'> </span><span style='color:red;'>Files</span><span style='color:blue;'>=</span>&quot;<span style='color:blue;'>@(EventProviderSource)</span>&quot;<span style='color:blue;'>/&gt;</span></span>
<span style='color:blue;'><span> </span>&lt;/</span><span style='color:maroon;'>Target</span><span style='color:blue;'>&gt;</span>

</pre>
<p>Finally, in order to support the Clean action, the MSBuild <em>AfterClean</em> target is overridden to delete the generated artifacts.</p>
<p><span style="font-family:Tahoma;font-weight:bold;">Conclusion</span></p>
<p>In this post, I have focused on providing an automated and integrated way of using ETW from the perspective of a Visual Studio developer.</p>
<p>In order to produce ETW traces from one&#8217;s application, it is necessary to <a href="http://msdn.microsoft.com/en-us/library/cc432690(v=prot.10)" title="register the managed ETW provider">register the managed Event Provider</a> to the system at install-time (using wevtutil.exe) and <a href="http://blogs.msdn.com/b/sudeepg/archive/2009/02/25/capturing-and-analyzing-an-etw-trace-event-tracing-for-windows.aspx" title="Collecting and Analysing ETW Traces">collect and analyse the resulting traces</a> at run-time (using <a href="http://msdn.microsoft.com/en-us/library/ms751538.aspx" title="Using logman.exe">logman.exe</a>, <a href="http://msdn.microsoft.com/en-us/library/ms732023.aspx" title="Using SvcTraceView.exe">svctraceview.exe</a>, tracerpt.exe, xperf.exe, etc.) Please, refer to the articles I linked to, as well as <a href="http://social.msdn.microsoft.com/Forums/en/etw/thread/a1aa1350-41a0-4490-9ae3-9b4520aeb9d4" title="ETW and Event Log FAQ">this excellent ETW FAQ</a>, for more information&#8230;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maximelabelle.wordpress.com/466/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maximelabelle.wordpress.com/466/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&#038;blog=16599311&#038;post=466&#038;subd=maximelabelle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maximelabelle.wordpress.com/2012/09/05/creating-strongly-typed-c-event-tracing-for-windows-etw-assemblies-with-visual-studio/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/957e1e828557735f52843d3c69f29b1e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maximelabelle</media:title>
		</media:content>

		<media:content url="http://maximelabelle.files.wordpress.com/2012/09/managed_visual_studio_etw_wrapper_project.png" medium="image">
			<media:title type="html">Managed ETW Wrapper Project in Visual Studio</media:title>
		</media:content>
	</item>
		<item>
		<title>Unit-Testing Custom Inline Functoids with the CodeDOM</title>
		<link>http://maximelabelle.wordpress.com/2012/06/06/unit-testing-custom-inline-functoids-with-the-codedom/</link>
		<comments>http://maximelabelle.wordpress.com/2012/06/06/unit-testing-custom-inline-functoids-with-the-codedom/#comments</comments>
		<pubDate>Wed, 06 Jun 2012 20:27:45 +0000</pubDate>
		<dc:creator>Maxime Labelle</dc:creator>
				<category><![CDATA[BizTalk]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://maximelabelle.wordpress.com/?p=444</guid>
		<description><![CDATA[As far as extending the BizTalk Mapper, custom inline functoids are probably one of the easiest ways. This particular types of functoids are what I called design-time functoids in the sense that they are only required to be made available &#8230; <a href="http://maximelabelle.wordpress.com/2012/06/06/unit-testing-custom-inline-functoids-with-the-codedom/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&#038;blog=16599311&#038;post=444&#038;subd=maximelabelle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>As far as extending the BizTalk Mapper, <a href="http://msdn.microsoft.com/en-us/library/aa559855.aspx">custom inline functoids</a><br />
are probably one of the easiest ways. This particular types of functoids are what I called <em>design-time</em> functoids in the sense<br />
that they are only required to be made available to Visual Studio. Once dropped on the design surface, they are responsible for emitting<br />
code that gets embedded inside the assembly once compiled.</p>
<p>In order to do that, custom inline functoids are C# classes that typically implement a <span style="font-family:'Courier New';"><a href="http://msdn.microsoft.com/en-us/library/microsoft.biztalk.basefunctoids.basefunctoid.getinlinescriptbuffer(v=bts.10).aspx">GetInlineScriptBuffer</a></span><br />
method to return a chunk of code during compilation.</p>
<p>However, as the MSDN documentation referred to above states, custom inline functoids can be challenging to test. Indeed, the documentation suggests to either carefully inspect the resulting XSLT code or verify the input and output of a map that makes use of the particular functoid you want to test.</p>
<p><span style="font-family:Tahoma;font-weight:bold;">The TDD-way of Developing Custom Inline Functoids</span></p>
<p>As a fan of the <a href="http://en.wikipedia.org/wiki/Test_Driven_Development">Test-Driven Development</a> process, I wanted a cleaner, more robust way to test the chunk of code that gets emitted as part of the <span style="font-family:'Courier New';">GetInlineScriptBuffer</span> method.</p>
<p>Ideally, it should be possible to test the very same code that the <span style="font-family:'Courier New';">GetInlineScriptBuffer</span> method returns without risking modifying the code by <em>cutting</em> and <em>pasting</em> and <em>escaping quotes</em> and <em>adding a bunch of StringBuilder.Append wrapping calls</em>!</p>
<p>Thanks to the power of the .net framework <a href="http://msdn.microsoft.com/en-us/library/y2k85ax6.aspx">CodeDOM</a> I thought one could find a way to test custom inline functoids in a way that is more integrated with my build process. Here is what I came up with:</p>
<p><span style="font-family:Tahoma;font-weight:bold;">A Simple Unit-Testing Helper Class</span></p>
<pre style="border:#cecece 1px solid;background-color:#fbfbfb;width:100%;font-family:consolas, 'Courier New', courier, monospace;font-size:12px;margin:0;padding:5px 1em;">
<span style="color:blue;">using</span> System.CodeDom.Compiler;
<span style="color:blue;">using</span> System.Reflection;
<span style="color:blue;">using</span> Microsoft.CSharp;

<span style="color:blue;">class</span> TestHelper
{
    <span style="color:blue;">public</span> <span style="color:blue;">static</span> <span style="color:blue;">string</span> GetInlineScriptBuffer(<span style="color:blue;">string</span> typeName, <span style="color:blue;">int</span> numParams, <span style="color:blue;">int</span> functionNumber)
    {
        <span style="color:blue;">object</span>[] args = <span style="color:blue;">new</span> <span style="color:blue;">object</span>[] { Microsoft.BizTalk.BaseFunctoids.<span style="color:lightseagreen;">ScriptType</span>.CSharp, numParams, functionNumber };

        <span style="color:lightseagreen;">Type</span> type = <span style="color:lightseagreen;">Type</span>.GetType(typeName);
        <span style="color:blue;">object</span> target = <span style="color:lightseagreen;">Activator</span>.CreateInstance(type);

        <span style="color:blue;">return</span> (<span style="color:blue;">string</span>) type.InvokeMember(
            <span style="color:maroon;">"GetInlineScriptBuffer"</span>
            , BindingFlags.Instance
            | BindingFlags.NonPublic
            | BindingFlags.InvokeMethod
            , <span style="color:blue;">null</span>
            , target
            , args);
    }

    <span style="color:blue;">public</span> <span style="color:blue;">static</span> <span style="color:blue;">string</span> GenerateSourceCode(<span style="color:blue;">string</span> source)
    {
        <span style="color:lightseagreen;">StringBuilder</span> builder = <span style="color:blue;">new</span> <span style="color:lightseagreen;">StringBuilder</span>();

        builder.AppendLine(<span style="color:maroon;">"namespace Core.Functoids.UnitTests {"</span>);
        builder.AppendLine(<span style="color:maroon;">"using System;"</span>);
        builder.AppendLine(<span style="color:maroon;">"public class Test {"</span>);
        builder.Append(source);
        builder.AppendLine(<span style="color:maroon;">"}"</span>);
        builder.AppendLine(<span style="color:maroon;">"}"</span>);

        <span style="color:blue;">return</span> builder.ToString();
    }

    <span style="color:blue;">public</span> <span style="color:blue;">static</span> <span style="color:lightseagreen;">Assembly</span> CreateAssembly(<span style="color:blue;">string</span> source)
    {
        <span style="color:lightseagreen;">CodeDomProvider</span> provider = <span style="color:blue;">new</span> <span style="color:lightseagreen;">CSharpCodeProvider</span>();

        <span style="color:lightseagreen;">CompilerParameters</span> options = <span style="color:blue;">new</span> <span style="color:lightseagreen;">CompilerParameters</span>();
        options.GenerateInMemory = <span style="color:blue;">true</span>;
        options.GenerateExecutable = <span style="color:blue;">false</span>;
        options.CompilerOptions = <span style="color:maroon;">"/target:library"</span>;
        options.ReferencedAssemblies.Add(<span style="color:maroon;">"mscorlib.dll"</span>);
        options.ReferencedAssemblies.Add(<span style="color:maroon;">"System.dll"</span>);
        options.ReferencedAssemblies.Add(<span style="color:maroon;">"System.Xml.dll"</span>);

        <span style="color:lightseagreen;">CompilerResults</span> results = provider.CompileAssemblyFromSource(options, <span style="color:blue;">new</span> <span style="color:blue;">string</span>[] { source });

        <span style="color:blue;">if</span> (results.Errors.HasErrors)
        {
            <span style="color:lightseagreen;">StringBuilder</span> exception = <span style="color:blue;">new</span> <span style="color:lightseagreen;">StringBuilder</span>();
            <span style="color:blue;">foreach</span> (CompilerError error <span style="color:blue;">in</span> results.Errors)
                exception.AppendFormat(<span style="color:maroon;">"{0}({1}): {2}\r\n"</span>, error.ErrorNumber, error.Line, error.ErrorText);
            <span style="color:blue;">throw</span> <span style="color:blue;">new</span> <span style="color:lightseagreen;">ApplicationException</span>(exception.ToString());
        }

        <span style="color:blue;">return</span> results.CompiledAssembly;
    }

    <span style="color:blue;">public</span> <span style="color:blue;">static</span> <span style="color:blue;">object</span> Invoke(<span style="color:lightseagreen;">Assembly</span> assembly, <span style="color:blue;">string</span> method, params <span style="color:blue;">object</span>[] args)
    {
        <span style="color:lightseagreen;">Type</span> type = assembly.GetType(<span style="color:maroon;">"Core.Functoids.UnitTests.Test"</span>);
        <span style="color:blue;">object</span> target = <span style="color:lightseagreen;">Activator</span>.CreateInstance(type);

        <span style="color:blue;">return</span> type.InvokeMember(method
        , BindingFlags.Instance
        | BindingFlags.Public
        | BindingFlags.InvokeMethod
        , <span style="color:blue;">null</span>
        , target
        , args);
    }
}

</pre>
<p>The code shown above is pretty self-explanatory but let&#8217;s walk through it in more details.</p>
<p>In the unit-testing helper class, the <span style="font-family:'Courier New';">GetInlineScriptBuffer</span> method is responsible for calling the corresponding method on the compiled custom inline functoid class. With a bit of reflection, the corresponding custom functoid class is instantiated dynamically, and the method is invoked. You&#8217;ll notice a bunch of flags to deal with calling a non-public methodby reflection.</p>
<p>Next, the <span style="font-family:'Courier New';">GenerateSourceCode</span> method is responsible for wrapping the chunk of code returned from the previous call inside both a C# class and namespace declarations. This turns a string that represents a single function to the well-formed source code for a C# class.</p>
<p>Third, the <span style="font-family:'Courier New';">CreateAssembly</span> method is responsible for compiling the resulting source code to a managed assembly. Notice that this assembly is generated in memory and does not need to be cleaned up after the test is executed.</p>
<p>Finally, the <span style="font-family:'Courier New';">Invoke</span> method instantiates the compiled <span style="font-family:'Courier New';">Core.Functoids.UnitTests.Test</span> class and invokes the wrapped function &#8211; the one that has been extracted from the compiled version of the custom inline functoid. It is the job of the unit-test author to supply correct parameters when calling into this function, as we&#8217;ll see now.</p>
<p><span style="font-family:Tahoma;font-weight:bold;">Unit-Testing Custom Inline Functoids</span></p>
<p>The code shown hereafter is taken from a very simple custom functoid I once wrote in order to convert text representations of a datetime value from one pattern to another. This seems like a common occurence in the map I use. What&#8217;s more interesting is the <span style="font-family:'Courier New';">RunDateTimeConversion</span> method that makes use of the <span style="font-family:'Courier New';">TestHelper</span> class demonstrated in this post in order to call into the custom inline functoid emitted code.</p>
<pre style="border:#cecece 1px solid;background-color:#fbfbfb;width:100%;font-family:consolas, 'Courier New', courier, monospace;font-size:12px;margin:0;padding:5px 1em;">
<span style="color:blue;">using</span> System.Reflection;
<span style="color:blue;">using</span> Microsoft.VisualStudio.TestTools.UnitTesting;

[<span style="color:lightseagreen;">TestClass</span>]
<span style="color:blue;">public</span> <span style="color:blue;">class</span> ConvertDateTime
{
    <span style="color:blue;">public</span> <span style="color:blue;">static</span> <span style="color:lightseagreen;">DateTime</span> date_ = <span style="color:blue;">new</span> <span style="color:lightseagreen;">DateTime</span>(2012, 7, 14, 14, 59, 58, 000, <span style="color:lightseagreen;">DateTimeKind</span>.Utc);
    <span style="color:blue;">public</span> <span style="color:blue;">const</span> <span style="color:lightseagreen;">String</span> iso_date = <span style="color:maroon;">"yyyy'-'MM'-'dd"</span>;
    <span style="color:blue;">public</span> <span style="color:blue;">const</span> <span style="color:lightseagreen;">String</span> iso_date_time = <span style="color:maroon;">"yyyy'-'MM'-'dd'T'HH':'mm':'ss"</span>;

    [<span style="color:lightseagreen;">TestMethod</span>]
    <span style="color:blue;">public</span> <span style="color:blue;">void</span> TestConvertDate()
    {
        Assert.AreEqual(date_.Date, <span style="color:lightseagreen;">DateTime</span>.Parse(RunDateTimeConversion(<span style="color:maroon;">"14/07/12"</span>, <span style="color:maroon;">"dd/MM/yy"</span>, iso_date)).Date);
        Assert.AreEqual(date_.Date, <span style="color:lightseagreen;">DateTime</span>.Parse(RunDateTimeConversion(<span style="color:maroon;">"14/07/2012"</span>, <span style="color:maroon;">"dd/MM/yyyy"</span>, iso_date)).Date);
        Assert.AreEqual(date_.Date, <span style="color:lightseagreen;">DateTime</span>.Parse(RunDateTimeConversion(<span style="color:maroon;">"14-07-2012"</span>, <span style="color:maroon;">"dd-MM-yyyy"</span>, iso_date)).Date);
    }

    <span style="color:blue;">#region</span><span style="color:gray;"> Implementation</span>

    <span style="color:blue;">private</span> <span style="color:blue;">string</span> RunDateTimeConversion(<span style="color:blue;">string</span> dateToConvert, <span style="color:blue;">string</span> inputPattern, <span style="color:blue;">string</span> outputPattern)
    {
        <span style="color:blue;">string</span> inlineScriptBuffer = <span style="color:lightseagreen;">TestHelper</span>.GetInlineScriptBuffer(<span style="color:maroon;">"Custom.Functoids.ConvertDateTime, My.Core.Functoids"</span>, 0, 0);
        <span style="color:blue;">string</span> sourceCode = <span style="color:lightseagreen;">TestHelper</span>.GenerateSourceCode(inlineScriptBuffer);

        <span style="color:lightseagreen;">Assembly</span> assembly = <span style="color:lightseagreen;">TestHelper</span>.CreateAssembly(sourceCode);
        <span style="color:blue;">return</span> (<span style="color:blue;">string</span>)<span style="color:lightseagreen;">TestHelper</span>.Invoke(assembly, <span style="color:maroon;">"DateTimeConversion"</span>, <span style="color:blue;">new</span> <span style="color:blue;">object</span>[] { dateToConvert, inputPattern, outputPattern });
    }

    <span style="color:blue;">#endregion</span><span style="color:gray;"></span>
}
</pre>
<p>That&#8217;s all folks.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maximelabelle.wordpress.com/444/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maximelabelle.wordpress.com/444/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&#038;blog=16599311&#038;post=444&#038;subd=maximelabelle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maximelabelle.wordpress.com/2012/06/06/unit-testing-custom-inline-functoids-with-the-codedom/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/957e1e828557735f52843d3c69f29b1e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maximelabelle</media:title>
		</media:content>
	</item>
		<item>
		<title>Preserving Input Sequence Order when Aggregating Debatched Messages</title>
		<link>http://maximelabelle.wordpress.com/2012/05/02/preserving-input-sequence-order-when-aggregating-debatched-messages/</link>
		<comments>http://maximelabelle.wordpress.com/2012/05/02/preserving-input-sequence-order-when-aggregating-debatched-messages/#comments</comments>
		<pubDate>Wed, 02 May 2012 15:54:27 +0000</pubDate>
		<dc:creator>Maxime Labelle</dc:creator>
				<category><![CDATA[BizTalk]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://maximelabelle.wordpress.com/?p=438</guid>
		<description><![CDATA[In a recent project, Jérémie wanted to improved one BizTalk solution where messages are debatched upon reception, processed independently and aggregated again before transmission to downstream processes or application partners. This is sort of a classic Scatter-Gather pattern. The catch, &#8230; <a href="http://maximelabelle.wordpress.com/2012/05/02/preserving-input-sequence-order-when-aggregating-debatched-messages/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&#038;blog=16599311&#038;post=438&#038;subd=maximelabelle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>
In a recent project, <a href="http://jeremiedevillard.wordpress.com/">Jérémie</a> wanted to improved one BizTalk solution where messages are debatched upon reception, processed independently and aggregated again before transmission to downstream processes or application partners.</p>
<p>
This is sort of a classic <em>Scatter-Gather</em> pattern. The catch, however, is that each message, once debatched, comes with its own sequence number that must be maintained throughout the whole processing chain.</p>
<p>
Since each stage in the process is independent of one another, we wanted to find the most flexible solution that still works in a decoupled fashion between the receive, the processing and the transmission sides.</p>
<p>
The solution we came up with was to create a interim C# dictionary-like class to hold the messages as they are received and rely on the builtin enumerator to retrieve the messages in the correct sequence order.</p>
<p><span style="font-family:Tahoma;font-weight:bold;">A Simple Message Sorted Collection Class</span></p>
<p>
The code below is a quick and simple collection class, designed to hold individual messages. This collection is keyed by an integer value that represents the order of the message in the original sequence of received messages.</p>
<pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;background-color:#fbfbfb;border-top:#cecece 1px solid;border-right:#cecece 1px solid;margin:40px;padding:1em;width:100%;font-family:consolas, 'Courier New', courier, monospace;font-size:12px;">
[<span style="color:lightseagreen;">Serializable</span>]
<span style="color:blue;">public</span> <span style="color:blue;">class</span> MessageSortedCollection : <span style="color:lightseagreen;">IEnumerable</span>&lt;<span style="color:lightseagreen;">XLANGMessage</span>&gt;
{
    <span style="color:blue;">private</span> <span style="color:lightseagreen;">SortedDictionary</span>&lt;<span style="color:lightseagreen;">Int32</span>, <span style="color:lightseagreen;">XLANGMessage</span>&gt; dictionary_ = <span style="color:blue;">new</span> <span style="color:lightseagreen;">SortedDictionary</span>&lt;<span style="color:lightseagreen;">Int32</span>, <span style="color:lightseagreen;">XLANGMessage</span>&gt;();

    <span style="color:blue;">public</span> <span style="color:blue;">void</span> Add(<span style="color:lightseagreen;">Int32</span> sequenceNumber, <span style="color:lightseagreen;">XLANGMessage</span> message)
    {
        dictionary_.Add(sequenceNumber, message);
    }

    <span style="color:blue;">#region</span><span style="color:gray;"> IEnumerable&lt;XLANGMessage&gt; Implementation</span>

    <span style="color:blue;">public</span> <span style="color:lightseagreen;">IEnumerator</span>&lt;<span style="color:lightseagreen;">XLANGMessage</span>&gt; GetEnumerator()
    {
        <span style="color:blue;">return</span> dictionary_.Values.Select(di =&gt; di).GetEnumerator();
    }

    System.Collections.<span style="color:lightseagreen;">IEnumerator</span> System.Collections.<span style="color:lightseagreen;">IEnumerable</span>.GetEnumerator()
    {
        <span style="color:blue;">return</span> (<span style="color:blue;">this</span> <span style="color:blue;">as</span> <span style="color:lightseagreen;">IEnumerable</span>&lt;<span style="color:lightseagreen;">XLANGMessage</span>&gt;).GetEnumerator();
    }

    <span style="color:blue;">#endregion</span><span style="color:gray;"></span>
}
</pre>
<p><span style="font-family:Tahoma;font-weight:bold;">Storing Messages in Order</span></p>
<p>
Using this helper class is very easy from your orchestration. In this post, I will demonstrate a simple scenario where each individual messages are first received by an upstream Orchestration for processing. Then, the following Orchestration, shown hereafter, is used for aggregation.</p>
<p>
Let&#8217;s walk through this very simple Orchestration.</p>
<p>
First, each debatched message must be stored temporarily, before it can be aggregated to the final message in the correct order.</p>
<p style="text-align:center;">
<img src="http://maximelabelle.files.wordpress.com/2012/05/singleton_message_collection1.png?w=640" /></p>
<p>
For this purpose, we typically use a <em>Singleton</em> Orchestration whose purpose would be to perform some kind of processing and store them before the final aggregation.</p>
<p>
In the preceding illustration, the <span style="font-family:'Courier New';">Add Item</span> Expression Shape holds code like this:</p>
<pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;background-color:#fbfbfb;border-top:#cecece 1px solid;border-right:#cecece 1px solid;margin:40px;padding:1em;width:100%;font-family:consolas, 'Courier New', courier, monospace;font-size:12px;">
Collection.Add(InboundMessage.Body.sequence, InboundMessage); 
</pre>
<p>
Where <span style="font-family:'Courier New';">Collection</span> is an Orchestration variable typed <span style="font-family:'Courier New';">MessageSortedCollection</span> and <span style="font-family:'Courier New';">InboundMessage</span> is an instance of a debatched message were the order in the original sequence is identified by a distinguished property.</p>
<p>
Second, once all messages have been received &#8211; identified in the scenario by a timeout condition &#8211; its time to perform further processing before the final aggregation.</p>
<p>
The following Orchestration snippet shows how one relies on the builtin enumeration behavior to iterate over the sequence of debatched messages in the correct order and submit them to a Send Pipeline.</p>
<p style="text-align:center;">
<img src="http://maximelabelle.files.wordpress.com/2012/05/enumerate_sorted_message_collection1.png?w=640" /></p>
<p>
The code in the <span style="font-family:'Courier New';">Get Enumerator</span> and <span style="font-family:'Courier New';">Add to Pipeline</span> Expression Shapes is straightforward:</p>
<pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;background-color:#fbfbfb;border-top:#cecece 1px solid;border-right:#cecece 1px solid;margin:40px;padding:1em;width:100%;font-family:consolas, 'Courier New', courier, monospace;font-size:12px;">
Enumerator = Collection.GetEnumerator();
</pre>
<pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;background-color:#fbfbfb;border-top:#cecece 1px solid;border-right:#cecece 1px solid;margin:40px;padding:1em;width:100%;font-family:consolas, 'Courier New', courier, monospace;font-size:12px;">
SendPipeline.Add(
    (Microsoft.XLANGs.BaseTypes.XLANGMessage) Enumerator.Current
);
</pre>
<p>
Please, note that, since an <span style="font-family:'Courier New';">IEnumerator</span> object is not serializable, the iteration must happen within an atomic scope.</p>
<p>
Next, the Send Pipeline is executed to perform the final aggregation and return the resulting message.</p>
<pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;background-color:#fbfbfb;border-top:#cecece 1px solid;border-right:#cecece 1px solid;margin:40px;padding:1em;width:100%;font-family:consolas, 'Courier New', courier, monospace;font-size:12px;">OutputMessage = new System.Xml.XmlDocument();

Microsoft.XLANGs.Pipeline.XLANGPipelineManager.ExecuteSendPipeline(
      typeof(Microsoft.BizTalk.DefaultPipelines.XMLTransmit)
    , SendPipeline
    , OutputMessage);
</pre>
<p>
This is a simple solution to a simple problem, but one that we BizTalker do not necessarily think about straight away. I hope this helps you deal with the similar situation in your projects.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maximelabelle.wordpress.com/438/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maximelabelle.wordpress.com/438/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&#038;blog=16599311&#038;post=438&#038;subd=maximelabelle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maximelabelle.wordpress.com/2012/05/02/preserving-input-sequence-order-when-aggregating-debatched-messages/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/957e1e828557735f52843d3c69f29b1e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maximelabelle</media:title>
		</media:content>

		<media:content url="http://maximelabelle.files.wordpress.com/2012/05/singleton_message_collection1.png" medium="image" />

		<media:content url="http://maximelabelle.files.wordpress.com/2012/05/enumerate_sorted_message_collection1.png" medium="image" />
	</item>
		<item>
		<title>Session TechDays &#8211; 2012 : Mettre en Oeuvre une Plateforme d&#8217;Intégration et de Gestion des Informations de l&#8217;Entreprise (EIM) avec SQL Server 2012 Master Data Services</title>
		<link>http://maximelabelle.wordpress.com/2012/02/08/session-techdays-2012-mettre-en-oeuvre-une-plateforme-dintegration-et-de-gestion-des-informations-de-lentreprise-eim-avec-sql-server-2012-master-data-services/</link>
		<comments>http://maximelabelle.wordpress.com/2012/02/08/session-techdays-2012-mettre-en-oeuvre-une-plateforme-dintegration-et-de-gestion-des-informations-de-lentreprise-eim-avec-sql-server-2012-master-data-services/#comments</comments>
		<pubDate>Wed, 08 Feb 2012 15:22:15 +0000</pubDate>
		<dc:creator>Maxime Labelle</dc:creator>
				<category><![CDATA[Master Data Services]]></category>

		<guid isPermaLink="false">http://maximelabelle.wordpress.com/?p=389</guid>
		<description><![CDATA[Warning: this post is about my contribution to the Microsoft TechDays 2011 in Paris and is therefore written in french. Pour la deuxième année consécutive, j&#8217;ai le plaisir d&#8217;animer une session sur la dernière version de SQL Server 2012 Master &#8230; <a href="http://maximelabelle.wordpress.com/2012/02/08/session-techdays-2012-mettre-en-oeuvre-une-plateforme-dintegration-et-de-gestion-des-informations-de-lentreprise-eim-avec-sql-server-2012-master-data-services/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&#038;blog=16599311&#038;post=389&#038;subd=maximelabelle&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><em>Warning: this post is about my contribution to the Microsoft TechDays 2011 in Paris and is therefore written in french.</em></p>
<p>Pour <a href="http://maximelabelle.wordpress.com/2011/03/16/session-techdays-2011-les-technologies-dintegration-de-mdm-et-de-soa/">la deuxième année consécutive</a>, j&#8217;ai le plaisir <a href="http://www.microsoft.com/france/mstechdays/programmes/parcours.aspx#DomID=3b327402-34a7-4f9e-9704-9ddebed8094f&amp;SessionID=e1a5bb87-7ce9-47b5-b2dd-c8dec94b87ae">d&#8217;animer une session</a> sur la dernière version de <a href="http://msdn.microsoft.com/en-us/sqlserver/ff943581">SQL Server 2012 Master Data Services</a> à l&#8217;occasion du salon Microsoft TechDays 2012, qui se tient au Palais des Congrès à Paris.</p>
<p>
Cette année, je me suis vu confier l&#8217;animation de la session par Damien Cudel. Je me suis associé à Laurent Banon et mon collègue Radoine pour porter cette session sur un produit en lequel nous croyons vraiment en 2012 !</p>
<p>
Le sujet, ambitieux, de la session est le suivant:</p>
<p>
Avec SQL Server 2012 Master Data Services, la plateforme Application Server de Microsoft se dote d&#8217;un outil puissant de gestion de la donnée de référence. Nous allons montrer en quoi et comment cette solution, qui dispose d&#8217;une fonctionnalité de maintien de la qualité de la donnée, complète l&#8217;écosystème applicatif et permet de mettre en oeuvre des processus d&#8217;intégration, d&#8217;enrichissement et de diffusion des données de référence, en temps réel, entre les différentes partenaires applicatifs du système d&#8217;information, à l&#8217;intérieur comme à l&#8217;extérieur de l&#8217;entreprise.</p>
<p>
Vous trouverez la <a href="http://www.microsoft.com/france/mstechdays/programmes/parcours.aspx#DomID=3b327402-34a7-4f9e-9704-9ddebed8094f&amp;SessionID=e1a5bb87-7ce9-47b5-b2dd-c8dec94b87ae">vidéo de la session</a> sur le site <a href="http://www.microsoft.com/france/mstechdays">Microsoft TechDays 2012</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maximelabelle.wordpress.com/389/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maximelabelle.wordpress.com/389/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&#038;blog=16599311&#038;post=389&#038;subd=maximelabelle&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maximelabelle.wordpress.com/2012/02/08/session-techdays-2012-mettre-en-oeuvre-une-plateforme-dintegration-et-de-gestion-des-informations-de-lentreprise-eim-avec-sql-server-2012-master-data-services/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/957e1e828557735f52843d3c69f29b1e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maximelabelle</media:title>
		</media:content>
	</item>
	</channel>
</rss>
