<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Visual Studio Tools and Anything Else I Can Think Of</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/philliphoff/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/philliphoff/feed.xml</link>
    <description />
    <lastBuildDate>Tue, 16 Apr 2019 05:24:18 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>MissingManifestResourceException when using Portable Class Libraries within WinRT</title>
      <link>https://docs.microsoft.com/archive/blogs/philliphoff/missingmanifestresourceexception-when-using-portable-class-libraries-within-winrt</link>
      <pubDate>Wed, 19 Nov 2014 12:12:00 GMT</pubDate>
      <dc:creator><![CDATA[Phil Hoff - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/philliphoff/2014/11/19/missingmanifestresourceexception-when-using-portable-class-libraries-within-winrt/</guid>
      <description><![CDATA[Our team recently ran into a strange issue. &nbsp;Our Windows Phone application targets Silverlight...]]></description>
      <content:encoded><![CDATA[<p>Our team recently ran into a strange issue. &nbsp;Our Windows Phone application targets Silverlight 8.1 but we have several WinRT 8.1 based background tasks. &nbsp;Recently, we refactored our codebase into several Portable Class Libraries (PCLs) in order to better share code between the application and background tasks. &nbsp;Since then, however, we've started seeing <span style="font-family: 'courier new', courier;">MissingManifestResourceExceptions</span> thrown from the background tasks from the <span style="font-family: 'courier new', courier;">ResourceManager.GetString(String, CultureInfo)</span> method. &nbsp;The odd thing was that this occurred <em>only</em> in the background tasks, <em>only</em> when running on a real phone, and <em>only</em> in the application's Release configuration. &nbsp;The exceptions were not seen in the Silverlight application, or in the Windows Phone emulator, or when using the application's Debug configuration.</p>
<p>We originally thought the issue must be due to some overlooked error in our build or packaging processes, but all of our analysis indicated that the there were no significant differences in the built assemblies nor in the packages generated for Debug and Release configurations; the issue must be in the runtime. &nbsp;After a lot of digging around, we finally found an active Microsoft Connect report for the issue:</p>
<p><a title="https://connect.microsoft.com/VisualStudio/feedback/details/991028/issue-using-resx-files-on-winrt-apps-windows-phone-and-windows" href="https://connect.microsoft.com/VisualStudio/feedback/details/991028/issue-using-resx-files-on-winrt-apps-windows-phone-and-windows" target="_blank">https://connect.microsoft.com/VisualStudio/feedback/details/991028/issue-using-resx-files-on-winrt-apps-windows-phone-and-windows</a></p>
<p>That others were running into the same problem, under the same circumstances, seemed to confirm our conclusion. &nbsp;However, we still needed a workaround. &nbsp;Our options were (1) to avoid using PCLs (that use their own resources) from our background task or &nbsp;(2) redirect use of the <span style="font-family: 'courier new', courier;">ResourceManager</span> within the PCL to the WinRT <span style="font-family: 'courier new', courier;">ResourceLoader</span>. &nbsp;Option #1 would mean undoing much of our refactoring work and obviously was a non-starter.</p>
<p>Option #2 works on the assumption that, in a WinRT library, all of the resources of the referenced PCLs are extracted and placed in the package's <span style="font-family: 'courier new', courier;">resources.pri</span> file <em>in addition to</em> being embedded within the PCL assembly itself. &nbsp;That means you can get to the duplicate resources using the WinRT <span style="font-family: 'courier new', courier;">ResourceLoader</span> even if you cannot using the .NET <span style="font-family: 'courier new', courier;">ResourceManager</span>. &nbsp;Because we need to dynamically switch between using the <span style="font-family: 'courier new', courier;">ResourceManager</span> and <span style="font-family: 'courier new', courier;">ResourceLoader</span> when in Silverlight and WinRT, respectively, we need some sort of dependency injection (DI) scheme.</p>
<p>In a typical .NET library, resources are added to a Resources file (<span style="font-family: 'courier new', courier;">.resx</span>). &nbsp;The file is then used to embed the resources into the built assembly. &nbsp;The file is also used to generate a class that exposes each resource as a strongly-typed property, making it easy to consume resources within the library. &nbsp;This generated class uses a <span style="font-family: 'courier new', courier;">ResourceManager</span> instance to retrieve the resource mapped to each property. &nbsp;Redirection means either (1) not using the generated class at all and using DI scheme directly, (2) alter the generation of the class to use the DI scheme, or (3) try to alter the <em>behavior</em> of the class to conform to the DI scheme.</p>
<p>Option #1 was least desirable as it meant a lot of churn within the PCLs. &nbsp;Option #2 was not particularly desirable either as it was a significant amount of work to write and test a generator that matched the built-in one except for this one minor change. &nbsp;The question was how to implement option #3.</p>
<p>Looking at the generated class for a Resources file, each contains a static <span style="font-family: 'courier new', courier;">ResourceManager</span> field named <span style="font-family: 'courier new', courier;">resourceMan</span>. &nbsp;This field (if null)&nbsp;is set on the first retrieval of a resource via one of the generated properties. &nbsp;The <span style="font-family: 'courier new', courier;">ResourceManager.GetString(String, CultureInfo)</span> also happens to be a virtual method, which means we cancreate a derived <span style="font-family: 'courier new', courier;">ResourceManager</span> that retrieves resources from, say, a <span style="font-family: 'courier new', courier;">ResourceLoader</span>. &nbsp;The trick then, is to initialize that static <span style="font-family: 'courier new', courier;">ResourceManager</span> field to an instance of our derived <span style="font-family: 'courier new', courier;">ResourceManager</span>. &nbsp;That turns out to be a simple act of reflection as shown in the following sample:&nbsp;</p>
<p class="scroll"><span style="font-family: 'courier new', courier;"><code class="csharp">public class WindowsRuntimeResourceManager : ResourceManager</code></span></p>
<div><span style="font-family: 'courier new', courier;">{</span></div>
<p class="scroll"><span style="font-family: 'courier new', courier;">&nbsp; private readonly ResourceLoader resourceLoader;<br /> <br />&nbsp; private WindowsRuntimeResourceManager(string baseName, Assembly assembly) : base(baseName, assembly)<br />&nbsp; {<br />&nbsp; &nbsp; this.resourceLoader = ResourceLoader.GetForViewIndependentUse(baseName);<br />&nbsp; }<br /> <br />&nbsp; public static void InjectIntoResxGeneratedApplicationResourcesClass(Type resxGeneratedApplicationResourcesClass)<br />&nbsp; {<br />&nbsp; &nbsp; resxGeneratedApplicationResourcesClass.GetRuntimeFields()<br />&nbsp; &nbsp; &nbsp; .First(m =&gt; m.Name == "resourceMan")<br />&nbsp; &nbsp; &nbsp; .SetValue(null, new WindowsRuntimeResourceManager(resxGeneratedApplicationResourcesClass.FullName, resxGeneratedApplicationResourcesClass.GetTypeInfo().Assembly));<br />&nbsp; }<br /> <br />&nbsp; public override string GetString(string name, CultureInfo culture)<br />&nbsp; {<br />&nbsp; &nbsp; return this.resourceLoader.GetString(name);<br />&nbsp; }<br /> }</span></p>
<p>In the WinRT component, we then call the static injection method <em>for each</em> generated Resources class within the PCL: &nbsp; &nbsp;&nbsp;</p>
<p class="scroll"><span style="font-family: 'courier new', courier;"><code class="csharp">&nbsp; WindowsRuntimeResourceManager.InjectIntoResxGeneratedApplicationResourcesClass(typeof(PortableLibrary.Resources.AppResources));</code></span></p>
<p>With that, our WinRT background tasks and referenced PCLs were able to access all of their resources without issue and we did not have to significantly refactor any code.</p>
<p>Caveats:</p>
<ul>
<li>Using reflection to set private fields for types you do not own completely (e.g. are generated) is highly fragile and could break with the next version of the Resources class generator. &nbsp;Do this only if you have no other choice and ensure you have checks in place to detect such breaks.</li>
<li>In our case we owned all of the PCLs referenced by our WinRT component. &nbsp;I cannot say whether this workaround will work for all (e.g. third-party) PCLs, and may not work for PCLs which have internal resource types that cannot be as easily injected.</li>
</ul>]]></content:encoded>
    </item>
    <item>
      <title>Dynamically Add Content to Windows Azure Application Roles</title>
      <link>https://docs.microsoft.com/archive/blogs/philliphoff/dynamically-add-content-to-windows-azure-application-roles</link>
      <pubDate>Thu, 05 Jul 2012 19:41:00 GMT</pubDate>
      <dc:creator><![CDATA[Phil Hoff - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/philliphoff/2012/07/05/dynamically-add-content-to-windows-azure-application-roles/</guid>
      <description><![CDATA[In a previous post I introduced the concept of Role Content Folders and how they can be used to...]]></description>
      <content:encoded><![CDATA[<p>In a previous <a href="https://blogs.msdn.com/b/philliphoff/archive/2012/06/08/add-files-to-your-windows-azure-package-using-role-content-folders.aspx">post</a> I introduced the concept of Role Content Folders and how they can be used to deploy additional content (e.g. configuration files, runtime components, etc.) to the virtual machine for a Windows Azure application role.&nbsp; That post was written from the perspective of a developer working within Visual Studio and works great when the content is relatively static and specific to a single project.&nbsp; However, this feature works less well in cases where the content is more dynamic (i.e. where the additional content is not known until package-time) or when the content is used across several roles or applications.&nbsp; Fortunately, the packaging of Role Content Folders within Visual Studio is built upon more general MSBuild infrastructure which we can extend to package additional, arbitrary content.</p>
<p>In v1.7, the targets file for Windows Azure projects contains a new packaging phase (i.e. high-level target) called <span style="font-family: Courier New;" face="Courier New">AddRoleContent</span>.&nbsp; In this phase, various sub-targets identify the Role Content Folders defined by the project file, prepare the files within those folders for packaging, and then inject appropriate elements into the Service Definition (.csdef) file such that those files will be packaged when the process invokes CSPack.&nbsp; The <span style="font-family: Courier New;" face="Courier New">AzureRoleContent</span> MSBuild item group ultimately determines what folders will be packaged and for which roles.&nbsp; An <span style="font-family: Courier New;" face="Courier New">AzureRoleContent</span> item contains the following metadata:</p>
<ul>
<li><strong><span style="font-family: Courier New;" face="Courier New">Identity</span> (i.e. <span style="font-family: Courier New;" face="Courier New">Include</span>):</strong> This metadata specifies the source folder of the content to package</li>
<li><strong><span style="font-family: Courier New;" face="Courier New">RoleName</span>:</strong> This metadata specifies the name of the role to which the content should be deployed; the content will be deployed to all instances of that role.</li>
<li><strong><span style="font-family: Courier New;" face="Courier New">Destination</span>:</strong> (Optional) This metadata specifies the location to which the content should be deployed (relative to <span style="font-family: Courier New;" face="Courier New">APPROOT</span>).&nbsp; If omitted, the content is deployed directly to <span style="font-family: Courier New;" face="Courier New">APPROOT</span>.</li>
</ul>
<p>To inject additional content into the package, one must add new <span style="font-family: Courier New;" face="Courier New">AzureRoleContent</span> items prior to the last step of this packaging phase.&nbsp; A convenient place to do this is within an override of the <span style="font-family: Courier New;" face="Courier New">BeforeAddRoleContent</span> target.&nbsp; An alternative is to add a custom target to the beginning of the target list <span style="font-family: Courier New;" face="Courier New">CoreAddRoleContentDependsOn</span> MSBuild property.&nbsp; This latter approach can be useful for cases where you customize many Windows Azure projects in the same way, as it ensures that individual Azure projects do not interfere with the customization if a project were to independently override the <span style="font-family: Courier New;" face="Courier New">BeforeAddRoleContent</span> target.</p>
<p>Let&rsquo;s suppose we have the following:</p>
<ul>
<li>A Visual Studio solution with a Windows Azure project, DynamicRoleContentFolderTest, containing two roles:</li>
<ul>
<li>A web role named MyWebRole</li>
<li>A worker role named MyWorkerRole</li>
</ul>
<li>An additional folder of content, <span style="font-family: Courier New;" face="Courier New">AdditionalContent</span>, to be deployed only to the web role:</li>
<ul>
<li>Located within the DynamicRoleContentFolderTest project</li>
<li>Contains a single file, <span style="font-family: Courier New;" face="Courier New">AdditionalContent.xml</span></li>
</ul>
</ul>
<p>The first step is to edit the Windows Azure project file and override the <span style="font-family: Courier New;" face="Courier New">BeforeAddRoleContent</span> target.&nbsp; Next, the target will create a new item group, <span style="font-family: Courier New;" face="Courier New">AzureRoleContent</span>, that includes the <span style="font-family: Courier New;" face="Courier New">AdditionalContent</span> folder.&nbsp; We&rsquo;ll then add metadata to the item group to specify that it be deployed with the web role, MyWebRole, as well as deployed to the <span style="font-family: Courier New;" face="Courier New">APPROOT\AdditionalContent</span> folder.&nbsp; In the end, we will have a project file that looks something like:</p>
<p><span style="font-family: Courier New;" face="Courier New">. <br /> . <br /> . <br />&lt;Import Project="$(CloudExtensionsDir)Microsoft.WindowsAzure.targets" /&gt; <br />&lt;Target Name="BeforeAddRoleContent"&gt; <br />&nbsp; &lt;ItemGroup&gt; <br />&nbsp;&nbsp;&nbsp; &lt;AzureRoleContent Include="AdditionalContent"&gt; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;RoleName&gt;MyWebRole&lt;/RoleName&gt; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Destination&gt;AdditionalContent&lt;/Destination&gt; <br />&nbsp;&nbsp;&nbsp; &lt;/AzureRoleContent&gt; <br />&nbsp; &lt;/ItemGroup&gt; <br />&lt;/Target&gt; <br /> . <br /> . <br />.</span></p>
<p>When a package is built and/or deployed you will then see the <span style="font-family: Courier New;" face="Courier New">AdditionalContent</span> folder, with its <span style="font-family: Courier New;" face="Courier New">AdditionalContent.xml</span> file, in the package layout and/or on the virtual machine.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/85/27/metablogapi/4314.AdditionalContent_07546AB9.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-85-27-metablogapi/4314.AdditionalContent_5F00_07546AB9.png"><img width="253" height="409" title="AdditionalContent" style="display: inline; background-image: none;" alt="AdditionalContent" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/85/27/metablogapi/5875.AdditionalContent_thumb_00A16136.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-85-27-metablogapi/5875.AdditionalContent_5F00_thumb_5F00_00A16136.png" border="0" /></a></p>
<p>Now what would happen if we omitted the <span style="font-family: Courier New;" face="Courier New">Destination</span> metadata from the item group, as in the following example?</p>
<p><span style="font-family: Courier New;" face="Courier New">. <br /> . <br /> . <br />&lt;AzureRoleContent Include="AdditionalContent"&gt; <br />&nbsp; &lt;RoleName&gt;MyWebRole&lt;/RoleName&gt; <br />&nbsp; &lt;!--&lt;Destination&gt;AdditionalContent&lt;/Destination&gt;--&gt; <br />&lt;/AzureRoleContent&gt; <br /> . <br /> . <br /> .</span></p>
<p>In this example, the content in the <span style="font-family: Courier New;" face="Courier New">AdditionalContent</span> folder will deployed directly to <span style="font-family: Courier New;" face="Courier New">APPROOT</span>, with no corresponding subfolder.&nbsp; This can be very useful when you need to deploy a configuration file to <span style="font-family: Courier New;" face="Courier New">APPROOT</span>.&nbsp; However, note that this can result in name collisions between files deployed by the role project and files deployed through this Role Content Folder mechanism.&nbsp; You will not get any warnings or errors from CSPack (or the Tools) when this happens, so beware!</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/85/27/metablogapi/8117.AdditionalContentInAppRoot_20BC6DF3.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-85-27-metablogapi/8117.AdditionalContentInAppRoot_5F00_20BC6DF3.png"><img width="250" height="405" title="AdditionalContentInAppRoot" style="display: inline; background-image: none;" alt="AdditionalContentInAppRoot" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/85/27/metablogapi/3302.AdditionalContentInAppRoot_thumb_55C8FD23.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-85-27-metablogapi/3302.AdditionalContentInAppRoot_5F00_thumb_5F00_55C8FD23.png" border="0" /></a></p>
<p>Role Content Folders can be a great option when you have additional content to deploy to a role of a Windows Azure application, whether used to deploy static content within Visual Studio or used in conjunction with the underlying infrastructure to deploy more dynamic content.</p>]]></content:encoded>
    </item>
    <item>
      <title>Transform Windows Azure Service Model Files During Packaging</title>
      <link>https://docs.microsoft.com/archive/blogs/philliphoff/transform-windows-azure-service-model-files-during-packaging</link>
      <pubDate>Mon, 02 Jul 2012 17:47:00 GMT</pubDate>
      <dc:creator><![CDATA[Phil Hoff - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/philliphoff/2012/07/02/transform-windows-azure-service-model-files-during-packaging/</guid>
      <description><![CDATA[The latest versions of the Windows Azure Tools for Visual Studio have the ability to maintain...]]></description>
      <content:encoded><![CDATA[<p>The latest versions of the Windows Azure Tools for Visual Studio have the ability to maintain multiple versions of the Service Configuration (.cscfg) file.&nbsp; The developer is then prompted to select the version to accompany a deployment, whether it&rsquo;s going to Windows Azure or the development fabric (i.e. the emulator).&nbsp; However, sometimes a developer needs to do something a little more dynamic, where elements of the Service Configuration file must be generated on-the-fly before deployment.</p>
<p>The Tools generate a Windows Azure package via a process driven by MSBuild.&nbsp; The process already performs certain transformations of the Service Configuration file from the original hosted by the project.&nbsp; These transformations include:</p>
<ul>
<li>Adding configuration setting values when IntelliTrace or Profiling are enabled during publishing</li>
<li>Adding configuration setting values when Remote Desktop is enabled during publishing</li>
<li>Adding endpoints when WebDeploy is enabled</li>
</ul>
<p>This transformation process is easily extensible (for certain definitions of &ldquo;easy&rdquo;).&nbsp; To do this, some of the MSBuild concepts you will need are:</p>
<ul>
<li><strong><span style="font-family: Courier New;" face="Courier New">TargetProfile</span>:</strong> This MSBuild property corresponds to the configuration selected for packaging or deployment, e.g. &ldquo;Local&rdquo; or &ldquo;Cloud&rdquo;.</li>
<li><strong><span style="font-family: Courier New;" face="Courier New">SourceServiceConfiguration</span>:</strong> This MSBuild item group* corresponds to the Service Configuration file hosted by the project that was selected for deployment (based on the value of the <span style="font-family: Courier New;" face="Courier New">TargetProfile</span> property), e.g. ServiceConfiguration.Cloud.cscfg.</li>
<li><strong><span style="font-family: Courier New;" face="Courier New">TargetServiceConfiguration</span>:</strong> This MSBuild item group* corresponds to the actual Service Configuration file that will be deployed.&nbsp; This file begins as a copy of <span style="font-family: Courier New;" face="Courier New">SourceServiceConfiguration</span> but may then be transformed based on the selected publish settings.</li>
<li>
<p><strong><span style="font-family: Courier New;" face="Courier New">TransformServiceModel</span>:</strong> This target represents the part of the build and package process that controls transformation of the Service Configuration file.&nbsp; It can be extended by overriding the <span style="font-family: Courier New;" face="Courier New">BeforeTransformServiceModel</span> or <span style="font-family: Courier New;" face="Courier New">AfterTransformServiceModel</span><span style="font-family: Segoe UI;" face="Segoe UI"> targets</span>, or by adding new targets to the <span style="font-family: Courier New;" face="Courier New">CoreTransformServiceModelDependsOn</span> MSBuild property.</p>
</li>
</ul>
<p>*Despite being an item group, it only ever contains a single file.</p>
<p>To add a new transformation step, start by updating the project file (.ccproj).&nbsp; Add a new property group that redefines <span style="font-family: Courier New;" face="Courier New">CoreTransformServiceModelDependsOn</span>, adding a new target to the end of the original value.&nbsp; Next, define the new target; it will now get called during the transformation phase of the package process.&nbsp; In the target, open the file represented by the <span style="font-family: Courier New;" face="Courier New">@(TargetServiceConfiguration)</span>item group, modify it as desired, and then save it.</p>
<p><span style="font-family: Courier New;" face="Courier New">&nbsp; . <br />&nbsp; . <br />&nbsp; . <br />&nbsp; &lt;Import Project="$(CloudExtensionsDir)Microsoft.WindowsAzure.targets" /&gt;&nbsp;&nbsp;&nbsp; <br />&nbsp; &lt;PropertyGroup&gt; <br />&nbsp;&nbsp;&nbsp; &lt;CoreTransformServiceModelDependsOn&gt; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $(CoreTransformServiceModelDependsOn); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NewServiceConfigurationTransform; <br />&nbsp;&nbsp;&nbsp; &lt;/CoreTransformServiceModelDependsOn&gt; <br />&nbsp; &lt;/PropertyGroup&gt; <br />&nbsp; &lt;Target Name="NewServiceConfigurationTransform"&gt; <br />&nbsp;&nbsp;&nbsp; &lt;!-- Perform transformation of @(TargetServiceConfiguration) here. &ndash;&gt; <br />&nbsp; &lt;/Target&gt; <br />&nbsp; . <br />&nbsp; . <br />&nbsp; .</span></p>
<p>To see a practical example of this technique used to workaround an issue encountered by some customers in the v1.7 Tools, read <a href="https://social.msdn.microsoft.com/Forums/en-US/windowsazuredevelopment/thread/70f7f535-9d3b-49db-b71a-edb9bcec22ea">this MSDN forum post</a>.</p>
<h4>Don&rsquo;t Forget the Service Definition File!</h4>
<p>The Service Definition (.csdef) file is intended to be the same across all deployments of a Windows Azure application.&nbsp; This is why it&rsquo;s located in the package rather than alongside the package like the Service Configuration file.&nbsp; However, there are still scenarios where a developer may wish to change the Service Definition dynamically, based on the environment for which the application is packaged.&nbsp; Even though the Tools do not support multiple Service Definition files hosted by a project, they undergo a very similar transformation process that can be extended in the same way, using similar MSBuild concepts:</p>
<ul>
<li><strong><span style="font-family: Courier New;" face="Courier New">SourceServiceDefinition</span>:</strong> This MSBuild item group* corresponds to the Service Definition file hosted by the project, e.g. ServiceDefinition.csdef.</li>
<li><strong><span style="font-family: Courier New;" face="Courier New">TargetServiceDefinition</span>:</strong> This MSBuild item group* corresponds to the actual Service Definition file that will be packaged.&nbsp; This file begins as a copy of <span style="font-family: Courier New;" face="Courier New">SourceServiceDefinition</span> but may then be transformed based on the selected publish settings.</li>
</ul>
<p>*Despite being an item group, it only ever contains a single file.</p>
<p>You can apply transformations to the Service Definition file using the <span style="font-family: Courier New;" face="Courier New">@(TargetServiceDefinition)</span>item group in the same target as you do the Service Configuration file.</p>
<h4>Project File Customization or Common Target?</h4>
<p>If the transformation scenario is specific to a single Windows Azure project, then it makes sense to alter the build and package process via that project file directly.&nbsp; However, if the scenario is common it may make sense to split out the customization into a separate targets file.&nbsp; This target file can then be imported in various ways depending on how commonly it&rsquo;s needed:</p>
<ul>
<li><strong>(Option #1) Import the targets directly from the project:</strong> In this option, the targets file is stored in a well-known location (preferably in a path that can be specified relative to any project which has occasion to use it).&nbsp; The project file is then modified by hand to import the targets file after the import of the Windows Azure targets file.&nbsp; This option is suitable when a limited, related set of Windows Azure projects (e.g. within the same solution) need the same customization.</li>
<li><strong>(Option #2) Globally import the targets:</strong> In this option, the targets file is placed in a well known location on the machine which will cause it to be automatically imported by <em>every</em> Windows Azure application on that machine.&nbsp; This option is suitable when <em>any</em> Windows Azure project might need the same customization.&nbsp; To have a target file imported automatically by all Windows Azure projects, add the file to this location:</li>
</ul>
<blockquote>
<p><span style="font-family: Courier New;" face="Courier New">&lt;Program Files (x86)&gt;\MSBuild\Microsoft\VisualStudio\&lt;VS Version&gt;\Windows Azure Tools\&lt;Tools Version&gt;\ImportAfter\</span></p>
</blockquote>
<blockquote>
<p>For example, on a machine with Visual Studio 2012 installed and version 1.7 of the tools the location would be:</p>
<p><span style="font-family: Courier New;" face="Courier New">C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Windows Azure Tools\1.7\ImportAfter\</span></p>
</blockquote>
<blockquote>
<p>Note that, since this target is imported by <em>all</em> Windows Azure projects on the machine, it should be robust enough to handle cases where the customization is not necessary.</p>
</blockquote>
<h4>But I Want Web.config-style Transforms!</h4>
<p>A common question is &ldquo;why don&rsquo;t the Tools support multiple Service Configuration files using web.config-style transforms?&rdquo;&nbsp; (This transformation mechanism is being more commonly referred to as <a href="https://visualstudiogallery.msdn.microsoft.com/69023d00-a4f9-4a34-a6cd-7e854ba318b5">SlowCheeta</a>.)&nbsp; Well, the short answer is: because the Tools has a designer over the Service Model files and web.config does not.&nbsp; Using multiple, complete, configuration files to represent different configuration environments is far less complex to automate via a design surface like the Role Editor (a.k.a. Service Model UI).&nbsp; In addition, it&rsquo;s easier for the beginning Windows Azure developer to understand complete files and not be forced to learn the complex XML matching and transformation syntax.</p>
<p>For those that still want web.config-style transformations, you can use the same techniques described above to get close to the familiar web application project experience.&nbsp; Start by updating the project file (.ccproj).&nbsp; Add a new property group that redefines <span style="font-family: Courier New;" face="Courier New">CoreTransformServiceModelDependsOn</span>, adding a new target to the end of the original value.&nbsp; Next, add a <span style="font-family: Courier New;" face="Courier New">UsingTask</span> element that refers to the <span style="font-family: Courier New;" face="Courier New">TransformXml</span> task in the web application publishing tasks assembly.&nbsp; Define the new target; it will now get called during the transformation phase of the package process.&nbsp; In the target, call the <span style="font-family: Courier New;" face="Courier New">TransformXml</span> task using the <span style="font-family: Courier New;" face="Courier New">@(TargetServiceConfiguration)</span> item group as both the source and destination, and specify an arbitrary transform file.&nbsp; In the example below, I&rsquo;m choosing a transform file based on the current <span style="font-family: Courier New;" face="Courier New">TargetProfile</span>.&nbsp; For example, if the <span style="font-family: Courier New;" face="Courier New">TargetProfile</span> is &ldquo;Cloud&rdquo; meaning the ServiceConfiguration.Cloud.cscfg file will be deployed, the task will transform the source file using the file ServiceConfiguration.Cloud.Transform.cscfg, if it exists.&nbsp; (If it does not exist, no transform is performed.)</p>
<p><span style="font-family: Courier New;" face="Courier New">. <br /> . <br /> . <br />&lt; Import Project="$(CloudExtensionsDir)Microsoft.WindowsAzure.targets" /&gt; <br />&lt; PropertyGroup&gt; <br />&nbsp; &lt; CoreTransformServiceModelDependsOn&gt; <br />&nbsp;&nbsp;&nbsp; $(CoreTransformServiceModelDependsOn); <br />&nbsp;&nbsp;&nbsp; PerformXmlTransform; <br />&nbsp; &lt;/CoreTransformServiceModelDependsOn&gt; <br />&lt; /PropertyGroup&gt;</span></p>
<p><span style="font-family: Courier New;" face="Courier New"></span></p>
<p><span style="font-family: Courier New;" face="Courier New">&lt;UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.Publishing.Tasks.dll" /&gt;</span></p>
<p><span style="font-family: Courier New;" face="Courier New"></span></p>
<p><span style="font-family: Courier New;" face="Courier New">&lt;Target Name="PerformXmlTransform" Condition=" Exists('ServiceConfiguration.$(TargetProfile).Transform.cscfg') "&gt;</span></p>
<p><span style="font-family: Courier New;" face="Courier New"></span></p>
<p><span style="font-family: Courier New;" face="Courier New">&nbsp; &lt;TransformXml Source="@(TargetServiceConfiguration)" <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transform="ServiceConfiguration.$(TargetProfile).Transform.cscfg" <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Destination="@(TargetServiceConfiguration)" /&gt;</span></p>
<p><span style="font-family: Courier New;" face="Courier New"></span></p>
<p><span style="font-family: Courier New;" face="Courier New">&nbsp; &lt;Message importance="high" Text="Transformed @(TargetServiceConfiguration) using ServiceConfiguration.$(TargetProfile).Transform.cscfg." /&gt; <br />&nbsp; <br />&lt; /Target&gt; <br /> . <br /> . <br /> .</span></p>
<p>To sum up, if you are willing to spend some time to learn a few basic MSBuild concepts, the Windows Azure Tools for Visual Studio offers a lot of packaging flexibility.&nbsp; If you have custom packaging scenarios that the Tools do not support directly, consider using the Tools extensibility to add your own!</p>]]></content:encoded>
    </item>
    <item>
      <title>Ignore Validation Warnings when Packaging a Windows Azure Application</title>
      <link>https://docs.microsoft.com/archive/blogs/philliphoff/ignore-validation-warnings-when-packaging-a-windows-azure-application</link>
      <pubDate>Wed, 27 Jun 2012 11:48:00 GMT</pubDate>
      <dc:creator><![CDATA[Phil Hoff - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/philliphoff/2012/06/27/ignore-validation-warnings-when-packaging-a-windows-azure-application/</guid>
      <description><![CDATA[When a package fails to deploy to Windows Azure (or deploys but its roles fail to start properly) it...]]></description>
      <content:encoded><![CDATA[<p>When a package fails to deploy to Windows Azure (or deploys but its roles fail to start properly) it can be difficult to determine what went wrong.&nbsp; In many cases, these failures often happen before the diagnostics agent has had a chance to startup and help identify the issue.&nbsp; A lot of these failures are due to simple but easily forgotten tasks, such as not adding a referenced assembly to the package or not updating your connection strings to point to Windows Azure storage instead of the storage emulator.&nbsp; The Windows Azure Tools for Visual Studio tries to help developers catch many of these issues before they spend time waiting for their package to deploy and the application to start (and then fail).&nbsp; When such issues are encountered during packaging the build process generates validation warnings or errors.&nbsp; The developer then has immediate, specific feedback on what needs to be done before deploying again to Windows Azure.</p>
<p>Validation performed by the Tools include:</p>
<ul>
<li>Verify that the projects corresponding to each role are built against versions of the .NET runtime that exist on the virtual machines.</li>
<li>Verify that the projects reference only assemblies that exist on the virtual machines (i.e. the .NET Framework or Windows Azure client libraries) or have been specifically included in the package (i.e. Copy Local is True).</li>
<li>Verify that connection strings for diagnostics or caching in the service configuration (.cscfg) do not point to the storage emulator (which will likely cause the corresponding agents to fail, and thus the role to fail).</li>
</ul>
<p>In some cases, however, these warnings may not apply.&nbsp; For example, suppose you are generating a package as part of a continuous build that will then be deployed to the development fabric and undergo a series of automated tests.&nbsp; If you were to generate a package (e.g. by calling the Publish target), you may see the following warnings:</p>
<p><span style="font-family: Courier New;" face="Courier New">WebRole1(0,0): warning WAT170: The configuration setting 'Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString' is set up to use the local storage emulator for role 'WebRole1' in configuration file 'ServiceConfiguration.Cloud.cscfg'. To access Windows Azure storage services, you must provide a valid Windows Azure storage connection string. <br /> WebRole1(0,0): warning WAT230: The connection string 'DefaultConnection' is using a local database '(LocalDb)\v11.0' in project 'WebRole1'. This connection string will not work when you run this application in Windows Azure. To access a different database, you should update the connection string in the web.config file.</span></p>
<p>The warnings indicate that there are connection strings pointing to the storage emulator as well as a local database and these will likely cause a deployment to Windows Azure to fail.&nbsp; In this case, however, we know that the package is being deployed to the development fabric so those connection strings are, in fact, perfectly valid.&nbsp; In the interests of producing &ldquo;clean&rdquo; builds, it would be nice to ignore these warnings in this particular case.</p>
<p>To ignore validation warnings when packaging a Windows Azure application, set the <span style="font-family: Courier New;" face="Courier New">IgnoreValidationIssueCodes</span> MSBuild property in your application&rsquo;s project file.&nbsp; For example, to ignore the two warnings encountered above set the property after the import of the WindowsAzure targets file:</p>
<p><span style="font-family: Courier New;" face="Courier New">. <br /> . <br /> . <br />&lt;Import Project="$(CloudExtensionsDir)Microsoft.WindowsAzure.targets" /&gt; <br />&lt;PropertyGroup&gt; <br />&nbsp; &lt;IgnoreValidationIssueCodes&gt;WAT170;WAT230&lt;/IgnoreValidationIssueCodes&gt; <br />&lt;/PropertyGroup&gt; <br /> . <br /> . <br />.</span></p>
<p>Now these warnings will not be generated when packaging.</p>]]></content:encoded>
    </item>
    <item>
      <title>Add Files to your Windows Azure Package using Role Content Folders</title>
      <link>https://docs.microsoft.com/archive/blogs/philliphoff/add-files-to-your-windows-azure-package-using-role-content-folders</link>
      <pubDate>Fri, 08 Jun 2012 18:47:23 GMT</pubDate>
      <dc:creator><![CDATA[Phil Hoff - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/philliphoff/2012/06/08/add-files-to-your-windows-azure-package-using-role-content-folders/</guid>
      <description><![CDATA[Windows Azure applications often need to package and deploy additional content.&#160; This could be...]]></description>
      <content:encoded><![CDATA[<p>Windows Azure applications often need to package and deploy additional content.&#160; This could be advanced configuration files such as the diagnostics.wadcfg for the Diagnostics plugin.&#160; It could also be scripts and binaries that modify the virtual machine to which a role is deployed, such as installing additional runtime components.&#160; In any case, prior to the June 2012 (1.7) release of the Windows Azure Tools for Visual Studio, there were few direct ways to get this content into a package and deployed to Windows Azure.&#160; </p>  <p>One of the most common ways to package and deploy additional content to Windows Azure was to add the content to one of the role projects and set its Build Action to Content.&#160; On build (e.g. when creating a package or publishing to Windows Azure), the content would be copied to the role project’s output directory and subsequently picked up during packaging.&#160; There are some downsides to this approach, however.&#160; First, depending on the type of role (i.e. web or worker), the content could end up deployed to different locations, either in the role’s APPROOT directory or a bin subdirectory.&#160; Any component which uses this content on the virtual machine must account for that inconsistency.&#160; Second, the approach tends to pollute role projects with Azure-specific files when they might otherwise be platform agnostic.&#160; (For example, a web application that can function on-premise as well as a web role in Windows Azure.)&#160; In other words, they simply do not belong in the role projects.</p>  <p>The June 2012 (1.7) release introduces a new feature of Windows Azure projects: Role Content Folders.&#160; Role Content Folders are nodes within Solution Explorer to which you can add new or existing files and folders.&#160; These files will then be automatically added to the package and deployed to a consistent location on the virtual machine.&#160; The role node itself is a Role Content Folder; it represents the role’s root directory and files added to that node will be deployed to the APPROOT directory.&#160; Files added to folders added to the role node will be packaged and deployed in the same relative hierarchy.</p>  <p>To add a file, simply select the role node, right-click, and choose on of the commands from the Add submenu.</p>  <p>&#160;</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/85/27/metablogapi/6076.AddNewRoleContentItem_3D1EE43D.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-85-27-metablogapi/6076.AddNewRoleContentItem_5F00_3D1EE43D.png"><img title="AddNewRoleContentItem" style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="AddNewRoleContentItem" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/85/27/metablogapi/4403.AddNewRoleContentItem_thumb_2AD61D7B.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-85-27-metablogapi/4403.AddNewRoleContentItem_5F00_thumb_5F00_2AD61D7B.png" width="572" height="290" /></a></p>  <p>&#160;</p>  <p>Note that the only item templates we include are for basic text and XML files.</p>  <p>&#160;</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/85/27/metablogapi/1602.AddNewItem_51A433BB.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-85-27-metablogapi/1602.AddNewItem_5F00_51A433BB.png"><img title="AddNewItem" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="AddNewItem" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/85/27/metablogapi/5086.AddNewItem_thumb_1C97A48B.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-85-27-metablogapi/5086.AddNewItem_5F00_thumb_5F00_1C97A48B.png" width="568" height="399" /></a></p>  <p>Once added to a Role Content Folder, files and folders operate like any other you might find in a standard Visual Studio project.&#160; They can be added, removed, and renamed, and are also source code controlled.&#160; In this example, I’ve added two files to the web role, one directly to the web role node (i.e. APPROOT) and another in a subfolder.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/85/27/metablogapi/2671.RoleContentHierarchy_5C618B10.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-85-27-metablogapi/2671.RoleContentHierarchy_5F00_5C618B10.png"><img title="RoleContentHierarchy" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="RoleContentHierarchy" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/85/27/metablogapi/5327.RoleContentHierarchy_thumb_6A33D10B.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-85-27-metablogapi/5327.RoleContentHierarchy_5F00_thumb_5F00_6A33D10B.png" width="317" height="387" /></a></p>  <p>The following two screenshots are of the application folder for one of the web role instances.&#160; In them you can see the two files deployed to the same relative hierarchy as in the Windows Azure project.&#160; That’s all it takes to package arbitrary role content!</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/85/27/metablogapi/7043.AppRootFile_1101E74C.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-85-27-metablogapi/7043.AppRootFile_5F00_1101E74C.png"><img title="AppRootFile" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="AppRootFile" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/85/27/metablogapi/4403.AppRootFile_thumb_707AA799.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-85-27-metablogapi/4403.AppRootFile_5F00_thumb_5F00_707AA799.png" width="558" height="422" /></a></p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/85/27/metablogapi/7140.AppRootSubFolder_30448E1F.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-85-27-metablogapi/7140.AppRootSubFolder_5F00_30448E1F.png"><img title="AppRootSubFolder" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="AppRootSubFolder" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/85/27/metablogapi/1777.AppRootSubFolder_thumb_292551A7.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-85-27-metablogapi/1777.AppRootSubFolder_5F00_thumb_5F00_292551A7.png" width="560" height="423" /></a></p>  <p>You might be wondering how this all works.&#160; This new feature is actually based on an existing capability of the Windows Azure SDK.&#160; Since version 1.5 the Windows Azure SDK has supported the <a href="https://msdn.microsoft.com/en-us/library/windowsazure/gg557553#Contents">Contents element</a> in the service definition that indicates additional folders to include in the package and deploy to the virtual machine.&#160; The Tools simply did not have any tooling around this capability…until now.&#160; During packaging, the Tools will identify project content within Role Content Folders and inject the appropriate elements into the service definition so that CSPack will insert that content into the package.</p>  <p>Note: Be careful of how you name content in a Role Content Folder.&#160; Because this content is deployed to the role’s APPROOT directory—the same directory in which the role is deployed—there is the possibility of file name collisions.&#160; Be sure to use filenames in your Azure project that are unlikely to conflict with files belonging to the role project itself.</p>]]></content:encoded>
    </item>
    <item>
      <title>Finding DASL Property Names</title>
      <link>https://docs.microsoft.com/archive/blogs/philliphoff/finding-dasl-property-names</link>
      <pubDate>Fri, 19 Dec 2008 13:37:12 GMT</pubDate>
      <dc:creator><![CDATA[Phil Hoff - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/philliphoff/2008/12/19/finding-dasl-property-names/</guid>
      <description><![CDATA[The LINQ-to-DASL provider of the Office Interop API Extensions provides a very limited set of...]]></description>
      <content:encoded><![CDATA[<p>The LINQ-to-DASL provider of the Office Interop API Extensions provides a very limited set of mappings between its query types and their associated DASL properties.&#160; We didn't have the time to add them all and we didn't know which properties (besides the obvious ones like Subject and DateReceived) users would be most likely to use in their queries.&#160; Instead, we created an extensibility mechanism (the OutlookItemPropertyAttribute) that allowed users to add their own mappings to DASL properties.&#160; Now the problem becomes, where do we find these DASL property names?</p>  <p>You can find some of the property names amongst the MSDN Office and Exchange documentation, but many properties are missing and sometimes the documentation is misleading (e.g. a listed property may work when querying Exchange but not Outlook).&#160; Outlook supports another query syntax (Jet) that uses a different set of property names, making the documentation even more confusing.</p>  <p>The best approach that I have found is to go directly to the source.&#160; Outlook actually has a built-in DASL query builder, if only you know how to find it.&#160; Here's the trick: start with the View : Current View : Customize Current View menu item.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/ViewMenu.jpg" original-url="https://blogs.msdn.com/blogfiles/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/ViewMenu.jpg"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="ViewMenu" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/ViewMenu_thumb.jpg" original-url="https://blogs.msdn.com/blogfiles/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/ViewMenu_thumb.jpg" width="444" height="333" /></a> </p>  <p>This displays the Customize View Messages dialog.&#160; </p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/CustomizeCurrentView.jpg" original-url="https://blogs.msdn.com/blogfiles/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/CustomizeCurrentView.jpg"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="CustomizeCurrentView" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/CustomizeCurrentView_thumb.jpg" original-url="https://blogs.msdn.com/blogfiles/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/CustomizeCurrentView_thumb.jpg" width="482" height="332" /></a> </p>  <p>Next, click the Filter button.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/AdvancedTab.jpg" original-url="https://blogs.msdn.com/blogfiles/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/AdvancedTab.jpg"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="AdvancedTab" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/AdvancedTab_thumb.jpg" original-url="https://blogs.msdn.com/blogfiles/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/AdvancedTab_thumb.jpg" width="423" height="318" /></a> </p>  <p>The filter dialog allows you to filter messages in a folder by a variety of criteria.&#160; Select the Advanced tab.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/FieldMenu_2.jpg" original-url="https://blogs.msdn.com/blogfiles/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/FieldMenu_2.jpg"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="FieldMenu" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/FieldMenu_thumb.jpg" original-url="https://blogs.msdn.com/blogfiles/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/FieldMenu_thumb.jpg" width="478" height="351" /></a> </p>  <p>Now use the Field button to select the Outlook item property you are interested in.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/FieldConditionAndValue.jpg" original-url="https://blogs.msdn.com/blogfiles/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/FieldConditionAndValue.jpg"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="FieldConditionAndValue" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/FieldConditionAndValue_thumb.jpg" original-url="https://blogs.msdn.com/blogfiles/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/FieldConditionAndValue_thumb.jpg" width="423" height="318" /></a> </p>  <p>You can then select the condition and a value.&#160; Click the Add to List button to add the criteria to the filter.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/CriteriaAdded.jpg" original-url="https://blogs.msdn.com/blogfiles/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/CriteriaAdded.jpg"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="CriteriaAdded" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/CriteriaAdded_thumb.jpg" original-url="https://blogs.msdn.com/blogfiles/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/CriteriaAdded_thumb.jpg" width="423" height="318" /></a></p>  <p>Finally, select the SQL tab to see the DASL.&#160; </p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/SqlTab.jpg" original-url="https://blogs.msdn.com/blogfiles/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/SqlTab.jpg"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="SqlTab" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/SqlTab_thumb.jpg" original-url="https://blogs.msdn.com/blogfiles/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/SqlTab_thumb.jpg" width="423" height="318" /></a>&#160; </p>  <p>In this case, we see that the DASL property associated with the Modified time of an appointment is &quot;DAV:getlastmodified&quot;.&#160; To cut and paste the query string elsewhere (e.g. to Notepad, so you can compare the query string to the <a href="https://blogs.msdn.com/philliphoff/archive/2008/12/18/debugging-linq-to-dasl-queries.aspx">debug output of your LINQ-to-DASL query</a>), check the box at the bottom of the tab.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/SelectedDasl.jpg" original-url="https://blogs.msdn.com/blogfiles/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/SelectedDasl.jpg"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="SelectedDasl" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/SelectedDasl_thumb.jpg" original-url="https://blogs.msdn.com/blogfiles/philliphoff/WindowsLiveWriter/FindingDASLPropertyNames_945A/SelectedDasl_thumb.jpg" width="423" height="318" /></a></p>]]></content:encoded>
    </item>
    <item>
      <title>Debugging LINQ-to-DASL Queries</title>
      <link>https://docs.microsoft.com/archive/blogs/philliphoff/debugging-linq-to-dasl-queries</link>
      <pubDate>Thu, 18 Dec 2008 15:19:49 GMT</pubDate>
      <dc:creator><![CDATA[Phil Hoff - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/philliphoff/2008/12/18/debugging-linq-to-dasl-queries/</guid>
      <description><![CDATA[When your LINQ-to-DASL queries do not return the results you expect, how do you determine where the...]]></description>
      <content:encoded><![CDATA[<p>When your LINQ-to-DASL queries do not return the results you expect, how do you determine where the problem is?&#160; The issue could be that the query simply doesn't do what you expect.&#160; For example, you could be querying the wrong DASL properties and therefore Outlook returns no (or unexpected) items.&#160; (This is easy to do, as DASL property names can be difficult to identify and map to the equivalent Outlook object model property.)&#160; It could also be that the DASL query syntax itself is incorrect or the LINQ-to-DASL provider did not manage the query results property.</p>  <p>Fortunately, the LINQ-to-DASL provider offers a way to gain a little insight into what it is actually doing.&#160; You can attach a logger to the provider that will be passed the exact DASL string passed to Outlook when the query is executed.</p>  <p>Let's say we want to find all appointments that have been modified in the last week.&#160; That is, where the LastModifiedTime is within the last seven days.&#160; First, we'll define a custom class on which to perform the query.&#160; (We do this because the built-in Appointment query class does not have LastModifiedTime.)</p>  <pre class="code"><span style="color: blue">public class </span><span style="color: #2b91af">MyAppointment </span>: <span style="color: #2b91af">Appointment
</span>{
    [<span style="color: #2b91af">OutlookItemProperty</span>(<span style="color: #a31515">&quot;DAV:getlastmodified&quot;</span>)]
    <span style="color: blue">public </span><span style="color: #2b91af">DateTime </span>LastModifiedTime { <span style="color: blue">get </span>{ <span style="color: blue">return </span>Item.LastModificationTime; } }
}</pre>

<p>Next, we'll create a method that generates the query.</p>

<pre class="code"><span style="color: blue">private </span><span style="color: #2b91af">IEnumerable</span>&lt;Outlook.<span style="color: #2b91af">AppointmentItem</span>&gt; CreateQueryWithoutDebuggingInformation(Outlook.<span style="color: #2b91af">Items </span>items, <span style="color: #2b91af">DateTime </span>oldestDate)
{
    <span style="color: blue">var </span>query = <span style="color: blue">from </span>item <span style="color: blue">in </span>items.AsQueryable&lt;<span style="color: #2b91af">MyAppointment</span>&gt;()
                <span style="color: blue">where </span>item.LastModifiedTime &gt; oldestDate.ToUniversalTime()
                <span style="color: blue">select </span>item.Item;

    <span style="color: blue">return </span>query;
}</pre>

<p>The method takes the items collection on which the query is to be performed and the date we wish to filter by.&#160; Note that there is nothing special about this LINQ-to-DASL query at this point.</p>

<p>Finally, we'll write the method to execute the query and show the results.</p>

<pre class="code"><span style="color: blue">private void </span>ThisAddIn_Startup(<span style="color: blue">object </span>sender, System.<span style="color: #2b91af">EventArgs </span>e)
{
    Outlook.<span style="color: #2b91af">Folder </span>folder = (Outlook.<span style="color: #2b91af">Folder</span>)Application.Session.GetDefaultFolder(Outlook.<span style="color: #2b91af">OlDefaultFolders</span>.olFolderCalendar);
    <span style="color: #2b91af">DateTime </span>oldestDate = <span style="color: #2b91af">DateTime</span>.Now.AddDays(-7);

    <span style="color: blue">var </span>query = CreateQueryWithoutDebuggingInformation(folder.Items, oldestDate);

    <span style="color: blue">foreach </span>(<span style="color: blue">var </span>appt <span style="color: blue">in </span>query)
    {
        <span style="color: blue">if </span>(<span style="color: #2b91af">MessageBox</span>.Show(appt.Subject, <span style="color: #a31515">&quot;Appointment Found!&quot;</span>, <span style="color: #2b91af">MessageBoxButtons</span>.OKCancel) == <span style="color: #2b91af">DialogResult</span>.Cancel)
        {
            <span style="color: blue">break</span>;
        }
    }
}</pre>

<p>The method simply retrieves the Calendar folder, calls the query creation method, and then iterates over the results.&#160; If the query doesn't return any items, or returns items that you do not expect, what do we do next?&#160; The answer is to modify our query by attaching a logger so that we can see the generated DASL.</p>

<p>First, we'll create a simple logger that writes to the debugger output window.</p>

<pre class="code"><span style="color: blue">internal class </span><span style="color: #2b91af">DebuggerWriter </span>: <span style="color: #2b91af">TextWriter
</span>{
    <span style="color: blue">public override </span><span style="color: #2b91af">Encoding </span>Encoding
    {
        <span style="color: blue">get </span>{ <span style="color: blue">throw new </span><span style="color: #2b91af">NotImplementedException</span>(); }
    }

    <span style="color: blue">public override void </span>WriteLine(<span style="color: blue">string </span>value)
    {
        <span style="color: #2b91af">Debug</span>.WriteLine(value);
    }
}</pre>

<p>The logger can be any TextWriter-derived class.&#160; Note that the Encoding property must be overridden, but need not actually be implemented.</p>

<p>Next, we'll create a new query generation method.</p>

<pre class="code"><span style="color: blue">private </span><span style="color: #2b91af">IEnumerable</span>&lt;Outlook.<span style="color: #2b91af">AppointmentItem</span>&gt; CreateQueryWithDebuggingInformation(Outlook.<span style="color: #2b91af">Items </span>items, <span style="color: #2b91af">DateTime </span>oldestDate)
{
    <span style="color: blue">var </span>source = <span style="color: blue">new </span><span style="color: #2b91af">ItemsSource</span>&lt;<span style="color: #2b91af">MyAppointment</span>&gt;(items)
    {
        Log = <span style="color: blue">new </span><span style="color: #2b91af">DebuggerWriter</span>()
    };

    <span style="color: blue">var </span>query = <span style="color: blue">from </span>item <span style="color: blue">in </span>source
                <span style="color: blue">where </span>item.LastModifiedTime &gt; oldestDate.ToUniversalTime()
                <span style="color: blue">select </span>item.Item;

    <span style="color: blue">return </span>query;
}</pre>

<p>Notice that the query itself (the from, where, and select) is virtually identical to the previous query.&#160; The only difference is that we explicitly create a ItemsSource.&#160; (This is what AsQueryable() did implicitly in the previous query.)&#160; We then attach an instance of our logger.</p>

<p>Finally, we update our query execution method.</p>

<pre class="code"><span style="color: blue">private void </span>ThisAddIn_Startup(<span style="color: blue">object </span>sender, System.<span style="color: #2b91af">EventArgs </span>e)
{
    Outlook.<span style="color: #2b91af">Folder </span>folder = (Outlook.<span style="color: #2b91af">Folder</span>)Application.Session.GetDefaultFolder(Outlook.<span style="color: #2b91af">OlDefaultFolders</span>.olFolderCalendar);
    <span style="color: #2b91af">DateTime </span>oldestDate = <span style="color: #2b91af">DateTime</span>.Now.AddDays(-7);

    <span style="color: green">//var query = CreateQueryWithoutDebuggingInformation(folder.Items, oldestDate);
    </span><span style="color: blue">var </span>query = CreateQueryWithDebuggingInformation(folder.Items, oldestDate);

    <span style="color: blue">foreach </span>(<span style="color: blue">var </span>appt <span style="color: blue">in </span>query)
    {
        <span style="color: blue">if </span>(<span style="color: #2b91af">MessageBox</span>.Show(appt.Subject, <span style="color: #a31515">&quot;Appointment Found!&quot;</span>, <span style="color: #2b91af">MessageBoxButtons</span>.OKCancel) == <span style="color: #2b91af">DialogResult</span>.Cancel)
        {
            <span style="color: blue">break</span>;
        }
    }
}</pre>

<p>The only change here was to call the new query generation method.&#160; Now when we run the code in the debugger, we'll see the following in our output window:</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/philliphoff/WindowsLiveWriter/DebuggingLINQtoDASLQueries_A85E/DebugOutput.jpg" original-url="https://blogs.msdn.com/blogfiles/philliphoff/WindowsLiveWriter/DebuggingLINQtoDASLQueries_A85E/DebugOutput.jpg"><img alt="DebugOutput" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/philliphoff/WindowsLiveWriter/DebuggingLINQtoDASLQueries_A85E/DebugOutput_thumb.jpg" original-url="https://blogs.msdn.com/blogfiles/philliphoff/WindowsLiveWriter/DebuggingLINQtoDASLQueries_A85E/DebugOutput_thumb.jpg" width="633" height="267" /></a></p>

<p>You can see the exact DASL filter string sent to Outlook when the query was executed.&#160; You can use this to verify that the DASL property names, syntax, and values all look correct.&#160; You can also compare this filter string to the string built using the advanced filtration dialog in Outlook.</p>]]></content:encoded>
    </item>
    <item>
      <title>Filter Outlook Items by Date with LINQ to DASL</title>
      <link>https://docs.microsoft.com/archive/blogs/philliphoff/filter-outlook-items-by-date-with-linq-to-dasl</link>
      <pubDate>Mon, 03 Mar 2008 22:02:00 GMT</pubDate>
      <dc:creator><![CDATA[Phil Hoff - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/philliphoff/2008/03/03/filter-outlook-items-by-date-with-linq-to-dasl/</guid>
      <description><![CDATA[I received an email over the weekend asking why the following LINQ to DASL query threw an exception:...]]></description>
      <content:encoded><![CDATA[<P>I received an email over the weekend asking why the following LINQ to DASL query threw an exception: </P>
<BLOCKQUOTE>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New">Outlook.<SPAN style="COLOR: #2b91af">Folder</SPAN> folder = (Outlook.<SPAN style="COLOR: #2b91af">Folder</SPAN>)Application.Session.GetDefaultFolder(Outlook.<SPAN style="COLOR: #2b91af">OlDefaultFolders</SPAN>.olFolderCalendar); </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: blue">var</SPAN> appointments = </SPAN></P>
<BLOCKQUOTE>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: blue">from</SPAN> item <SPAN style="COLOR: blue">in</SPAN> folder.Items.AsQueryable&lt;<SPAN style="COLOR: #2b91af">Appointment</SPAN>&gt;() </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: blue">where</SPAN> item.Categories.Contains(<SPAN style="COLOR: #a31515">"Personal Appointments"</SPAN>) &amp;&amp; item.Item.Start.Date &gt;= <SPAN style="COLOR: #2b91af">DateTime</SPAN>.Now - <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: #2b91af">TimeSpan</SPAN>(30, 0, 0, 0) </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: blue">select</SPAN> item.Item; </SPAN></P></BLOCKQUOTE>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: blue">foreach</SPAN> (<SPAN style="COLOR: blue">var</SPAN> appointment <SPAN style="COLOR: blue">in</SPAN> appointments) </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New">{ </SPAN></P>
<BLOCKQUOTE>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: #2b91af">MessageBox</SPAN>.Show(appointment.Start.ToString()); </SPAN></P></BLOCKQUOTE>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New">} </SPAN></P></BLOCKQUOTE>
<P>The query looks simple enough—return all personal appointments for the last 30 days—but when the foreach loop executes a MissingPropertyAttributeException is thrown stating "The property Date on class DateTime does not have an attached OutlookItemUserPropertyAttribute". The problem here is that (as the exception indicates) the Appointment.Item.Start.Date property does not have an OutlookItemProperty or OutlookItemUserProperty attached. These attributes are used by LINQ to DASL to map properties defined on .NET classes to DASL properties defined by Outlook. Why doesn't this attribute exist? Appointment.Item is of type Microsoft.Office.Interop.Outlook.AppointmentItem. This type is part of the Outlook object model and defined by the Outlook PIA. Unfortunately, since we have no control over the Office PIAs, we can't markup the types with our LINQ to DASL attributes. This means that we can't directly query properties on Outlook items. Instead, we query properties on a proxy class (i.e. Appointment) that we do have control over. </P>
<P>But wait a minute…the Appointment class doesn't have a Start property! Yes, unfortunately we weren't able to map every known DASL property to its Outlook item equivalent for this initial release (only so many hours in the day and all that). We did, however, provide a way for you to add such properties yourself. </P>
<BLOCKQUOTE>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: blue">internal</SPAN> <SPAN style="COLOR: blue">class</SPAN> <SPAN style="COLOR: #2b91af">MyAppointment</SPAN> : <SPAN style="COLOR: #2b91af">Appointment </SPAN></SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New">{ </SPAN></P>
<BLOCKQUOTE>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New">[<SPAN style="COLOR: #2b91af">OutlookItemProperty</SPAN>(<SPAN style="COLOR: #a31515">"urn:schemas:calendar:dtstart"</SPAN>)] </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: blue">public</SPAN> <SPAN style="COLOR: #2b91af">DateTime</SPAN> Start { <SPAN style="COLOR: blue">get</SPAN> { <SPAN style="COLOR: blue">return</SPAN> Item.Start; } } </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New">[<SPAN style="COLOR: #2b91af">OutlookItemProperty</SPAN>(<SPAN style="COLOR: #a31515">"urn:schemas:calendar:dtend"</SPAN>)] </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: blue">public</SPAN> <SPAN style="COLOR: #2b91af">DateTime</SPAN> End { <SPAN style="COLOR: blue">get</SPAN> { <SPAN style="COLOR: blue">return</SPAN> Item.End; } } </SPAN></P></BLOCKQUOTE>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New">} </SPAN></P></BLOCKQUOTE>
<P>The MyAppointment class above derives from the existing Appointment class and adds two new properties, Start and End. These properties simply defer to the inner Item's Start and End properties. Each property has an OutlookItemPropertyAttribute attached that maps the property to its corresponding DASL property, which can be found using the handy SQL tab of Outlook's custom filter dialog. Next, the query can be revised as follows: </P>
<BLOCKQUOTE>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New">Outlook.<SPAN style="COLOR: #2b91af">Folder</SPAN> folder = (Outlook.<SPAN style="COLOR: #2b91af">Folder</SPAN>)Application.Session.GetDefaultFolder(Outlook.<SPAN style="COLOR: #2b91af">OlDefaultFolders</SPAN>.olFolderCalendar); </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: blue">var</SPAN> appointments = </SPAN></P>
<BLOCKQUOTE>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: blue">from</SPAN> item <SPAN style="COLOR: blue">in</SPAN> folder.Items.AsQueryable&lt;<SPAN style="COLOR: #2b91af">MyAppointment</SPAN>&gt;() </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: blue">where</SPAN> item.Categories.Contains(<SPAN style="COLOR: #a31515">"Personal Appointments"</SPAN>) &amp;&amp; item.Start &gt;= <SPAN style="COLOR: #2b91af">DateTime</SPAN>.Now - <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: #2b91af">TimeSpan</SPAN>(30, 0, 0, 0) </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: blue">select</SPAN> item.Item; </SPAN></P></BLOCKQUOTE>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: blue">foreach</SPAN> (<SPAN style="COLOR: blue">var</SPAN> appointment <SPAN style="COLOR: blue">in</SPAN> appointments) </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New">{ </SPAN></P>
<BLOCKQUOTE>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: #2b91af">MessageBox</SPAN>.Show(appointment.Start.ToString()); </SPAN></P></BLOCKQUOTE>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New">} </SPAN></P></BLOCKQUOTE>
<P>Note that the AsQueryable&lt;T&gt;() extension method now uses the new MyAppointment type and that its Start property is used instead of Item.Start.Date. Run the query again and Outlook should return a collection of appointments instead of an exception (presuming you have any appointments which match the query).</P>]]></content:encoded>
    </item>
    <item>
      <title>LINQ to DASL Walkthrough</title>
      <link>https://docs.microsoft.com/archive/blogs/philliphoff/linq-to-dasl-walkthrough</link>
      <pubDate>Mon, 25 Feb 2008 21:44:00 GMT</pubDate>
      <dc:creator><![CDATA[Phil Hoff - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/philliphoff/2008/02/25/linq-to-dasl-walkthrough/</guid>
      <description><![CDATA[Now that the Office Interop API Extensions have been released, I thought I would post a complete...]]></description>
      <content:encoded><![CDATA[<P>Now that the Office Interop API Extensions have been <A href="https://blogs.msdn.com/philliphoff/archive/2008/02/21/office-interop-api-extensions-now-available.aspx" mce_href="https://blogs.msdn.com/philliphoff/archive/2008/02/21/office-interop-api-extensions-now-available.aspx">released</A>, I thought I would post a complete walkthrough of a simple LINQ to DASL application. Let's start with my fictitious Outlook calendar: </P>
<P mce_keep="true"><IMG style="WIDTH: 725px; HEIGHT: 756px" height=756 src="https://nvmabg.tuk.livefilestore.com/y1p6OOMYIkLAB349vPAdzkuz8M4gSW9b7f7GH3YSqnBQam3Xzyh5xLJXstYfGMhnmq7JkTiIp4dY1Hq3MdgFZDdazpdnnuMiCAz/AppointmentsView.JPG" width=725 mce_src="https://nvmabg.tuk.livefilestore.com/y1p6OOMYIkLAB349vPAdzkuz8M4gSW9b7f7GH3YSqnBQam3Xzyh5xLJXstYfGMhnmq7JkTiIp4dY1Hq3MdgFZDdazpdnnuMiCAz/AppointmentsView.JPG"></P>
<P>This calendar shows that I have four appointments today. The appointments have been categorized as either "Work" (blue) or "Personal" (green). Suppose I would like to create an Outlook add-in that displays my personal appointments on startup. I will first create a new C#-based Outlook 2007 Add-in project in Visual Studio 2008. </P>
<P mce_keep="true"><IMG style="WIDTH: 697px; HEIGHT: 478px" height=478 src="https://nvmabg.tuk.livefilestore.com/y1p6OOMYIkLAB0jpqmKoYm-1FEp9D_63KJDXAB8DM9yPIzT-cFRfb286jA2oJ_YXI-28L-gLA99w_mg5TIh945JR1DJi4Ij7Vgo/NewProject.JPG" width=697 mce_src="https://nvmabg.tuk.livefilestore.com/y1p6OOMYIkLAB0jpqmKoYm-1FEp9D_63KJDXAB8DM9yPIzT-cFRfb286jA2oJ_YXI-28L-gLA99w_mg5TIh945JR1DJi4Ij7Vgo/NewProject.JPG"></P>
<P>Next I'll add a reference to one of the Outlook extension assemblies, which were installed as part of the Office Interop API Extensions. I'll select version 12.0.0.0 of the assembly because I'm using Outlook 2007. Version 11.0.0.0 of the assembly would be used with Outlook 2003. </P>
<P mce_keep="true"><IMG src="https://nvmabg.tuk.livefilestore.com/y1p6OOMYIkLAB0POz6cH0FADoJn8jBJp5iIZlxKcMtraplOg4ERs_43Pk38IHm7_q2x5mSeYUA7rEe0kBepUsujhBZutEngnhKH/AddReference.JPG" mce_src="https://nvmabg.tuk.livefilestore.com/y1p6OOMYIkLAB0POz6cH0FADoJn8jBJp5iIZlxKcMtraplOg4ERs_43Pk38IHm7_q2x5mSeYUA7rEe0kBepUsujhBZutEngnhKH/AddReference.JPG"></P>
<P>Before they can be used, I have to tell the compiler to look for the extensions during build. I'll do that through a set of using statements at the beginning of my source file. </P>
<P mce_keep="true"><IMG src="https://nvmabg.tuk.livefilestore.com/y1p6OOMYIkLAB3LdjJasY-aCIl8Oz9cek0sEw7Wu4tv1TTzmBdfIxD1YR6NLtGfytmhlAFfqPByF1PpLObVYT0_o6N_FQ7JrUcA/AddUsingStatements.JPG" mce_src="https://nvmabg.tuk.livefilestore.com/y1p6OOMYIkLAB3LdjJasY-aCIl8Oz9cek0sEw7Wu4tv1TTzmBdfIxD1YR6NLtGfytmhlAFfqPByF1PpLObVYT0_o6N_FQ7JrUcA/AddUsingStatements.JPG"></P>
<P>Two using statements are required: </P>
<UL>
<LI>
<DIV><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Courier New">using</SPAN><SPAN style="FONT-FAMILY: Consolas"> </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New">Microsoft.Office.Interop.Outlook.Extensions;</SPAN><SPAN style="FONT-FAMILY: Consolas"> </SPAN></DIV>
<P>This statement brings in the Items.AsQueryable&lt;T&gt;() extension method that I'll use in my LINQ expression. </P></LI>
<LI>
<DIV><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Courier New">using</SPAN><SPAN style="FONT-FAMILY: Consolas"> </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New">Microsoft.Office.Interop.Outlook.Extensions.Linq;</SPAN><SPAN style="FONT-FAMILY: Consolas"> </SPAN></DIV>
<P>This statement brings in the LINQ to DASL types that form the basis for my LINQ expression. </P></LI></UL>
<P>With that, I can then write my LINQ expression in the startup event handler of the add-in: </P>
<P style="MARGIN-LEFT: 36pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: blue">private</SPAN> <SPAN style="COLOR: blue">void</SPAN> ThisAddIn_Startup(<SPAN style="COLOR: blue">object</SPAN> sender, System.<SPAN style="COLOR: #2b91af">EventArgs</SPAN> e) </SPAN></P>
<P style="MARGIN-LEFT: 36pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New">{ </SPAN></P>
<BLOCKQUOTE>
<P style="MARGIN-LEFT: 36pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New">Outlook.<SPAN style="COLOR: #2b91af">Folder</SPAN> folder = (Outlook.<SPAN style="COLOR: #2b91af">Folder</SPAN>) Application.Session.GetDefaultFolder(Outlook.<SPAN style="COLOR: #2b91af">OlDefaultFolders</SPAN>.olFolderCalendar); </SPAN></P>
<P style="MARGIN-LEFT: 36pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: blue">var</SPAN> appointments = </SPAN></P>
<BLOCKQUOTE>
<P style="MARGIN-LEFT: 36pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: blue">from</SPAN> item <SPAN style="COLOR: blue">in</SPAN> folder.Items.AsQueryable&lt;<SPAN style="COLOR: #2b91af">Appointment</SPAN>&gt;() </SPAN></P>
<P style="MARGIN-LEFT: 36pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: blue">where</SPAN> item.Categories.Contains(<SPAN style="COLOR: #a31515">"Personal"</SPAN>) </SPAN></P>
<P style="MARGIN-LEFT: 36pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: blue">select</SPAN> item.Item; </SPAN></P></BLOCKQUOTE>
<P style="MARGIN-LEFT: 36pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: blue">var</SPAN> builder = <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: #2b91af">StringBuilder</SPAN>(); </SPAN></P>
<P style="MARGIN-LEFT: 36pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New">builder.AppendLine(<SPAN style="COLOR: #a31515">"Personal Appointments:"</SPAN>); </SPAN></P>
<P style="MARGIN-LEFT: 36pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New">builder.AppendLine(); </SPAN></P>
<P style="MARGIN-LEFT: 36pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: blue">foreach</SPAN> (<SPAN style="COLOR: blue">var</SPAN> appointment <SPAN style="COLOR: blue">in</SPAN> appointments) </SPAN></P>
<P style="MARGIN-LEFT: 36pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New">{ </SPAN></P>
<BLOCKQUOTE>
<P style="MARGIN-LEFT: 36pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New">builder.AppendLine(appointment.Subject); </SPAN></P></BLOCKQUOTE>
<P style="MARGIN-LEFT: 36pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New">} </SPAN></P>
<P style="MARGIN-LEFT: 36pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: #2b91af">MessageBox</SPAN>.Show(builder.ToString()); </SPAN></P></BLOCKQUOTE>
<P style="MARGIN-LEFT: 36pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New">} </SPAN></P>
<P>Let's look at this query more closely. The first clause "<SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: blue">from</SPAN> item <SPAN style="COLOR: blue">in</SPAN> folder.Items.AsQueryable&lt;<SPAN style="COLOR: #2b91af">Appointment</SPAN>&gt;()</SPAN>" uses the new Items.AsQueryable&lt;T&gt; extension method. This extension method simply returns a new instance of the ItemsSource&lt;T&gt; class, which implements the LINQ interfaces IQueryProvider and IQueryable. I know this folder contains only appointments, so I specify the Appointment class for the generic type. The Appointment class is the LINQ to DASL class associated with the AppointmentItem interface in Outlook. If the folder contained a mixture of Outlook item types (such as both appointments and meetings), I would either need to use the more generic OutlookItem class or use the MessageClass property in my query to restrict the types of the items returned. </P>
<P>The second clause "<SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: blue">where</SPAN> item.Categories.Contains(<SPAN style="COLOR: #a31515">"Personal"</SPAN>)</SPAN>" is the "meat" of the query. This is the expression translated into a DASL query string and passed to Outlook. Outlook then returns a collection of Items matching the query string. In this case, I want Outlook to return only items where the categories property contains the string "Personal". The where clause can contain a number of different types of expressions: </P>
<UL>
<LI>The typical set of comparisons (==, !=, &lt;, &lt;=, &gt;=, &gt;, &amp;&amp;, ||) </LI>
<LI>Negation (!) </LI>
<LI>Method calls on properties using String.Contains(), String.StartsWith(), and String.EndsWith() </LI>
<LI>Expressions involving user properties (e.g. item.UserProperties["Foo"].Value) </LI></UL>
<P>The last clause "<SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"><SPAN style="COLOR: blue">select</SPAN> item.Item</SPAN>" specifies what items to return from the query. LINQ to DASL will wrap each item returned by Outlook with an instance of the type specified in the AsQueryable&lt;T&gt;() extension method. That instance can be returned as-is, or a projection on that instance can be returned instead. I want the original AppointmentItem instance returned by Outlook so I specify a simple projection that returns the Item property on the Appointment class. The select clause also determines the ultimate type of the returned data, IEnumerable&lt;Outlook.AppointmentItem&gt; in this case. This is what I iterate over in my foreach loop. </P>
<P>Finally, I can hit 'F5' and see the results. </P>
<P mce_keep="true"><IMG src="https://nvmabg.tuk.livefilestore.com/y1p6OOMYIkLAB0Qr6tOxr9HkoenpJgVsh2Pn3av3F_j1V-f0nKVuqU0tsbliJNsvNo3zs6BbJd15MXaNZqCnmFPIgnZ6ZYhZEja/Output.JPG" mce_src="https://nvmabg.tuk.livefilestore.com/y1p6OOMYIkLAB0Qr6tOxr9HkoenpJgVsh2Pn3av3F_j1V-f0nKVuqU0tsbliJNsvNo3zs6BbJd15MXaNZqCnmFPIgnZ6ZYhZEja/Output.JPG"></P>
<P>Hopefully this helps people get started with LINQ to DASL. (If it doesn't, please let me know what else I can cover to make things more clear.) This sample can be found on Code Gallery <A href="https://code.msdn.microsoft.com/Release/ProjectReleases.aspx?ProjectName=OfficeExtensions&amp;ReleaseId=527" mce_href="https://code.msdn.microsoft.com/Release/ProjectReleases.aspx?ProjectName=OfficeExtensions&amp;ReleaseId=527">here</A>.</P>]]></content:encoded>
    </item>
    <item>
      <title>Parameterized Properties and the Office Interop API Extensions</title>
      <link>https://docs.microsoft.com/archive/blogs/philliphoff/parameterized-properties-and-the-office-interop-api-extensions</link>
      <pubDate>Thu, 21 Feb 2008 21:16:24 GMT</pubDate>
      <dc:creator><![CDATA[Phil Hoff - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/philliphoff/2008/02/21/parameterized-properties-and-the-office-interop-api-extensions/</guid>
      <description><![CDATA[One of the disadvantages of C# compared with VB is its lack of support for parameterized properties....]]></description>
      <content:encoded><![CDATA[<p>One of the disadvantages of C# compared with VB is its lack of support for parameterized properties.  Instead, parameterized properties in C# are exposed as normal method calls prefixed with "get_" and "set_".  This is particularly apparent when working with the Office object model as it exposes many such properties, the majority being indexers on collection interfaces.  To make matters worse, some collection interfaces have array indexers rather than indexer properties, which make indexing inconsistent between collection types.  Since many of the parameters are optional or accept varying types, we lose many of the strong typing benefits of the C# language.  The end result is inconsistent, inelegant, and error prone code.
</p><p>Let's take the Documents collection in Word for example.  That interface defines the Item property with a single variant (i.e. object) argument.  According to the MSDN documentation, that argument value should be an integer or a string.  Retrieving a document by integer index looks something like:
</p><p><span style="font-family:Courier New; font-size:10pt">
			<span style="color:blue">object</span> index = 1;
</span></p><p>
 </p><p><span style="font-family:Courier New; font-size:10pt">            Word.<span style="color:#2b91af">Document</span> doc = Application.Documents.get_Item(<span style="color:blue">ref</span> index);
</span></p><p>
 </p><p><span style="font-family:Courier New; font-size:10pt">
			<span style="color:#2b91af">MessageBox</span>.Show(<span style="color:#a31515">"Name: "</span> + doc.Name);
</span></p><p>
 </p><p>Notice the use of 1 instead of 0; remember that the Office object model uses 1-based indexing.  Also note that we have to pass the index by reference, requiring an extra object on the stack.  This is a particular quirk of the Word object model, but one that makes for even more inelegant code.
</p><p>Retrieving a document by name looks something like:
</p><p><span style="font-family:Courier New; font-size:10pt">
			<span style="color:blue">object</span> index = <span style="color:#a31515">"WordDocument1.docx"</span>;
</span></p><p>
 </p><p><span style="font-family:Courier New; font-size:10pt">            Word.<span style="color:#2b91af">Document</span> doc = Application.Documents.get_Item(<span style="color:blue">ref</span> index);
</span></p><p>
 </p><p><span style="font-family:Courier New; font-size:10pt">
			<span style="color:#2b91af">MessageBox</span>.Show(<span style="color:#a31515">"Name: "</span> + doc.Name);
</span></p><p>
 </p><p>Let's clean up these examples using the Office Interop API Extensions, one of the recently released <a href="https://www.microsoft.com/downloads/details.aspx?FamilyId=46B6BF86-E35D-4870-B214-4D7B72B02BF9&amp;displaylang=en">VSTO Power Tools</a>.  For collections, the libraries expose a set of common Item() extension methods with strongly-typed arguments.  With those we can rewrite our examples:
</p><p><span style="font-family:Courier New; font-size:10pt">            Word.<span style="color:#2b91af">Document</span> doc = Application.Documents.Item(1);
</span></p><p>
 </p><p><span style="font-family:Courier New; font-size:10pt">
			<span style="color:#2b91af">MessageBox</span>.Show(<span style="color:#a31515">"Name: "</span> + doc.Name);
</span></p><p>
 </p><p>And:
</p><p><span style="font-family:Courier New; font-size:10pt">            Word.<span style="color:#2b91af">Document</span> doc = Application.Documents.Item(<span style="color:#a31515">"WordDocument1.docx"</span>);
</span></p><p>
 </p><p><span style="font-family:Courier New; font-size:10pt">
			<span style="color:#2b91af">MessageBox</span>.Show(<span style="color:#a31515">"Name: "</span> + doc.Name);
</span></p><p>
 </p><p>Unfortunately, not all of the collections could be extended in the initial release of the VSTO Power Tools.  You will find the Word and Excel object models to be most complete, with key collections extended across the rest of the Office suite.  (If there are particular collections which you think should be extended in the future, please let us know so that we can prioritize them appropriately.)
</p><p>Indexers are not the only parameterized properties which were extended, however.  Let's take another example from Excel:
</p><p><span style="font-family:Courier New; font-size:10pt">            Excel.<span style="color:#2b91af">Worksheet</span> sheet = InnerObject;
</span></p><p><span style="font-family:Courier New; font-size:10pt">            Excel.<span style="color:#2b91af">Range</span> range1 = sheet.get_Range(<span style="color:#a31515">"A1:B1"</span>, System.<span style="color:#2b91af">Type</span>.Missing);
</span></p><p><span style="font-family:Courier New; font-size:10pt">            Excel.<span style="color:#2b91af">Range</span> range2 = sheet.get_Range(<span style="color:#a31515">"A1"</span>, <span style="color:#a31515">"B2"</span>);
</span></p><p>
 </p><p>In this example, we're retrieving two ranges from an Excel Worksheet.  The Range property (as defined by the COM interface) accepts two parameters, both of which are of variant type and the second of which is also marked optional.  Since C# doesn't support optional parameters, we have to pass System.Type.Missing to indicate the absence of the second value.  Since both values are variant types, we do not have any compile-time type checking.  Again, we can use the extensions provided by the Office Interop API Extensions to improve the code:
</p><p><span style="font-family:Courier New; font-size:10pt">            Excel.<span style="color:#2b91af">Worksheet</span> sheet = InnerObject;
</span></p><p><span style="font-family:Courier New; font-size:10pt">            Excel.<span style="color:#2b91af">Range</span> range1 = sheet.Range(<span style="color:#a31515">"A1:B1"</span>);
</span></p><p><span style="font-family:Courier New; font-size:10pt">            Excel.<span style="color:#2b91af">Range</span> range2 = sheet.Range(<span style="color:#a31515">"A1"</span>, <span style="color:#a31515">"B2"</span>);
</span></p><p>
 </p><p>Not only have we eliminated the ugly "get_" and the need to specify System.Type.Missing, our arguments are conveniently strongly-typed.  These may seem like little things, but over the long term I think the improved readability and additional compile-time support will make for a better Office development experience for the C# developer.
</p>]]></content:encoded>
    </item>
  </channel>
</rss>