<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Distributed Matters</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/carlos/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/carlos/feed.xml</link>
    <description>Troubleshooting issues in technologies available to developers for building distributed applications</description>
    <lastBuildDate>Tue, 16 Apr 2019 04:51:18 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>SocketException: “a non-blocking socket operation could not be completed immediately” with .Net Remoting</title>
      <link>https://docs.microsoft.com/archive/blogs/carlos/socketexception-a-non-blocking-socket-operation-could-not-be-completed-immediately-with-net-remoting</link>
      <pubDate>Mon, 05 Feb 2018 14:16:28 GMT</pubDate>
      <dc:creator><![CDATA[Carlo_Colombo]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/carlos/?p=765</guid>
      <description><![CDATA[If you are using .Net Remoting with the TCP channel, you may get the error SocketException: “a...]]></description>
      <content:encoded><![CDATA[<p><font size="2">If you are using .Net Remoting with the </font><a href="https://msdn.microsoft.com/en-us/library/system.runtime.remoting.channels.tcp.tcpchannel(v=vs.110).aspx"><font size="2">TCP channel</font></a><font size="2">, you may get the error SocketException: “a non-blocking socket operation could not be completed immediately” under some specific conditions.</font></p><p><font size="2">The underlying socket error code is SocketError.WouldBlock(10035). This is defined as WSAWOULDBLOCK in he Platform SDK header files:</font><!-- HTML generated using hilite.me --><div><pre style="margin: 0px;line-height: 125%"><span>#define WSABASEERR              10000</span>
...
<span>#define WSAEWOULDBLOCK          (WSABASEERR+35)</span>
</pre></div>
<p><font size="2">The managed call stack at exception time can be something like this:</font></p><!-- HTML generated using hilite.me --><div><pre style="margin: 0px;line-height: 125%">System.Net.Sockets.SocketException: A non-blocking socket operation could not be completed immediately
    at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
    at System.Runtime.Remoting.Channels.SocketStream.Read(Byte[] buffer, Int32 offset, Int32 size)
    at System.Runtime.Remoting.Channels.SocketHandler.ReadFromSocket(Byte[] buffer, Int32 offset, Int32 count)
    at System.Runtime.Remoting.Channels.SocketHandler.BufferMoreData()
    at System.Runtime.Remoting.Channels.SocketHandler.Read(Byte[] buffer, Int32 offset, Int32 count)
    at System.Runtime.Remoting.Channels.Tcp.TcpFixedLengthReadingStream.Read(Byte[] buffer, Int32 offset, Int32 count)
    at System.IO.BinaryReader.ReadString()
    at System.Runtime.Serialization.Formatters.Binary.IOUtil.ReadArgs(__BinaryParser input)
    at System.Runtime.Serialization.Formatters.Binary.BinaryMethodCall.Read(__BinaryParser input)
    at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadMethodObject(BinaryHeaderEnum binaryHeaderEnum)
    at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
    at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
    at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
    at System.Runtime.Remoting.Channels.CoreChannel.DeserializeBinaryRequestMessage(String objectUri, Stream inputStream, Boolean bStrictBinding, TypeFilterLevel securityLevel)
    at System.Runtime.Remoting.Channels.BinaryServerFormatterSink.ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, IMessage&amp; responseMsg, ITransportHeaders&amp; responseHeaders, Stream&amp; responseStream)
</pre></div>
<p><font size="2">WSAEWOULDBLOCK is returned by some socket APIs when the call may need to block the caller (in other words, it cannot return immediately), but the underlying socket is in <a href="https://docs.microsoft.com/en-us/cpp/mfc/windows-sockets-blocking">non-blocking mode</a>. For instance, the </font><a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms740121(v=vs.85).aspx"><font size="2">recv</font></a><font size="2"> socket api needs to block, waiting for enough bytes to be in the input buffer, if they are not already there.</font></p><p><font size="2">With .Net Remoting using the TCP channel, a socket should not be in non-blocking mode. However, this situation may arise on the server side of .Net Remoting if you call StartListening() on the channel when the channel is already listening.</font></p><p><font size="2">The typical scenario is if you create the channel and call </font><a href="https://msdn.microsoft.com/en-us/library/system.runtime.remoting.channels.tcp.tcpchannel.startlistening(v=vs.110).aspx"><font size="2">StartListening</font></a><font size="2"> on it:</font></p><!-- HTML generated using hilite.me --><div><pre style="margin: 0px;line-height: 125%"><span>private</span> <span>static</span> <span>string</span> <span>StartServer</span>()
{
     TcpChannel serverChannel = <span>new</span> TcpChannel(<span>0</span>);
     ChannelServices.RegisterChannel(serverChannel, <span>false</span>);
     RemotingConfiguration.RegisterWellKnownServiceType(<span>typeof</span>(MyHost), <span>"MyHost"</span>,
                                                        WellKnownObjectMode.Singleton);
     serverChannel.StartListening(<span>null</span>);            
     <span>return</span> ((ChannelDataStore)serverChannel.ChannelData).ChannelUris[<span>0</span>];
}
</pre></div>
<p><font size="2">The TcpChannel constructor puts the channel in listening mode, so calling StartListening at this stage creates the conditions for this behavior. Without going into too much detail on the underlying cause, suffice it to say that in this case a listening socket will experience an error while accepting the incoming connection, so it will be put into non-blocking mode. This will cause the next accept to succeed but the new connection at this point will be in non-blocking mode also.</font></p><p><font size="2">Fortunately, if you run into this condition, the fix is easy: just remove the additional StartListening call:</font></p><!-- HTML generated using hilite.me --><div><pre style="margin: 0px;line-height: 125%"><span>private</span> <span>static</span> <span>string</span> <span>StartServer</span>()
{
    TcpChannel serverChannel = <span>new</span> TcpChannel(<span>0</span>);
     ChannelServices.RegisterChannel(serverChannel, <span>false</span>);
     RemotingConfiguration.RegisterWellKnownServiceType(<span>typeof</span>(MyHost), <span>"MyHost"</span>,
                                                        WellKnownObjectMode.Singleton);
     <span>return</span> ((ChannelDataStore)serverChannel.ChannelData).ChannelUris[<span>0</span>];
}
</pre></div><p>
<font size="2"><strong><br></strong></font></p><p><font size="2"><strong>Notes</strong></font></p><ul><li><font size="2">StartListening is a method of the <a href="https://msdn.microsoft.com/en-us/library/system.runtime.remoting.channels.ichannelreceiver(v=vs.110).aspx">IChannelReceiver interface</a> and is also implemented by the other channels in .Net Remoting: IpcChannel and HttpChannel. However, these channels do not suffer from this behavior: calling StartListening on an already listening IpcChannel or HttpChannel doesn’t do anything.</font></li><li><font size="2">StartListening has its own place as a way to resume listening on a channel that is not listening. In other words, it is safe to call StartListening on a channel on which StopListening had been called previously.</font></li></ul>]]></content:encoded>
    </item>
    <item>
      <title>DistributedCOM Event Log Entries</title>
      <link>https://docs.microsoft.com/archive/blogs/carlos/distributedcom-event-logs-2</link>
      <pubDate>Fri, 14 Apr 2017 19:54:56 GMT</pubDate>
      <dc:creator><![CDATA[Carlo_Colombo]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/carlos/?p=746</guid>
      <description><![CDATA[DistributedCOM (DCOM) events 10000-1010 and 10028-10030 are written to the System Event Log when a...]]></description>
      <content:encoded><![CDATA[<p>DistributedCOM (DCOM) events 10000-1010 and 10028-10030 are written to the System Event Log when a DCOM activation fails. You can find information on these events on the web, however this information is scattered across multiple places, often incomplete, sometimes incorrect.  <p>In this post, I’ll try to (hopefully) bring some clarity to the subject.  <h3>Background</h3> <p>When a client calls a COM activation API (<a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms694473(v=vs.85).aspx">CoGetClassObject</a>, <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms680701(v=vs.85).aspx">CoCreateInstanceEx</a>, <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms694473(v=vs.85).aspx">CoGetInstanceFromFile</a>, <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms686574(v=vs.85).aspx">CoGetInstanceFromIStorage</a>, <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms691433(v=vs.85).aspx">IMoniker::BindToObject</a>) and the component to be activated is out-of-process, several things happen.  <p>The COM runtime (ole32.dll or combase.dll, running in the process that called the COM activation API) contacts the local RpcSs service (display name “Remote Procedure Call (RPC)”).  <p>RpcSs determines if the component should be activated remotely. If so, the local RpcSs service forwards the request to the RpcSs service of the remote machine.  <p>If not, RpcSs determines if the process that hosts that COM object is already running (RpcSs keeps internal data structures for every running DCOM server). If it is, it uses its endpoint to send the activation request to the process.  <p>If the DCOM Server is not running, RpcSs sends the request to the local DcomLaunch service (display name “DCOM Server Process Launcher”) to execute the DCOM server that will host the desired component. DcomLaunch uses the CreateProcessXxx() APIs, or StartService() if the DCOM server has been configured to run as a service.  <p><b>Note</b>: DcomLaunch exists for security reasons: the RpcSs service runs under the “Network Service” account. This account does not have all the required permissions to create processes with different identities. Therefore, it defers these operations to DcomLaunch, that runs under the “Local System” account.  <p>A DCOM Server can be a DCOM EXE server or a <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms695225(v=vs.85).aspx">surrogate</a>, including a COM+ server application. RpcSs first looks up the to-be-activated CLSID in the <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms679196(v=vs.85).aspx">COM+ catalog</a>. If it is not in the COM+ catalog, RpcSss searches the registry. Through these searches, RpcSs ultimately knows the name of the executable that should host the to-be-activated component.  <p>Unlike COM server DLLs, which export the function <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms680760(v=vs.85).aspx">DllGetClassObject</a> to allow clients to get the class factories of the components hosted in the DLL, COM EXE servers must explicitly register their class factories by calling <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms693407(v=vs.85).aspx">CoRegisterClassObject</a> for each component it hosts. The RpcSs service maintains a local table, binding CLSIDs to running processes. The function CoRegisterClassObject() connects to the local RpcSs to add an entry to the table.  <p><b>Note</b>: the server can also call CoRegisterClassObject() using the REGCLS_SUSPENDED flag for every component, then register them all with RpcSs with CoResumeClassObjects(). This is more efficient if the COM server hosts many components.  <p>As you can see, several things happen during COM activation. Consequently, several things can potentially go wrong. The RpcSs and DcomLaunch services write events to the System event log when this happens. The event source of all these events is “DistributedCOM”. The event ID identifies what exactly went wrong.  <p>In the next section, we are having a look at these events, explaining when, and under which circumstances, each of them occurs. In the last section, we’ll explain how to troubleshoot them.  <p><b>Note</b>: what is being said in the following applies to Windows 10. Other versions of Windows, in many respects, will behave in the same or a similar way.  <h3>Events</h3> <p>As said in the previous section, when a process calls a COM Activation API, the activation request is passed on to the local RpcSs service and, if the DCOM Server must be started, further on to the DcomLaunch service.  <p>If the DCOM Server is configured to be run with the identity of the caller (Activate as Activator, or “The Launching User” in Component Services):  <p><a href="https://msdnshared.blob.core.windows.net/media/2017/04/LaunchingUser1.png"><img title="LaunchingUser" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="LaunchingUser" src="https://msdnshared.blob.core.windows.net/media/2017/04/LaunchingUser_thumb.png" width="379" height="510"></a>  <p>DcomLaunch will impersonate the caller of the COM Activation API, then call <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms682429(v=vs.85).aspx">CreateProcessAsUser</a> to create the DCOM Server process under that same identity. If CreateProcessAsUser() fails, this event log is created: </p><pre class="brush: text;"><font style="background-color: #cccccc"></font>MessageId=<font style="background-color: #ffff00">10000</font> Severity=Error SymbolicName=EVENT_RPCSS_CREATEPROCESS_FAILURE 
<p><font style="background-color: #ffff00"></font>Unable to start a DCOM Server: %3. 
<p>The error:%n"%%%2"%nHappened while starting this command:%n%1<font style="background-color: #ffff00"></font> 
</p></pre>
<p>If the DCOM Server is configured to be run with a specific identity (“This user” in Component Services): 
<p><a href="https://msdnshared.blob.core.windows.net/media/2017/04/ThisUser1.png"><img title="ThisUser" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="ThisUser" src="https://msdnshared.blob.core.windows.net/media/2017/04/ThisUser_thumb.png" width="379" height="510"></a>\ 
<p>DcomLaunch will first call <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/bb540756(v=vs.85).aspx">LogonUserExExW</a> to get the access token. If it fails, DcomLaunch logs this error: </p><pre class="brush: text;">MessageId=<font style="background-color: #ffff00">10004</font> Severity=Error SymbolicName= EVENT_RPCSS_RUNAS_CANT_LOGIN 
<p>DCOM got error "%%%1" and was unable to logon %2\%3 
<p>in order to run the server:%n%4 
</p></pre>
<p>Next, DcomLaunch calls <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms682429(v=vs.85).aspx">CreateProcessAsUser</a> to launch the process. If CreateProcessAsUser() fails, this event log is created: </p><pre class="brush: text;">MessageId=<font style="background-color: #ffff00">10001</font> Severity=Error SymbolicName= EVENT_RPCSS_RUNAS_CREATEPROCESS_FAILURE 
<p>Unable to start a DCOM Server: %3 as %4/%5. 
<p>The error:%n"%%%2"%nHappened while starting this command:%n%1 
</p></pre>
<p>If the DCOM Server is configured to run as a service, <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms686321(v=vs.85).aspx">StartService</a> is called to start the service if needed. If StartService() fails, this event log is created: </p><pre class="brush: text;">MessageId=<font style="background-color: #ffff00">10005</font> Severity=Error SymbolicName=EVENT_RPCSS_START_SERVICE_FAILURE 
<p>DCOM got error "%%%1" attempting to start the service %2 with arguments "%3" 
<p>in order to run the server:%n%4 
</p></pre>
<p>The error reported in the log is obtained by calling GetLastError(), if StartService() returns FALSE. 
<p><b>Note</b>:if the service is disabled, StartService() will fail but the above event is not logged. 
<p>If the DCOM Server is configured as a service, and the service is running, but returned CO_E_SERVER_STOPPING when asked to activate a component (meaning that the service is being stopped), then RpcSs queries the service status to check if it eventually reaches the SERVICE_STOPPED or SERVICE_RUNNING status. If this does not happen within 4 minutes, the following event is logged: </p><pre class="brush: text;">MessageId=<font style="background-color: #ffff00">10029</font> Severity=Error SymbolicName= EVENT_RPCSS_STOP_SERVICE_FAILURE 
<p>The activation of the CLSID %1 timed out waiting for the service %2 to stop. 
<p>in order to run the server:%n%4 
</p></pre>
<p>In COM+, it is possible to configure the application to be started under a debugger: 
<p><a href="https://msdnshared.blob.core.windows.net/media/2017/04/UnderDebugger1.png"><img title="UnderDebugger" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="UnderDebugger" src="https://msdnshared.blob.core.windows.net/media/2017/04/UnderDebugger_thumb.png" width="379" height="527"></a> 
<p>With this configuration in place, DcomLaunch calls <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms682429(v=vs.85).aspx">CreateProcessAsUser</a> for the specified debugger. Should CreateProcessAsUser() fail, the following event is logged: </p><pre class="brush: text;">MessageId=<font style="background-color: #ffff00">10030</font> Severity=Error SymbolicName= EVENT_RPCSS_CREATEDEBUGGERPROCESS_FAILURE 
<p>Unable to start a COM Server for debugging: %3. 
<p>The error:%n"%%%2"%nHappened while starting this command:%n%1 
</p></pre>
<p>The %3 argument is the CLSID of the component that is being activated, whereas %1 represents the command line that was passed to CreateProcessAsUser() to launch the debugger. 
<p>If, on the other hand, the component is configured for activation on a remote machine: 
<p><a href="https://msdnshared.blob.core.windows.net/media/2017/04/RemoteActivation1.png"><img title="RemoteActivation" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="RemoteActivation" src="https://msdnshared.blob.core.windows.net/media/2017/04/RemoteActivation_thumb.png" width="379" height="510"></a> 
<p>the local RpcSs defers the activation to the remote RpcSs. In this case, the first step of the local RpcSs is to establish a connection (an RPC binding) with the remote RpcSs. The connection is tried in several ways, using cached and uncached RPC binding handles, using client-specified security (if the client provided it) or trying all the available authentication packages and, if all of them fail, trying to establish an unauthenticated connection. 
<p>If none of the above succeeds, this event is logged: </p><pre class="brush: text;">MessageId=<font style="background-color: #ffff00">10028</font> Severity=Error SymbolicName= EVENT_RPCSS_REMOTE_SIDE_UNAVAILABLE_WITH_CLIENT_INFO 
<p>DCOM was unable to communicate with the computer %1 using any of the configured protocols; requested by PID %2 (%3) 
</p></pre>
<p><b>Note</b>: in older versions of Windows, the event is 10009 (EVENT_RPCSS_REMOTE_SIDE_UNAVAILABLE). Unlike EVENT_RPCSS_REMOTE_SIDE_UNAVAILABLE_WITH_CLIENT_INFO, EVENT_RPCSS_REMOTE_SIDE_UNAVAILABLE does not contain the PID of the client process that called the COM activation API. 
<p>If the connection to the remote RpcSs succeeds, but the activation fails, the local RpcSs reports the failure using the events: </p><pre class="brush: text;">MessageId=<font style="background-color: #ffff00">10006</font> Severity=Error SymbolicName= EVENT_RPCSS_REMOTE_SIDE_ERROR 
<p>DCOM got error "%%%1" from the computer %2 when attempting to 
<p>activate the server:%n%3
</p></pre><pre class="brush: text;">MessageId=<font style="background-color: #ffff00">10008</font> Severity=Error SymbolicName= EVENT_RPCSS_REMOTE_SIDE_ERROR_WITH_FILE 
<p>DCOM got error "%%%1" from the computer %2 when attempting to 
<p>activate the server:%n%3 with file %4. 
</p></pre>
<p>If the previous steps succeed, the DCOM Server is started successfully. There is an additional, important step: the DCOM server (an executable, a service or the DLLHOST.EXE surrogate) must register its class factories by calling <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms693407(v=vs.85).aspx">CoRegisterClassObject</a>. RpcSs waits for this to happen within a period of 2 minutes, otherwise it logs the following event in the event log: </p><pre class="brush: text;">MessageId=<font style="background-color: #ffff00">10010</font> Severity=Error SymbolicName=EVENT_RPCSS_SERVER_START_TIMEOUT 
<p>The server %1 did not register with DCOM within the required timeout.
</p></pre>
<p><b>Note</b>: all the event logs reported above are subject to filtering: if <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms692700(v=vs.85).aspx)">ActivationFailureLoggingLevel</a> is 2, or if it is 0 and the activation API is called with CLSCTX_NO_FAILURE_LOG, no entry is written to the event log. The default value is 0, and usually clients do not use CLSCTX_NO_FAILURE_LOG, so failures are logged by default. 
<h3>Troubleshooting</h3>
<p>The troubleshooting is heavily dependent on the event ID. 
<p>If the Event ID is </p><pre class="brush: text;">MessageId=<font style="background-color: #ffff00">10004</font> Severity=Error SymbolicName= EVENT_RPCSS_RUNAS_CANT_LOGIN 
<p>DCOM got error "%%%1" and was unable to logon %2\%3 
<p>in order to run the server:%n%4 
</p></pre>
<p>this means, as said in the previous section, that the DCOM Server is configured with RunAs identity, RpcSs called LogonUserExExW() for that identity, but it failed. 
<p>The error logged (%1) is the value returned by GetLastError(), and it gives additional information about what went wrong. 
<p>Additional troubleshooting steps include double-checking that the username and password configured for the DCOM Server’s identity are valid, and that the account has not been disabled. Beware, in particular, of expired passwords. The security event log (Security Audit) can be a valid help to further troubleshoot this issue. 
<p>A set of events indicate that the process creation failed: </p><pre class="brush: text;">MessageId=<font style="background-color: #ffff00">10000</font> Severity=Error SymbolicName=EVENT_RPCSS_CREATEPROCESS_FAILURE 
<p>Unable to start a DCOM Server: %3. 
<p>The error:%n"%%%2"%nHappened while starting this command:%n%1 
</p></pre><pre class="brush: text;">MessageId=<font style="background-color: #ffff00">10001</font> Severity=Error SymbolicName= EVENT_RPCSS_RUNAS_CREATEPROCESS_FAILURE 
<p>Unable to start a DCOM Server: %3 as %4/%5. 
<p>The error:%n"%%%2"%nHappened while starting this command:%n%1
</p></pre><pre class="brush: text;">MessageId=<font style="background-color: #ffff00">10005</font> Severity=Error SymbolicName=EVENT_RPCSS_START_SERVICE_FAILURE 
<p>DCOM got error "%%%1" attempting to start the service %2 with arguments "%3" 
<p>in order to run the server:%n%4 
</p></pre>
<p>These events mean that CreateProcessAsUser()/StartService() failed. Follow these steps to troubleshoot: 
<ol>
<li>The event log reports the error. This is the value returned by GetLastError() after the CreateProcessAsUser()/StartService() APIs failed. Often the error gives a valuable hint at what the problem is (access denied, file not found, etc). 
<li>The command is reported in the event log. Verify that the executable is in the specified location. If the executable was deleted, or moved to a different location without being re-registered, RpcSs will pass the wrong path to CreateProcessAsUser(). Re-registering the DCOM Server fixes this problem. 
<li>Verify that the executable has all its required dependencies. Be aware that some dependencies might work with your logged-in user path, but might not work with the path of another account (including the System account). 
<li>Try launching the executable manually from the command line, or starting the service manually - if this is not working, you can investigate this directly. 
<li>Verify that the executable does not have an <a href="https://blogs.msdn.microsoft.com/oldnewthing/20051219-11/?p=32923">Image File Execution Options</a> (IFEO) key. If it does have such a key, and it has a "Debugger" named value, verify that the debugger listed is on the system path. A common mistake is to enter the name of the debugger without the full path in the Debugger value, and the folder is not in the PATH environment variable. This will cause CreateProcessAsUser() call from DcomLaunch to fail, with GetLastError() returning ERROR_FILE_NOT_FOUND (2), which is reported in the event log. 
<li>If the server is configured with RunAs (“This user”) or Activate-As-Activator (“The launching user”), verify that this identity has access to the server executable, and all its dependencies. If not, the error reported in events 10000, 10001 and 10005 will be access denied (5) The caller of the activation API will receive an E_ACCESSDENIED return value. 
<li>If the DCOM Server is implemented as a service, additional considerations apply: 
<ul>
<li>Make sure that the service is not disabled. 
<li>The service startup may have run into trouble. This is unlikely if you are using a surrogate or a service written with ATL, because these services have well-tested service startup code. The section <a href="https://msdn.microsoft.com/en-us/library/windows/hardware/ff540613(v=vs.85).aspx">Debugging a Service Application</a> in the “Debugging Tools for Windows” help has information on how to debug the service startup.</li></ul></li></ol>
<p>If none of the above resolves the issue, it is possible to get more information by debugging RpcSs and DcomLaunch directly. This is risky, however, because they are key operating system processes. Debugging in the usual way (say, for instance, by using Visual Studio) will almost certainly bring to a hang of the machine, or a crash. So, debugging is usually done by using a debugger like cdb.exe (part of the <a href="https://msdn.microsoft.com/en-us/library/windows/hardware/ff551063(v=vs.85).aspx">Debugging Tools for Windows</a>) that does not have a user interface, and by using a debugger script that drives the debugger, thus never blocking the debugged process. This is an advanced scenario, I don’t recommend doing it unless you are really a debugging expert. If things get to this point, you may also get in touch with Microsoft Support for additional assistance. 
<p>We discussed the error </p><pre class="brush: text;">MessageId=<font style="background-color: #ffff00">10029</font> Severity=Error SymbolicName= EVENT_RPCSS_STOP_SERVICE_FAILURE 
<p>The activation of the CLSID %1 timed out waiting for the service %2 to stop. 
<p>in order to run the server:%n%4 
</p></pre>
<p>in some detail in the previous section. The real cause of this error is a service that presumably hung while stopping. You can take a dump of the process while it is in this state, and analyze it with WinDbg (also part of the Debugging Tools for Windows). 
<p>Another set of events applies to remote activation failure. The most likely cause of this event: </p><pre class="brush: text;">MessageId=<font style="background-color: #ffff00">10028</font> Severity=Error SymbolicName= EVENT_RPCSS_REMOTE_SIDE_UNAVAILABLE_WITH_CLIENT_INFO 
<p>DCOM was unable to communicate with the computer %1 using any of the configured protocols; requested by PID %2 (%3) 
</p></pre>
<p>is that the remote machine is unreachable. It could be no longer available, turned off, or disconnected from the network. 
<p>The event log reports the name of the remote computer, so you can double-check that it is reachable from the machine where the event is logged. 
<p>It is possible that this event occurs because of a COM activation that is no longer needed or wanted. For instance, the destination machine may have been decommissioned and replaced with a machine having a different name. To modify the identification of the remote machine for the COM activation, let’s first keep in mind that this information can be specified either declaratively in Component Services, as shown in the picture in the previous section, or programmatically, by providing in the <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms687322(v=vs.85).aspx">COSERVERINFO</a> structure in the COM Activation API. Note that the event does not provide the CLSID of the component that we are trying to activate. 
<p>The events </p><pre class="brush: text;">MessageId=<font style="background-color: #ffff00">10006</font> Severity=Error SymbolicName= EVENT_RPCSS_REMOTE_SIDE_ERROR 
<p>DCOM got error "%%%1" from the computer %2 when attempting to 
<p>activate the server:%n%3 
</p></pre><pre class="brush: text;">MessageId=<font style="background-color: #ffff00">10008</font> Severity=Error SymbolicName= EVENT_RPCSS_REMOTE_SIDE_ERROR_WITH_FILE 
<p>DCOM got error "%%%1" from the computer %2 when attempting to 
<p>activate the server:%n%3 with file %4. 
</p></pre>
<p>indicate a remote activation failure. This means that the connection to the remote RpcSs could be established successfully, however the activation request itself, issued by the remote RpcSs, failed. 
<p>Note that, in this case, the remote machine may or may not log an event. For instance, if the activation failure on the remote machine is caused by the CLSID not being registered, there won’t be any corresponding event logged on the remote machine. If, on the other hand, the component is registered on the remote machine, but the executable is not found, the remote machine will log an event. In this case, the combination of the local and remote event contribute to give the complete picture. For instance: 
<p>Local: </p><pre class="brush: text;">Log Name: System 
<p>Source: Microsoft-Windows-DistributedCOM 
<p>Date: 4/12/2017 12:05:14 PM 
<p>Event ID: 10006 
<p>Task Category: None 
<p>Level: Error 
<p>Keywords: Classic 
<p>User: Xxxx 
<p>Computer: Yyyy 
<p>Description: 
<p>DCOM got error "2147942402" from the computer Zzzz when attempting to activate the server: 
<p>{02ACA2A3-51F7-48FD-9246-5D0A84102414} 
</p></pre>
<p>Remote: </p><pre class="brush: text;"><p>Log Name: System 
<p>Source: Microsoft-Windows-DistributedCOM 
<p>Date: 4/12/2017 12:05:14 PM 
<p>Event ID: 10000 
<p>Task Category: None 
<p>Level: Error 
<p>Keywords: Classic 
<p>User: Xxxx 
<p>Computer: Zzzz 
<p>Description: 
<p>Unable to start a DCOM Server: {02ACA2A3-51F7-48FD-9246-5D0A84102414}. The error: 
<p>"2" 
<p>Happened while starting this command: 
<p>"D:\DCOMServer\x64\Release\DCOMServer.exe" -Embedding 
</p></pre>
<p>Last, the event </p><pre class="brush: text;">MessageId=<font style="background-color: #ffff00">10010</font> Severity=Error SymbolicName=EVENT_RPCSS_SERVER_START_TIMEOUT 
<p>The server %1 did not register with DCOM within the required timeout. 
</p></pre>
<p>indicates that the DCOM Server was successfully started by DcomLaunch (CreateProcessAsUser()/StartService() succeeded), but it failed to register its class factories within 2 minutes. This is typically an indication of a problem happening in the startup of the DCOM Server. 
<p>If we rule out trivial errors in the code of the DCOM Server (for instance, having a code path that causes CoRegisterClassObject() not to be called), the issue can be of 3 types: 
<p>A. Crash at process startup 
<p>B. Deadlock at process startup 
<p>C. Macroscopic slowness at process startup 
<p>You can easily tell if we are in scenario A. by monitoring the lifetime of the DCOM server: we are in scenario A. if it starts up and terminates soon after. You can use the Task Manager or a tool like <a href="https://technet.microsoft.com/en-us/sysinternals/processexplorer.aspx">Process Explorer</a> to determine this. Scenario A. can be further troubleshot by using a tool like Windows Error Reporting or ProcDump or another debugger <a href="https://msdn.microsoft.com/en-us/library/windows/hardware/ff542967(v=vs.85).aspx">specified as postmortem debugger</a>, that takes a dump of the process when the crash occurs. 
<p>If, on the other hand, the DCOM Server stays alive until the event 10010 is logged, that means that we are in scenarios B. or C. Keep in mind that, after logging the 10010 event log, RpcSs kills the process (except if the DCOM Server runs as a service), if it hasn’t already died. RpcSs does this for a very good reason: by killing the process, the next COM activation request for the same CLSID, or a different CLSID hosted in the same DCOM Server, will cause a new process to be created, instead of directing the call to a running process that presumably hung. If the issue is a “once in a while” one, this makes it much more likely for the next activation request to succeed. However, you need to keep this in mind, when debugging the DCOM Server startup: if you attach a debugger to the process, the debuggee will likely be killed while you are debugging! A better approach in this case is to take a dump of the process in the time interval from the process startup until the DCOM event 10010 is logged. 
<p>You can take the memory dump with Task Manager: 
<p><a href="https://msdnshared.blob.core.windows.net/media/2017/04/CreateDump1.png"><img title="CreateDump" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="CreateDump" src="https://msdnshared.blob.core.windows.net/media/2017/04/CreateDump_thumb.png" width="504" height="448"></a> 
<p>Whatever the scenario A., B. or C. above, you end up with a user-mode dump of the DCOM Server. This can be analyzed with a debugger like WinDbg to find out the cause of the crash or the hang.]]></content:encoded>
    </item>
    <item>
      <title>Side-by-Side Execution of Workflow Services: Step-by-Step Example</title>
      <link>https://docs.microsoft.com/archive/blogs/carlos/side-by-side-execution-of-workflow-services-step-by-step-example</link>
      <pubDate>Wed, 16 Dec 2015 07:44:00 GMT</pubDate>
      <dc:creator><![CDATA[carcolo]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/carlos/2015/12/16/side-by-side-execution-of-workflow-services-step-by-step-example/</guid>
      <description><![CDATA[Introduction
In this blog post, we go through a complete example of a workflow service that handles...]]></description>
      <content:encoded><![CDATA[<h1>Introduction</h1>
<p>In this blog post, we go through a complete example of a workflow service that handles multiple versions.</p>
<p>The <a href="https://msdn.microsoft.com/en-us/library/hh314045.aspx">MSDN Documentation</a> covers this topic, and a <a href="https://code.msdn.microsoft.com/Side-by-Side-Versioning-0fe24cd3">sample</a> is available in the Samples section of MSDN. In this post we are going to cover the topic step-by-step, building a complete sample from scratch. We will also try to emphasize the relevant pieces and to provide a motivation for them. We will focus on IIS/WAS-hosted workflow services, even though we will also briefly touch on the underlying API that is available to self-hosted workflow services. Last, we will cover the more advanced scenario of changes that extend outside the workflow definition itself, to activities used by the workflow.</p>
<p><strong>Note</strong>: the step-by-step procedure is relative to Visual Studio 2015, the current version as of this writing. It is possible, though not guaranteed, that the same steps, possibly with minor adjustments, also work with other Visual Studio versions. Since SxS versioning is a new feature of WF4.5, the .Net Framework must be 4.5 or higher.</p>
<p>The steps are highlighted in <span style="background-color: #ffff00;">yellow</span> throughout the post.</p>
<h1>Defining Side-by-Side Execution</h1>
<p>Workflows (including workflow services) can be long-running. With long-running workflows, you may need to update the structure of a workflow while some instances are running. This poses the problem of what happens to the running instances.</p>
<p>In WF4.0, you do not have much choice: it is up to you to maintain the new and old definition at different endpoints, so the client has to explicitly decide which version to use. This obviously creates tight coupling between clients and the service.</p>
<p>WF4.5 addressed this lack of flexibility by providing two options:</p>
<ul>
<li>Side-by-side execution</li>
<li>Dynamic update</li>
</ul>
<p><strong>Side-by-side execution</strong> is defined as follows:</p>
<ul>
<li>all the <span style="text-decoration: underline;"><em>existing instances</em></span> will continue to run, until completion, using the <span style="text-decoration: underline;"><em>original workflow definition</em></span> (that is, the definition that was current when the workflow instance started execution)</li>
<li><span style="text-decoration: underline;"><em>new instances</em></span> start execution using the <span style="text-decoration: underline;"><em>most current workflow definition.</em></span></li>
</ul>
<p>Dynamic update, on the other hand, implies the dynamic update of the running instances, so to migrate them to the new definition. If the dynamic update completes successfully for all the running instances, it is not necessary to keep multiple versions, because all instances (existing and new) will use the most recent version at this point.</p>
<p>In this post we focus on side-by-side execution only. This is the easiest and most common scenario.</p>
<h1>Creating the Service</h1>
<p>We start by creating the workflow service from the default template. As we&rsquo;ll see, several additions are necessary before we can create a working side-by-side example. Nonetheless, starting with the default template is much faster than building everything from scratch.</p>
<p>To create the service:</p>
<ul>
<li><span style="background-color: #ffff00;">Open Visual Studio 2015</span></li>
<li><span style="background-color: #ffff00;">Select the File | New | Project menu item</span></li>
<li><span style="background-color: #ffff00;">In the dialog box, in the left pane, select Visual C# | Workflow</span></li>
<li><span style="background-color: #ffff00;">Select <span style="text-decoration: underline;"><em>WCF Workflow Service Application</em></span></span></li>
<li><span style="background-color: #ffff00;">Give a name to the project (for instance, SxSWfSvc)</span></li>
</ul>
<p><strong>Note</strong>: you may want to open Visual Studio as Administrator. This is not required for the steps above, but it will make it possible to run the service under the debugger. Without administrative privileges, the service won&rsquo;t be able to open the endpoint to listen for incoming requests.</p>
<p><strong>Note</strong>: the default project configuration is such that, when running the project, it will open the URL to the currently selected document in the project (see Project Properties, Web tab, Start Action: it is set to Current Page). If anything other than Service1.xamlx is selected (for instance, web.,config), we won&rsquo;t get the expected behavior. To fix this, change this setting: <span style="background-color: #ffff00;">in Start Action, select Specific Page and set it to Service1.xamlx</span>.</p>
<p>This service is already operational. You can double-check this by running the project in the debugger (F5). This fires up WcfTestClient; use it to execute the GetData operation and check that it completes successfully:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/6607.TemplateTesting_5388704A.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/6607.TemplateTesting_5F00_5388704A.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border: 0px;" title="TemplateTesting" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/8306.TemplateTesting_thumb_7^5C3.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/8306.TemplateTesting_5F00_thumb_5F00_75E005C3.png" alt="TemplateTesting" width="644" height="288" border="0" /></a></p>
<h1>Adding a Second Operation</h1>
<p>At the moment, our service has a single operation. Once a client calls the operation, the service completes execution. This service cannot be a long-running service. We need a service with at least two operations, in sequence. The first operation starts the service. Once the operation completes, the workflow service continues to run and is idle. When the client calls the second operation on the same workflow instance, the service completes execution. This way, the lifetime of the service is entirely in the hands of the clients, and workflow services can be as long-running as the clients wish.</p>
<p>In our case, the <a href="https://en.wikipedia.org/wiki/Messaging_pattern">Message Exchange Pattern (MEP)</a> between the client and the service, once we have added the second operation, will be like this:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/5432.MEP_37E67505.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/5432.MEP_5F00_37E67505.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border: 0px;" title="MEP" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/1830.MEP_thumb_72CDA7CE.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/1830.MEP_5F00_thumb_5F00_72CDA7CE.png" alt="MEP" width="760" height="419" border="0" /></a></p>
<p>InstanceId is the identifier (a GUID) of the running workflow instance. Note that this is just for the sake of this sample, a real-life workflow can return any business-related data.</p>
<p>To add a second operation:</p>
<ul>
<li><span style="background-color: #ffff00;">Drag and Drop a ReceiveAndSendReply &ldquo;activity&rdquo; to the workflow, at the end of the workflow</span></li>
</ul>
<p>This is enough to add a second operation, however we also take the chance to do some cleanup, fix-up and cosmetic changes:</p>
<ul>
<li><span style="background-color: #ffff00;">In the Variables, rename __handle1 to SecondRequestResponse and chance its scope to &ldquo;Sequential Service&rdquo;</span></li>
<li><span style="background-color: #ffff00;">Also in the Variables, rename handle to FirstRequestResponse. Ignore the validation error for now.</span></li>
<li><span style="background-color: #ffff00;">Also in Variables, remove data, as we won&rsquo;t use it anymore. </span></li>
<li><span style="background-color: #ffff00;">Also in Variables, define a new variable at Sequential Service scope, of type System.Guid, and name it InstanceId</span></li>
<li><span style="background-color: #ffff00;">Also in Variables, define a new variable at Sequential Service scope, of type string, and name it sInstanceId</span></li>
<li><span style="background-color: #ffff00;">Change the display name of the Receive activities to ReceiveFirstOp and ReceiveSecondOp, respectively</span></li>
<li><span style="background-color: #ffff00;">Change the display name of the Send activities to SendFirstOp and SendSecondOp, respectively</span></li>
<li><span style="background-color: #ffff00;">Drag and Drop ReceiveSecondOp and SendSecondOp outside of their Sequence activity, directly below SendFirstOp</span></li>
<li><span style="background-color: #ffff00;">Remove Sequence, which is empty at this point</span></li>
<li><span style="background-color: #ffff00;">Change SendFirstOp: set Content to sInstanceId</span></li>
<li><span style="background-color: #ffff00;">Change ReceiveFirstOp: set OperationName to StartWf and remove data from the Content. In CorrelationIntializers, set FirstRequestResponse instead of handle. Validation errors should disappear at this point.</span></li>
<li><span style="background-color: #ffff00;">Change ReceiveSecondOp: set OperationName to ContinueWf and Content to sInstanceId</span></li>
<li><span style="background-color: #ffff00;">Change SendSecondOp: set Content to &ldquo;Done with " + sInstanceId.</span></li>
</ul>
<p>FirstRequestResponse needs to return the InstanceId to the client, so we need to retrieve it. This information is available in the activity context, so the easiest way to retrieve it is by means of a code activity:</p>
<ul>
<li><span style="background-color: #ffff00;">Add a class to the project, name it WfInstanceId and implement it this way</span>:</li>
</ul>
<div>
<div id="codeSnippet" style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> WfInstanceId: CodeActivity</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">{</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">    <span style="color: #0000ff;">public</span> OutArgument&lt;Guid&gt; InstanceId</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">    {</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">        get; set;</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">    }</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">    <span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">override</span> <span style="color: #0000ff;">void</span> Execute(CodeActivityContext context)</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">    {</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">        InstanceId.Set(context, context.WorkflowInstanceId);</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">    }</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">}</pre>
<!--CRLF--></div>
</div>
<p><strong>Note</strong>: mind to make the class public, otherwise the activity won&rsquo;t show up in the Toolbox in the next steps.</p>
<ul>
<li><span style="background-color: #ffff00;">Build the project (necessary for the WfInstanceId activity to show up in the Toolbox)</span></li>
<li><span style="background-color: #ffff00;">Drag and Drop the WfInstanceId activity from the Toolbox to after ReceiveFirstOp and before SendFirstOp</span></li>
<li><span style="background-color: #ffff00;">Set the InstanceId property of WfInstanceId to the InstanceId variable</span></li>
<li><span style="background-color: #ffff00;">Drag and Drop an Assign activity from the Toolbox to after WfInstanceId. Assign to sInstanceId the value &ldquo;InstanceId.ToString()&rdquo;</span></li>
</ul>
<p>This is how the workflow should look like at this point:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/6710.Wf_49C59983.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/6710.Wf_5F00_49C59983.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border: 0px;" title="Wf" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/7142.Wf_thumb_245BA615.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/7142.Wf_5F00_thumb_5F00_245BA615.png" alt="Wf" width="413" height="484" border="0" /></a></p>
<h1>Adding Persistence</h1>
<p>Though this is not a strict requirement, long-running workflows usually don&rsquo;t stay in memory for their entire lifetime: they are persisted and unloaded when appropriate (typically, when they are idle, that is when they are waiting for some external event like an incoming message or an expired timer to occur, before resuming execution).</p>
<p>Persistence adds the following benefits:</p>
<ul>
<li>reliability: if the host crashes without having ever persisted a workflow instance, the instance state is lost. If, on the other hand, the workflow instance has been persisted, it can be resumed from its last persistence point.</li>
<li>scalability: if thousands or workflows are executing at the same time (which is well possible, if workflows are long-running), persisting and unloading idle workflows decreases the memory usage and increases scalability. Scalability is further increased by the possibility to persist and unload from one machine and reload from a different machine.</li>
</ul>
<p>Adding support for persistence is straightforward and can be done declaratively in the configuration file. In addition, we also configure the workflow to be persisted whenever it reaches an idle point:</p>
<ul>
<li><span style="background-color: #ffff00;">add the SqlWorkflowInstanceStore and WorklfowIdle behaviors to web.config:</span></li>
</ul>
<div id="codeSnippetWrapper" style="font-size: 8pt; overflow: auto; cursor: text; font-family: 'Courier New', courier, monospace; width: 97.5%; direction: ltr; text-align: left; margin: 20px 0px 10px; line-height: 12pt; max-height: 200px; background-color: #f4f4f4; border: silver 1px solid; padding: 4px;">
<div id="codeSnippet" style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">system.serviceModel</span><span style="color: #0000ff;">&gt;</span></pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">  <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">behaviors</span><span style="color: #0000ff;">&gt;</span></pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">    <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">serviceBehaviors</span><span style="color: #0000ff;">&gt;</span></pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">      <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">behavior</span><span style="color: #0000ff;">&gt;</span></pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">        <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">sqlWorkflowInstanceStore</span> <span style="color: #ff0000;">connectionString</span><span style="color: #0000ff;">="Initial Catalog=WorkflowInstanceStore;Server=(local);Integrated Security=true"</span><span style="color: #0000ff;">/&gt;</span></pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">        <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">workflowIdle</span> <span style="color: #ff0000;">timeToUnload</span><span style="color: #0000ff;">="0:00:0"</span> <span style="color: #ff0000;">timeToPersist</span><span style="color: #0000ff;">="0:00:0"</span><span style="color: #0000ff;">/&gt;</span></pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">      <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">behavior</span><span style="color: #0000ff;">&gt;</span></pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">    <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">serviceBehaviors</span><span style="color: #0000ff;">&gt;</span></pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">  <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">behaviors</span><span style="color: #0000ff;">&gt;</span></pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">system.serviceModel</span><span style="color: #0000ff;">&gt;</span></pre>
<!--CRLF--></div>
</div>
<h1>Configuring Correlation</h1>
<p>Let&rsquo;s try the sample. Run the project, use WcfTestClient to execute, in the correct sequence, the operations StartWf and ContinueWf. Make sure to copy the instance id, output of StartWf, to the input of ContinueWf (without &ldquo;&rdquo;).</p>
<p>When you execute the ContinueWf project, you should get this error message in WcfTestClient:</p>
<div id="codeSnippetWrapper"><span style="color: #ff0000; font-family: Courier New;">System.ServiceModel.FaultException was unhandled <br />Message: An exception of type 'System.ServiceModel.FaultException' occurred in mscorlib.dll and wasn't handled before a managed/native boundary <br />Additional information: There is no context attached to the incoming message for the service and the current operation is not marked with "CanCreateInstance = true". In order to communicate with this service check whether the incoming binding supports the context protocol and has a valid context initialized. <br /></span></div>
<p>Why is that? The reason has to do with <span style="text-decoration: underline;"><em>how correlation is configured for this workflow</em></span>.</p>
<p>You may recall from the previous steps that we have two variables of type CorrelationHandle in our workflow: FirstRequestResponse and SecondRequestResponse. These correlation handles are initialized with a Request-reply correlation initializer (see the CorrelationInitializers property of ReceiveFirstOp and ReceiveSecondOp). They are used to correlate each Receive activity to its corresponding SendReply activity (or activities).</p>
<p>However, <span style="text-decoration: underline;"><em>we don&rsquo;t have anything that relates the first operation to the second operation</em></span>. In other words, we need something that, when the client calls the second operation, is able to identify to which running workflow instance this operation is directed.</p>
<p>There are two types of correlation that can be used for this purpose: context-exchange correlation and content-based correlation. <a href="https://msdn.microsoft.com/en-us/library/ee358754(v=vs.110).aspx">This MSDN topic</a> and its subtopics have all the details. We will be using content-based correlation in this case, because the workflow can be long running. The lifetime of a long-running workflow should not be constrained by the lifetime of the client that initiated it (in other words, it should be possible for one client to start the workflow, and for other clients to continue its execution). Since a context, established by context-exchange correlation, is limited to the lifetime of the client, it is not suitable for our needs.</p>
<p>Content-based correlation uses values (called instance keys) contained in the messages exchanged by client and service, that uniquely identify a workflow instance. In our MEP described above, this role can be played by the InstanceId. Therefore, we will configure content-based correlation using the InstanceId as the key. To do this, follow these steps:</p>
<ul>
<li><span style="background-color: #ffff00;">Add a variable named InstanceCorrelation of type CorrelationHandle, at Sequential Service scope</span></li>
<li><span style="background-color: #ffff00;">Set the CorrelationInitializers property of SendFirstOp: type InstanceCorrelation on the left, then select &ldquo;Query correlation initializer&rdquo; and select Content: String in the XPath query</span></li>
<li><span style="background-color: #ffff00;">Set the CorrelatesOn property of ReceiveSecondOp: set CorrelatesWith to InstanceCorrelation, and select Content: String in the XPath query</span></li>
</ul>
<p>The steps above look somewhat esoteric, but in fact they are pretty simple: we are basically specifying that the key that uniquely identifies the message is the InstanceId contained, in string form, in the response of the first operation and in the request of the second operation.</p>
<p>Let&rsquo;s now test that this fixed the previous FaultException: run with F5, execute the first operation, copy the output GUID and paste it into the input of the ContinueWf operation (make sure not to include the &ldquo;&rdquo;). This time everything should work and you should get &ldquo;Done with &lt;GUID&gt;&rdquo; in the Response of the ContinueWf operation.</p>
<p>Let&rsquo;s further test the effect of content-based correlation: as before, execute StartWf. Copy the returned GUID. However, this time after pasting the GUID in ContinueWf, modify it so that it does not match the one returned by StartWf and execute.</p>
<p>You should get this exception:</p>
<p><span style="color: #ff0000; font-family: Courier New;">System.ServiceModel.FaultException was unhandled <br />Message: An exception of type 'System.ServiceModel.FaultException' occurred in mscorlib.dll and wasn't handled before a managed/native boundary <br />Additional information: The execution of an InstancePersistenceCommand was interrupted because the instance key 'b4c6f11b-a465-87ce-fe6e-7cf3d2558b6c' was not associated to an instance. This can occur because the instance or key has been cleaned up, or because the key is invalid. The key may be invalid if the message it was generated from was sent at the wrong time or contained incorrect correlation data.</span></p>
<p>The key that we provided is invalid, because there isn&rsquo;t any running workflow instance with that instance id, hence the exception.</p>
<p><strong>Note</strong>: if you query the InstancesTable table of the persistence database, you should find an instance with the GUID used in the last test: since we failed to execute the second operation, that workflow instance is still running, persisted in the database.</p>
<h1>Adding Support for Multiple Versions</h1>
<p>After sorting out all the previous steps, we are now ready to implement side-by-side execution. The steps are pretty easy, but let&rsquo;s first look at the api provided at WF Runtime level since WF4.5, as this helps understand what happens in IIS/WAS-hosted workflows.</p>
<p>WorkflowService in WF4.5 has a new property, DefinitionIdentity of type <strong>WorkflowIdentity</strong>, which identifies a particular version of a workflow service definition. In addition, WorkflowServiceHost has a SupportedVersions property, which is a collection of WorkflowService instances.</p>
<p>When explicitly using WorkflowServiceHost (self-hosting), a host that supports multiple versions side-by-side would use the following code:</p>
<div id="codeSnippetWrapper">
<div id="codeSnippet" style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">WorkflowService initialService = <span style="color: #0000ff;">new</span> WorkflowService</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">{    </pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">    Name = <span style="color: #006080;">"MyWorkflowService"</span>,</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">    Body = <span style="color: #0000ff;">new</span> MyWorkflowService1(),</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">    DefinitionIdentity = <span style="color: #0000ff;">new</span> WorkflowIdentity(<span style="color: #006080;">"Initial Version"</span>, <span style="color: #0000ff;">new</span> Version(1, 0, 0, 0), <span style="color: #0000ff;">null</span>)</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">};</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">&nbsp;</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">WorkflowService updatedService = <span style="color: #0000ff;">new</span> WorkflowService</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">{</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">   Name = <span style="color: #006080;">"MyWorkflowService"</span>,</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">   Body = <span style="color: #0000ff;">new</span> MyWorkflowService2(),</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">   DefinitionIdentity = <span style="color: #0000ff;">new</span> WorkflowIdentity(<span style="color: #006080;">"Updated Version"</span>, <span style="color: #0000ff;">new</span> Version(2, 0, 0, 0), <span style="color: #0000ff;">null</span>)</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">};</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">WorkflowServiceHost sh = <span style="color: #0000ff;">new</span> WorkflowServiceHost(updatedService);</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">sh.SupportedVersions.Add(initialService);</pre>
<!--CRLF--><!--CRLF--></div>
</div>
<p>This host will implement SxS versioning, in that</p>
<ul>
<li>when a new workflow is activated, version 2.0.0.0 is used</li>
<li>when a request directed at an existing instance arrives, the correct workflow definition will be used, if it is 1.0.0.0 or 2.0.0.0.</li>
</ul>
<p>For IIS/WAS-hosted workflow services, this same effect can be achieved by using a well-defined naming convention for workflow services and the folders that contain them. Specifically:</p>
<ul>
<li>the .xamlx file at the URL used by the client is the &ldquo;main version&rdquo;, equivalent to the one used as an argument of the WorkflowServiceHost constructor in the code above</li>
<li>all the .xamlx files placed under subfolders of <strong>App_Code</strong>, named after the workflow service itself, are &ldquo;supported versions&rdquo;, equivalent to those added to the SupportedVersions collection in the code above.</li>
</ul>
<p>The DefnitionIdentity property of WorkflowService can be set directly in the workflow designer.</p>
<p>In our sample, we opt for a change to the InstanceId that is used to uniquely identify the workflow. Instead of the GUID, we want to use the syntax InstanceId: GUID. Before making the change, we run StartWf and get the Instance ID back. This is to ensure that, after making the change, we&rsquo;ll have an instance running with the previous workflow definition.</p>
<p>In order to support SxS execution in our sample:</p>
<ul>
<li><span style="background-color: #ffff00;">Set the DefinitionIdentity property of Service1.xamlx: set Name to &ldquo;Service1&rdquo; and Version to 1.0.0.0. Leave Package empty.</span></li>
<li><span style="background-color: #ffff00;">Create a subfolder called App_Code</span></li>
<li><span style="background-color: #ffff00;">Create a subfolder of App_Code, named Service1</span></li>
<li><span style="background-color: #ffff00;">Copy Service1.xamlx to the Service1 subfolder, possibly changing the file name (for instance, Service1_v1.xamlx)</span></li>
<li><span style="background-color: #ffff00;">Make changes to the top-level Service1.xamlx file: set Version in DefinitionIdentity to 2.0.0.0; set SendFirstOp&rsquo;s Content to &lsquo;&ldquo;Instance Id: &ldquo; + sInstanceId; set SendSecondOp&rsquo;s Content to "V2: Done with " + sInstanceId</span></li>
<li><span style="background-color: #ffff00;">Build and run</span></li>
<li><span style="background-color: #ffff00;">Execute StartWf. This will start a new workflow that uses version 2.0.0.0, so you should get a response like &ldquo;Instance Id: &lt;GUID&gt;&rdquo;</span></li>
<li><span style="background-color: #ffff00;">Copy the string and paste (without quotes) in the Request of ContinueWf. You should get the Response: &ldquo;V2: Done with Instance Id: &lt;GUID&gt;&rdquo;</span></li>
<li>Execute ContinueWf using this time the GUID returned by StartWf before we introduced versioning. You should get the Response &ldquo;Done with Instance Id: &lt;GUID&gt;&rdquo;. This shows that this workflow instance continued execution using the original workflow definition, thus achieving the desired SxS versioning behavior.</li>
</ul>
<h1>Constraints of Multiple Versions</h1>
<p>You may have noticed that, when upgrading our workflow service from version 1.0.0.0 to version 2.0.0.0, we haven&rsquo;t changed the MEP between client and service. Note that the client code does not change and the choice of which version to use is taken at runtime on the service side. Any change to the MEP between client and service, for instance</p>
<ul>
<li>Changing the names of the operations</li>
<li>Changing the number or type of the arguments of the operations</li>
<li>Adding / removing operations to the MEP</li>
<li>Changing the type of the operation from Request/Response to OneWay or vice-versa</li>
</ul>
<p>For the sake of completeness, let&rsquo;s see what happens if we change the MEP:</p>
<ul>
<li>Under App_Code\Service1, copy Service1_v1.xamlx to Service1_v15.xamlx</li>
<li>Change DefinitionIdentity for Service1_V15.xamlx: set Version to 1.5.0.0</li>
<li>Modify SendFirstOp of Service1_V15.xamlx: set Content to InstanceId instead of sInstanceId</li>
<li>Build and run.</li>
</ul>
<p>When WcfTestClient starts, it should display an error message. If you look at it in Html View, you should see an error message like this:</p>
<p><span style="color: #ff0000; font-family: Courier New;">Exception loading supported version 'App_Code\Service1\Service1_v15.xamlx': Two SendReply objects with same ServiceContractName and OperationName 'StartWf' have different ValueType.</span></p>
<p>Before going forward, remove Service1_v15.xamlx, otherwise the service won&rsquo;t start.</p>
<h1>Updating Code Activities</h1>
<p>So far in our example, the changes were relative to the .xamlx file only. Workflows, however, are made of activities, and some of them can be custom activities, which in turn may also use custom assemblies in their implementation. When it comes to modifying a workflow definition, therefore, the changes are not necessarily restricted to the .xamlx workflow service; they may also affect custom assemblies (eventually the same assembly where .xamlx files are located).</p>
<p><strong>Note</strong>: the following considerations on assembly version handling apply to code activities and other custom assemblies as well.</p>
<p>In order to exemplify the concept, let&rsquo;s now make a variation to our previous change: instead of changing the returned string by editing the Content of SendFirstOp, we change the implementation of the WfInstanceId activity to return a string with the new syntax. This also requires changing the type of OutArgument of WfInstanceId, from System.Guid to String.</p>
<p>This change requires modification to both the .xamlx file and the compiled assembly, where WfInstanceId is defined. Mind that, if we want to support SxS for the workflow service, <span style="text-decoration: underline;"><em>we need to keep both versions</em></span> of the assembly: running instances that use the previous version will still need access to the previous version of WfInstanceId.</p>
<p>In .Net it is possible to keep multiple versions of an assembly in this way:</p>
<ul>
<li>give different assembly version to the assemblies</li>
<li>put the assemblies in the GAC</li>
</ul>
<p><strong>Note</strong>: assembly version is different from the file version. In .Net, assembly version is set with the AssemblyVersion attribute, the file version is set with the AssemblyFileVersion attribute.</p>
<p><strong>Note</strong>: in order to put the assemblies in the GAC it is also necessary to give them a strong name.</p>
<p>All this is simplified if we factor out the custom activity in a separate assembly, so let&rsquo;s do it first:</p>
<ul>
<li><span style="background-color: #ffff00;">Add a new project to the solution, of type class library. We can call it ActivityLibrary (but feel free to choose a different name)</span></li>
<li><span style="background-color: #ffff00;">Remove Class1.cs from the project, as we won&rsquo;t use it</span></li>
<li><span style="background-color: #ffff00;">Move WfInstanceId.cs from the previous project to the new project. You may want to change the namespace for the WfInstanceId activity. Also fix-up assembly references (add System.Activities).</span></li>
</ul>
<p>Now we need to give a strong name to the assembly built out of this new project, and to put the assembly in the GAC at the end of each successful build:</p>
<ul>
<li><span style="background-color: #ffff00;">In the Project Properties of ActivityLibrary, in the Signing tab, check &ldquo;Sign the assembly&rdquo; and choose a .snk file (or create new, if you don&rsquo;t have one already)</span></li>
<li><span style="background-color: #ffff00;">In the Project Properties of ActivityLibrary, in the Build Events tab, add a Post-build event &ldquo;gacutil.exe &ndash;i $(TargetPath)&rdquo; (you&rsquo;ll need to use the full path to gacutil.exe, if it is not in the PATH environment variable)</span></li>
</ul>
<p>If you build the ActivityLibrary project, you should see that the assembly is now in the GAC (look under %WINDIR%\Microsoft.NET\assembly).</p>
<p>The assembly we have just built has version 1.0.0.0, this is determined by the AssemblyVersion attribute in AssemblyInfo.cs. Now let&rsquo;s build version 2.0.0.0 of this assembly, with the updated WfInstanceId activity:</p>
<ul>
<li><span style="background-color: #ffff00;">Set the AssemblyVersion attribute to 2.0.0.0 in AssemblyInfo.cs</span></li>
<li><span style="background-color: #ffff00;">Modify the WfInstanceId activity in this way:</span></li>
</ul>
<div>
<div id="codeSnippet" style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> WfInstanceId: CodeActivity</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">{</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">    <span style="color: #0000ff;">public</span> OutArgument&lt;<span style="color: #0000ff;">string</span>&gt; InstanceId</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">    {</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">        get; set;</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">    }</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">&nbsp;</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">    <span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">override</span> <span style="color: #0000ff;">void</span> Execute(CodeActivityContext context)</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">    {</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">        InstanceId.Set(context, <span style="color: #006080;">"Instance Id: "</span> + context.WorkflowInstanceId.ToString());</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">    }</pre>
<!--CRLF-->
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">}</pre>
<!--CRLF--></div>
</div>
<ul>
<li>Build the solution (including the SxSWfSvc project). If you look at the GAC now, you should see that both version 1.0.0.0 and version 2.0.0.0 of the assembly are present.</li>
</ul>
<p>Let&rsquo;s recall that different versions of our workflow service will need to use different versions of the WfInstanceId activity. Let&rsquo;s open the two .xamlx files in the designer. You should see something like this:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/8407.WfWithErrorInActivity_346A74CC.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/8407.WfWithErrorInActivity_5F00_346A74CC.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border: 0px;" title="WfWithErrorInActivity" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/6431.WfWithErrorInActivity_thumb_617F619A.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/6431.WfWithErrorInActivity_5F00_thumb_5F00_617F619A.png" alt="WfWithErrorInActivity" width="268" height="484" border="0" /></a></p>
<p>The reason of the error is that the referenced activity is still the one contained in SxSSvcWf, which is no longer present. At the same time, in the toolbox you will see the new WfInstanceId activity under the ActivityLibrary category. For both .xamlx files, let&rsquo;s fix the error:</p>
<ul>
<li><span style="background-color: #ffff00;">Remove the old WfInstanceId activity (the red box)</span></li>
<li><span style="background-color: #ffff00;">Drag&amp;Drop the new WfInstanceId activity in the same position</span></li>
</ul>
<p>We also need to bind the InstanceId argument of the WfInstanceId activity. You&rsquo;ll notice, if you try to bind it, that for both XAMLX files the InstanceId argument appears to be of type String:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/6518.NewInstanceIdArgument_11A93D0F.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/6518.NewInstanceIdArgument_5F00_11A93D0F.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border: 0px;" title="NewInstanceIdArgument" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/7851.NewInstanceIdArgument_thumb_185C4692.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/7851.NewInstanceIdArgument_5F00_thumb_5F00_185C4692.png" alt="NewInstanceIdArgument" width="244" height="133" border="0" /></a></p>
<p>In other words, both versions of the workflow service are now using the WfInstanceId activity contained in version 2.0.0.0 of the ActivityLibrary assembly, This is not what we want, and it is happening because the activity in the toolbox is version 2.0.0.0. Let&rsquo;s make the following changes:</p>
<ul>
<li><span style="background-color: #ffff00;">Remove the WfInstanceId activity from the Toolbox</span></li>
<li><span style="background-color: #ffff00;">Right-click on the ActivityLibrary category in the Toolbox and select &ldquo;Choose Items&hellip;&rdquo;</span></li>
<li><span style="background-color: #ffff00;">In the dialog box, click the Browse button and select ActivityLibrary.dll version 1.0.0.0 and ActivityLibrary version 2.0.0.0 from the GAC, as shown below:</span></li>
</ul>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/4478.WfInstanceIdBothVersions_137992D6.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/4478.WfInstanceIdBothVersions_5F00_137992D6.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border: 0px;" title="WfInstanceIdBothVersions" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/8461.WfInstanceIdBothVersions_thumb_2EB1EBD7.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/8461.WfInstanceIdBothVersions_5F00_thumb_5F00_2EB1EBD7.png" alt="WfInstanceIdBothVersions" width="644" height="460" border="0" /></a></p>
<p>&nbsp;</p>
<p>When you click Ok, you should get a cryptic message box with this message:</p>
<p>The following controls were successfully added to the toolbox but are not enabled in the active designer: WfInstanceId</p>
<p>This message means that we do have both activities in the toolbox, but only one of them is shown when the current workflow service is open. If we hover on the WfInstanceId activity shown in the Toolbox, we find out that it is version 2.0.0.0. If we open the other version of the workflow service, the same thing happens. So our workflow services are still referencing version 2.0.0.0 of the ActivityLibrary assembly.</p>
<p>Let&rsquo;s have a look at how ActivityLibrary is referenced by our workflow services. In order to do this, we need to switch to the XAML view of the workflow services. Right-click on Service1.xamlx and select &ldquo;View Code&rdquo;. Near the beginning of the xamlx file you should see something like this:</p>
<div id="codeSnippetWrapper">
<div id="codeSnippet" style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">xmlns:a="clr-namespace:ActivityLibrary;assembly=ActivityLibrary"</pre>
<!--CRLF--></div>
</div>
<p>In other words. the assembly reference is qualified only by name, not by the fully qualified assembly name, including version and public key token. This is how the workflow designer adds assembly references automatically, and it has its own advantages in some scenarios. If there are multiple versions in the GAC, the latest is loaded. This explains why we could only see version 2.0.0.0 in the Toolbox.</p>
<p>The good thing is that you can manually modify the default, and fully qualify an assembly reference. Since we need to reference different versions of the assembly from our workflow services, do the following:</p>
<ul>
<li><span style="background-color: #ffff00;">open the top-level Service1.xamlx and replace the assembly reference with:</span></li>
</ul>
<div id="codeSnippetWrapper" style="font-size: 8pt; overflow: auto; cursor: text; font-family: 'Courier New', courier, monospace; width: 97.5%; direction: ltr; text-align: left; margin: 20px 0px 10px; line-height: 12pt; max-height: 200px; background-color: #f4f4f4; border: silver 1px solid; padding: 4px;">
<div id="codeSnippet" style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">xmlns:a="clr-namespace:ActivityLibrary;assembly=ActivityLibrary, Version=2.0.0.0, Culture=neutral, PublicKeyToken=4a41ef8fd7501054"</pre>
<!--CRLF--></div>
</div>
<div>&nbsp;</div>
<ul>
<li><span style="background-color: #ffff00;">open the xaml under App_Code and replace the assembly reference with:</span></li>
</ul>
<div id="codeSnippetWrapper" style="font-size: 8pt; overflow: auto; cursor: text; font-family: 'Courier New', courier, monospace; width: 97.5%; direction: ltr; text-align: left; margin: 20px 0px 10px; line-height: 12pt; max-height: 200px; background-color: #f4f4f4; border: silver 1px solid; padding: 4px;">
<div id="codeSnippet" style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">
<pre style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">xmlns:a="clr-namespace:ActivityLibrary;assembly=ActivityLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4a41ef8fd7501054"</pre>
<!--CRLF--></div>
</div>
<p><strong>Note</strong>: The PublicKeyToken depends on the signing key and will be different in your case, You can find the full assembly reference using ILDASM, ILSpy or another disassembly tool.</p>
<p>After saving the .xamlx files, open them under the designer. If you try to bind the InstanceId argument of WfInstanceId, you should find that each workflow service is referencing its own version. So in the workflow service under App_Code you should see that the argument is of type Guid:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/1373.OldInstanceIdArgument_5E6F9456.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/1373.OldInstanceIdArgument_5F00_5E6F9456.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border: 0px;" title="OldInstanceIdArgument" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/0410.OldInstanceIdArgument_thumb_7E1E6E1E.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/0410.OldInstanceIdArgument_5F00_thumb_5F00_7E1E6E1E.png" alt="OldInstanceIdArgument" width="244" height="132" border="0" /></a></p>
<p>Now let&rsquo;s complete the binding. For the workflow service 1.0.0.0:</p>
<ul>
<li><span style="background-color: #ffff00;">Bind InstanceId to the InstanceId variable, as before</span></li>
</ul>
<p>For the workflow service version 2.0.0.0:</p>
<ul>
<li><span style="background-color: #ffff00;">Bind InstanceId to the sInstanceId variable</span></li>
<li><span style="background-color: #ffff00;">Remove the Assign activity that follows the WfInstanceId activity in the workflow</span></li>
</ul>
<p>If you try this time, you should see that both new workflows and existing workflows can run successfully.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/10/66/06/73/SxSWfSvc.zip" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-66-06-73/SxSWfSvc.zip">SxSWfSvc.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Dynamic Update in WF4.5: Sample using a re-hosted Workflow Designer</title>
      <link>https://docs.microsoft.com/archive/blogs/carlos/dynamic-update-in-wf4-5-sample-using-a-re-hosted-workflow-designer</link>
      <pubDate>Fri, 29 Nov 2013 03:23:00 GMT</pubDate>
      <dc:creator><![CDATA[carcolo]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/carlos/2013/11/29/dynamic-update-in-wf4-5-sample-using-a-re-hosted-workflow-designer/</guid>
      <description><![CDATA[Introduction
WF 4.5 added Versioning and Dynamic Updates to workflows.
The dynamic update process...]]></description>
      <content:encoded><![CDATA[<h1>Introduction</h1>
<p>WF 4.5 added Versioning and Dynamic Updates to workflows.</p>
<p>The dynamic update process consists in 2 main steps:</p>
<ol type="A">
<li>Defining the update, in terms of changes to the workflow definition. The output of this step is an Update Map</li>
<li>Applying the Update Map to persisted workflow instances</li>
</ol>
<p>Step A. above takes place in 3 substeps:</p>
<ol>
<li>Calling DynamicUpdateServices.PrepareForUpdate(Activity), where activity is the root activity of the workflow definition</li>
<li>Making <strong>in-memory</strong> changes to the workflow definition</li>
<li>Calling DynamicUpdateServices.CreateUpdateMap(Activity). This creates an update map, which is typically persisted, to be used sometime later to carry out step B. above.</li>
</ol>
<h1>Under the hood</h1>
<p>Steps 1. &ndash; 3. above must be applied to <strong>the same</strong> in-memory workflow definition. This is because DynamicUpdateServices.PrepareForUpdate(activity) prepares that specific in-memory workflow definition for update, so the following call to CreateUpdateMap() must happen on the same in-memory instance.</p>
<p>PrepareForUpdate() annotates the in-memory workflow definition with information that will be used at a later time, when CreateUpdateMap() is called, to compute the delta. This is logically equivalent to creating an internal cloned workflow definition.</p>
<p><strong>Note</strong>: PrepareForUpdate() and CreateUpdateMap() have overloads that take an ActivityBuilder as an argument, instead of an Activity. This simplifies the usage in conjunction with workflow definitions loaded from XAML (XamlServices.Load() returns an ActivityBuilder object, not an Activity), but it does not change the requirement that changes be applied to the in-memory workflow definition.</p>
<h1>The Code Approach</h1>
<p>Let&rsquo;s focus now on step A.2 above, the in-memory changes to the workflow definition.</p>
<p>The easiest approach to the in-memory changes is to hard-code the changes in code. <a href="http://msdn.microsoft.com/pl-pl/library/jj205427(v=vs.110).aspx">This link</a> exemplifies this process. See, specifically, the &ldquo;To update StateMachineNumberGuessWorkflow&rdquo;, &ldquo;To update FlowchartNumberGuessWorkflow&rdquo; and | To update SequentialNumberGuessWorkflow&rdquo; sections.</p>
<p>This approach works just fine. However, by hard-coding the changes into the program, it</p>
<ul>
<li>requires a different program for each new change</li>
<li>requires a programmer to make the change, instead of a business owner</li>
<li>may require a complex and hard-to-read sequence of statements in order to make a simple change to the workflow definition. This is especially true when the changes are made deep into the hierarchy of activities</li>
</ul>
<p>In order to overcome these limitations, the changes would have to be made through the Workflow Designer, instead of being hard-coded. The requirement that the changes be made to the in-memory workflow definition rules out the Workflow Designer used in Visual Studio however: the WF Designer used in Visual Studio loads a workflow from a XAML file and saves the change to a XAML file, so it is not usable to make in-memory changes to a workflow definition.</p>
<h1>The Re-hosted Workflow Designer Approach</h1>
<p>The Workflow Designer, thankfully, is a reusable component that can be hosted in any process. Visual Studio just happens to be one host of Workflow Designer. By re-hosting the Workflow Designer in a custom host, we may be able to allow in-memory changes to the workflow definition through the Workflow Designer.</p>
<h1>The Sample Code</h1>
<p>The sample code attached to this post is general-purpose: the input is a workflow in XAML and the output, after the user makes changes to the workflow definition in the designer, are:</p>
<ul>
<li>the XAML file of the modified workflow</li>
<li>the update map (XML file)</li>
</ul>
<p>To use the sample:</p>
<ul>
<li>Load a workflow from the FIle&hellip;Open Workflow Definition menu item. DynamicUpdateServices.PrepareForUpdate() is called at this stage.</li>
<li>Make the changes to the workflow definition in the designer. This includes adding activities, modifying existing activities, adding/removing variables and arguments.</li>
<li>Save the workflow and create the update map using the File&hellip;Save and Create Update Map menu item. First, you can save the workflow definition to a .XAML file. Then, if you choose to save the update map, DynamicUpdateServices.CreateUpdateMap() is called and the update map is saved to an XML file.</li>
</ul>
<p>This is how the program looks like, when a workflow definition is loaded:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/3681.AppSnapshot_4CC25584.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/3681.AppSnapshot_5F00_4CC25584.png"><img style="display: inline;" title="AppSnapshot" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/8360.AppSnapshot_thumb_65792EDA.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/8360.AppSnapshot_5F00_thumb_5F00_65792EDA.png" alt="AppSnapshot" width="446" height="288" border="0" /></a></p>
<h3><strong>A word of caution</strong></h3>
<p>A re-hosted Workflow Designer does not always offer the same user experience of the Workflow Designer in Visual Studio, because the Workflow Designer can be configured in many different ways.</p>
<p>For instance, the Services and Items of the Editing Context may be different, or configured differently. Also, a re-hosted Workflow Designer has some <a href="http://msdn.microsoft.com/en-us/library/jj205428(v=vs.110).aspx">limitations</a>. As far as dynamic update of workflows goes, though, these limitations should not be a roadblock.</p>
<p>You&rsquo;ll also notice that the behavior of the Toolbox in the sample differs from that of Visual Studio:</p>
<ul>
<li>at startup, a pre-defined set of common activities is loaded in the Toolbox, grouped into a set of categories</li>
<li>when a workflow definition is loaded, the activities of the workflow are added to a new category called Auto, displayed at the top of the toolbox</li>
<li>it is possible to load additional activities by using the File | Add Activities in Assembly&hellip; menu item. All the activities in that assembly are added to a new category, named after the assembly, displayed at the bottom of the toolbox. You may want to load the System.Activities.dll assembly to see a broad range of activities (more than the Visual Studio toolbox shows)</li>
<li>you can remove an entire category or an activity from the toolbox by right-clicking on them and selecting Remove</li>
</ul>
<p>The sample provided here is not production-ready code: error handling is minimal, it does not have tracing or logging, and it has not been extensively tested.</p>
<p>All this said :-), if you find any issue with the sample, please let me know.</p>
<p>Enjoy!</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/10/47/26/22/UpdateWithDesigner.zip" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-47-26-22/UpdateWithDesigner.zip">UpdateWithDesigner.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>How to clean up a WF4 persistence database</title>
      <link>https://docs.microsoft.com/archive/blogs/carlos/how-to-clean-up-a-wf4-persistence-database</link>
      <pubDate>Thu, 24 Oct 2013 03:07:34 GMT</pubDate>
      <dc:creator><![CDATA[carcolo]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/carlos/2013/10/24/how-to-clean-up-a-wf4-persistence-database/</guid>
      <description><![CDATA[Introduction  The SqlWorkflowInstanceStore class in WF4 uses a Sql Server database for persistence....]]></description>
      <content:encoded><![CDATA[<h1>Introduction</h1>  <p>The SqlWorkflowInstanceStore class in WF4 uses a Sql Server database for persistence. See <a href="http://blogs.msdn.com/b/carlos/archive/2013/01/10/workflow-foundation-sql-scripts.aspx">this post</a> for more details on how you can create the schema and the logic for the persistence database.</p>  <p>The database stores the serialized form of workflow instances, along with lock and key information.</p>  <h1>Database clean-up</h1>  <p>You may need to restart from a clean database from time to time. This can be a consequence of some testing, that caused the accumulation of a number of persisted instances that you do not want to, or can’t, continue to execute. In these cases, you may decide to remove the database altogether, create a new one and re-create its schema and logic.</p>  <p>However, there may be scenarios where deleting and re-creating the database is not convenient, for one of these reasons:</p>  <ul>   <li>You changed the permissions in the database. The typical case is when the client process is the IIS/WAS worker process W3WP.EXE, and you added a user for its identity (NETWORK SERVICE, for instance) and appropriate role membership for it.</li>    <li>You need to act quickly, possibly because this is a production environment that ended up in an unexpected state and you want to quickly restore a working environment.</li>    <li>You are sharing the persistence DB with “something else”. For instance, the AppFabric Monitoring and AppFabric Persistence schemas (a superset of the WF4 Persistence schema) can coexist in the same database.</li> </ul>  <p>In these cases, you may prefer to simply clean up the existing database. </p>  <p>A few caveats apply:</p>  <ul>   <li>Cleaning up the persistence database may cause loss of data: if there are workflow instances currently persisted in the database, you won’t be able to reload them in memory at a later time, after cleaning up the persistence database.</li>    <li>The clean up of the database should take place when all its users (all the applications that are using this database as the persistence store for workflows) are in a stopped state. Running processes that use workflows may make use of existing entries in the LockOwnersTable and would raise an exception if those entries are removed.</li>    <li>The schema of the persistence database may change in future releases of WF. It is not guaranteed that this procedure will work with future releases of WF. The current release as of this writing is WF 4.5.</li> </ul>  <p>Clean up consists in truncating the contents of <strong>nearly</strong> all the persistence tables in the database, This is a stored procedure that you can use:</p>  <div id="codeSnippetWrapper">   <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">CREATE</span> <span style="color: rgb(0, 0, 255);">PROCEDURE</span> [dbo].[DeleteAll] <br /><span style="color: rgb(0, 0, 255);">AS</span><br /> <span style="color: rgb(0, 0, 255);">BEGIN</span><br />     <span style="color: rgb(0, 0, 255);">SET</span> NOCOUNT <span style="color: rgb(0, 0, 255);">ON</span>;<br />     <span style="color: rgb(0, 0, 255);">SET</span> <span style="color: rgb(0, 0, 255);">TRANSACTION</span> <span style="color: rgb(0, 0, 255);">ISOLATION</span> <span style="color: rgb(0, 0, 255);">LEVEL</span> <span style="color: rgb(0, 0, 255);">READ</span> COMMITTED<br />     <span style="color: rgb(0, 0, 255);">SET</span> XACT_ABORT <span style="color: rgb(0, 0, 255);">ON</span>;    <br /><br />    <span style="color: rgb(0, 0, 255);">BEGIN</span> <span style="color: rgb(0, 0, 255);">TRANSACTION</span><br /><br />    <span style="color: rgb(0, 0, 255);">TRUNCATE</span> <span style="color: rgb(0, 0, 255);">TABLE</span> [System.Activities.DurableInstancing].[IdentityOwnerTable];<br />    <span style="color: rgb(0, 0, 255);">TRUNCATE</span> <span style="color: rgb(0, 0, 255);">TABLE</span> [System.Activities.DurableInstancing].[InstanceMetadataChangesTable];<br />    <span style="color: rgb(0, 0, 255);">TRUNCATE</span> <span style="color: rgb(0, 0, 255);">TABLE</span> [System.Activities.DurableInstancing].[InstancePromotedPropertiesTable];<br />    <span style="color: rgb(0, 0, 255);">TRUNCATE</span> <span style="color: rgb(0, 0, 255);">TABLE</span> [System.Activities.DurableInstancing].[KeysTable];<br />    <span style="color: rgb(0, 0, 255);">TRUNCATE</span> <span style="color: rgb(0, 0, 255);">TABLE</span> [System.Activities.DurableInstancing].[LockOwnersTable];<br />    <span style="color: rgb(0, 0, 255);">TRUNCATE</span> <span style="color: rgb(0, 0, 255);">TABLE</span> [System.Activities.DurableInstancing].[RunnableInstancesTable];<br />    <span style="color: rgb(0, 0, 255);">TRUNCATE</span> <span style="color: rgb(0, 0, 255);">TABLE</span> [System.Activities.DurableInstancing].[ServiceDeploymentsTable];<br />    <span style="color: rgb(0, 0, 255);">TRUNCATE</span> <span style="color: rgb(0, 0, 255);">TABLE</span> [System.Activities.DurableInstancing].[InstancesTable];<br /><br />    <span style="color: rgb(0, 0, 255);">COMMIT</span> <span style="color: rgb(0, 0, 255);">TRANSACTION</span><br /> <span style="color: rgb(0, 0, 255);">END</span><br /></pre>

  <br /></div>


<p><strong>Note:</strong> the table IdentityOwnerTable is part of the Workflow Persistence Schema since WF4.5. Therefore, if you are using WF4.0, the first TRUNCATE statement in the procedure above should be removed.</p>]]></content:encoded>
    </item>
    <item>
      <title>Debugging Multiple CLRs (InProc SxS)</title>
      <link>https://docs.microsoft.com/archive/blogs/carlos/debugging-multiple-clrs-inproc-sxs</link>
      <pubDate>Fri, 06 Sep 2013 07:29:00 GMT</pubDate>
      <dc:creator><![CDATA[carcolo]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/carlos/2013/09/06/debugging-multiple-clrs-inproc-sxs/</guid>
      <description><![CDATA[Introduction
In the previous post, we looked at how multiple CLRs can be loaded in the same process...]]></description>
      <content:encoded><![CDATA[<h1>Introduction</h1>
<p>In the <a href="http://blogs.msdn.com/b/carlos/archive/2013/08/23/loading-multiple-clr-runtimes-inproc-sxs.aspx">previous post</a>, we looked at how multiple CLRs can be loaded in the same process (CLR InProc SxS).</p>
<p>In this post, we&rsquo;ll build on the example from that post to look at how we can do debugging of processes that use multiple CLRs. We&rsquo;ll focus on CLR4 with CLR2, because CLR 1.x has been largely replaced by new versions (though the same considerations should apply to CLR4 with CLR 1.x).</p>
<p>We&rsquo;ll focus on the two most popular ways to debug managed processes: Visual Studio and WinDbg + the SOS debugger extension. Visual Studio has&nbsp; friendlier user interface and is easier to use, WinDbg + SOS allows more in-depth debugging, and is especially versed towards dump analysis.</p>
<h1>Visual Studio 2012</h1>
<p>With reference to the sample code, if we start ConsoleApplication3 under the debugger, and we let it execute until both CLRs are loaded (Console.ReadKey() statement in Main()), everything seems to work fine as we debug.</p>
<p>If we look at the modules window, however, we see the following:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/3005.Modules7_7C6AAD45.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/3005.Modules7_5F00_7C6AAD45.png"><img style="display: inline; background-image: none;" title="Modules" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/5826.Modules7_thumb_64D2FFD2.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/5826.Modules7_5F00_thumb_5F00_64D2FFD2.png" alt="Modules" width="644" height="189" border="0" /></a></p>
<p>The modules in the window are assemblies loaded by the CLR2. ClassLibrary3.dll, loaded by the CLR4, is notably missing here.</p>
<p>If you set breakpoints inside ClassLibrary3.dll, for example in Class1.DoNothing()), the breakpoint won&rsquo;t be hit. All these symptoms have the same common root: only the CLR2 debugger is active. This is because the process started as a CLR2 process (ConsoleApplication3 binds to CLR2) and, consequently, Visual Studio loaded the &ldquo;right&rdquo; CLR debugger.</p>
<p>If we attach Visual Studio to a running process, we do have a way to manually choose the Visual Studio debuggers, by using the Debug&hellip;Attach to Process menu item.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/1754.AttachToProcess_4211C815.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/1754.AttachToProcess_5F00_4211C815.png"><img style="display: inline; background-image: none;" title="AttachToProcess" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/4265.AttachToProcess_thumb_28402297.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/4265.AttachToProcess_5F00_thumb_5F00_28402297.png" alt="AttachToProcess" width="618" height="484" border="0" /></a></p>
<p>So we run the process again, outside of Visual Studio (Ctrl+F5), and we attach later on and select the debuggers. Note however that you can&rsquo;t select both CLR2 and CLR4:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/2555.MultipleDebuggers_2C4D011A.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/2555.MultipleDebuggers_5F00_2C4D011A.png"><img style="display: inline; background-image: none;" title="MultipleDebuggers" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/6708.MultipleDebuggers_thumb_77AF358F.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/6708.MultipleDebuggers_5F00_thumb_5F00_77AF358F.png" alt="MultipleDebuggers" width="569" height="484" border="0" /></a></p>
<p>Note however that, once you attached to a process, <em><span style="text-decoration: underline;">you can&rsquo;t further change the debugger during the same debugging session</span></em>: the user interface of the Attach To Process dialog grays out the currently debugged process.</p>
<p>If we restart the process and attach using the CLR4 debugger this time, we have a different managed view of the debuggee. For instance, this is the set of managed modules:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/0882.Modules-CLR4_2DB3B49D.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/0882.Modules_2D00_CLR4_5F00_2DB3B49D.png"><img style="display: inline; background-image: none;" title="Modules CLR4" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/5125.Modules-CLR4_thumb_71F6AC9A.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/5125.Modules_2D00_CLR4_5F00_thumb_5F00_71F6AC9A.png" alt="Modules CLR4" width="783" height="82" border="0" /></a></p>
<p>Along the same lines: a breakpoint in ClassLibrary3.dll (using CLR4) will be hit, but a breakpoint in ConsoleApplication3.exe (using CLR2) will not.</p>
<p><strong>Note</strong>: you may have noticed that mscorlib.dll shows up in the list of modules when the CLR2 is being debugged, and when CLR4 is being debugged. Note however that they are different modules: version and timestamp are different.</p>
<p><strong>Note</strong>: you can also enable native debugging (step into native code, setting breakpoints on native code, etc.) by selecting the &ldquo;Enable Native Code Debugging&rdquo; check box in the Debug tab of the startup project (ConsoleApplication3 in this case). With this sample, this may be handy if you want to follow the thread of execution from ConsoleApplication3 to ATLProject1, down to Classlibrary3. With Visual Studio 2012, this works for 32-bit builds, not for 64-bit builds (mixed-mode debugging is not supported for 64-bit with earlier versions of the .Net Framework).</p>
<h4>Exceptions</h4>
<p>The same story applies to exceptions: only exceptions raised by a debugged CLR are recognized by Visual Studio. Since you can debug at most one CLR at a time, this means that you don&rsquo;t have a way to break the debugger on every managed exception. This is a limitation especially if you are troubleshooting a complex issue and any exception can put you on the right track.</p>
<h1>WinDbg with SOS</h1>
<p>If we attach WinDbg to a running process using both CLR2 and CLR4, we&rsquo;ll see that both CLR dlls are loaded:</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.46%; height: 100%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre id="codeSnippet" class="csharpcode"><strong>0:008<span class="kwrd">&gt;</span> lm v mclr</strong><br />start             end                 module name<br />00007ffc`6e020000 00007ffc`6e9b8000   clr        (deferred)             <br />    Image path: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll<br />    Image name: clr.dll<br />    Timestamp:        Tue Aug 06 01:43:57 2013 (520038BD)<br />    CheckSum:         0099DECA<br />    ImageSize:        00998000<br />    File version:     4.0.30319.33440<br />    Product version:  4.0.30319.33440<br />    File flags:       8 (Mask 3F) Private<br />    File OS:          4 Unknown Win32<br />    File type:        2.0 Dll<br />    File date:        00000000.00000000<br />    Translations:     0409.04b0<br />    CompanyName:      Microsoft Corporation<br />    ProductName:      Microsoft&reg; .NET Framework<br />    InternalName:     clr.dll<br />    OriginalFilename: clr.dll<br />    ProductVersion:   4.0.30319.33440<br />    FileVersion:      4.0.30319.33440 built by: FX45W81RTMREL<br />    PrivateBuild:     DDBLD106<br />    FileDescription:  Microsoft .NET Runtime Common Language Runtime - WorkStation<br />    LegalCopyright:   &copy; Microsoft Corporation.  All rights reserved.<br />    Comments:         Flavor=Retail</pre>
<pre id="codeSnippet" class="csharpcode"><strong>0:008<span class="kwrd">&gt;</span> lm v mmscorwks<br /></strong>start             end                 module name<br />00007ffc`72010000 00007ffc`729af000   mscorwks   (deferred)             <br />    Image path: C:\Windows\Microsoft.NET\Framework64\v2.0.50727\mscorwks.dll<br />    Image name: mscorwks.dll<br />    Timestamp:        Wed Aug 14 06:55:49 2013 (520B0DD5)<br />    CheckSum:         0098EB16<br />    ImageSize:        0099F000<br />    File version:     2.0.50727.7905<br />    Product version:  2.0.50727.7905<br />    File flags:       0 (Mask 3F)<br />    File OS:          4 Unknown Win32<br />    File type:        2.0 Dll<br />    File date:        00000000.00000000<br />    Translations:     0409.04b0<br />    CompanyName:      Microsoft Corporation<br />    ProductName:      Microsoft&reg; .NET Framework<br />    InternalName:     mscorwks.dll<br />    OriginalFilename: mscorwks.dll<br />    ProductVersion:   2.0.50727.7905<br />    FileVersion:      2.0.50727.7905 (win9rel.050727-7900)<br />    FileDescription:  Microsoft .NET Runtime Common Language Runtime - WorkStation<br />    LegalCopyright:   &copy; Microsoft Corporation.  All rights reserved.<br />    Comments:         Flavor=Retail</pre>
</div>
<p>SOS is the debugger extension used by native debuggers like WinDbg to debug managed code. Each version of the CLR ships with its own SOS.dll (in the same folder of the CLR dll), and it can be loaded with the .loadby command (for user dumps coming from a different machine,&nbsp; .loadby may not always work, depending on the path of the .Net Framework on the target machine and on the bitness of the target process, see <a href="http://blogs.msdn.com/b/dougste/archive/2009/02/18/failed-to-load-data-access-dll-0x80004005-or-what-is-mscordacwks-dll.aspx">this post</a> for more details):</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.46%; height: 100%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre class="csharpcode"><strong>0:008<span class="kwrd">&gt;</span> .loadby sos clr<br />0:008<span class="kwrd">&gt;</span> .loadby sos mscorwks<br />0:008<span class="kwrd">&gt;</span> .chain<br /></strong>...<br />Extension DLL chain:</pre>
<span style="background-color: #ffff00;"> C:\Windows\Microsoft.NET\Framework64\v2.0.50727\sos: image 2.0.50727.7905, API 1.0.0, built Wed Aug 14 07:06:07 2013<br /> [path: C:\Windows\Microsoft.NET\Framework64\v2.0.50727\sos.dll]<br /> C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos: image 4.0.30319.33440, API 1.0.0, built Tue Aug 06 01:33:29 2013<br /> [path: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos.dll]<br /></span>
<pre id="codeSnippet" class="csharpcode">    dbghelp: image 6.13.0015.1725, API 6.3.6, built Sat Feb 16 04:34:59 2013<br />        [path: C:\dbginternal\dbghelp.dll]<br />    ext: image 6.13.0015.1825, API 1.0.0, built Sat May 04 11:27:44 2013<br />        [path: C:\Users\carcolo\AppData\Local\DBG\ExtLibrary\x64\ext\6.13.15.1825\winext\ext.dll]<br />    exts: image 6.13.0015.1725, API 1.0.0, built Sat Feb 16 04:37:51 2013<br />        [path: C:\dbginternal\WINXP\exts.dll]<br />    uext: image 6.13.0015.1725, API 1.0.0, built Sat Feb 16 04:37:47 2013<br />        [path: C:\dbginternal\winext\uext.dll]<br />    ntsdexts: image 6.3.9321.0, API 1.0.0, built Sat Feb 16 04:37:58 2013<br />        [path: C:\dbginternal\WINXP\ntsdexts.dll]</pre>
</div>
<p>However, once you start issuing commands, something strange happens (note that we are using the full path of the debugger extension, in order to distinguish SOS for CLR2 from SOS for CLR4:</p>
<div style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.46%; height: 100%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre class="csharpcode"><strong>0:008<span class="kwrd">&gt;</span> !C:\Windows\Microsoft.NET\Framework64\v2.0.50727\sos.threads<br /></strong>ThreadCount: 2<br />UnstartedThread: 0<br />BackgroundThread: 1<br />PendingThread: 0<br />DeadThread: 0<br />Hosted Runtime: no<br />                                              PreEmptive                                                Lock<br />       ID OSID        ThreadOBJ     State   GC     GC Alloc Context                  Domain           Count APT Exception<br />   0    1 1d80 000000000118b750      a020 Enabled  00000000030e0160:00000000030e1fd0 0000000001181a80     0 MTA<br />   2    2 3008 0000000001199c80      b220 Enabled  0000000000000000:0000000000000000 0000000001181a80     0 MTA (Finalizer)</pre>
<pre class="csharpcode"><strong>0:008<span class="kwrd">&gt;</span> !C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos.threads<br /></strong>Failed to load data access DLL, 0x80004005<br />Verify that 1) you have a recent build of the debugger (6.2.14 or newer)<br />            2) the file mscordacwks.dll that matches your version of clr.dll is <br />                in the version directory or on the symbol path<br />            3) or, if you are debugging a dump file, verify that the file <br />                mscordacwks_<span class="kwrd">&lt;</span><span class="html">arch</span><span class="kwrd">&gt;</span>_<span class="kwrd">&lt;</span><span class="html">arch</span><span class="kwrd">&gt;</span>_<span class="kwrd">&lt;</span><span class="html">version</span><span class="kwrd">&gt;</span>.dll is on your symbol path.<br />            4) you are debugging on supported cross platform architecture as <br />                the dump file. For example, an ARM dump file must be debugged<br />                on an X86 or an ARM machine; an AMD64 dump file must be<br />                debugged on an AMD64 machine.<br /><br />You can also run the debugger command .cordll to control the debugger's<br />load of mscordacwks.dll.  .cordll -ve -u -l will do a verbose reload.<br />If that succeeds, the SOS command should work on retry.<br /><br />If you are debugging a minidump, you need to make sure that your executable<br />path is pointing to clr.dll as well.</pre>
</div>
<div class="csharpcode-wrapper">In this case, the !threads command works fine for CLR2, but it gives the &ldquo;failed to load data access DLL&rdquo; error for CLR4. A <a href="http://www.bing.com/search?q=mscordacwks">bing search</a> can show more about the data access (DAC) dll, mscordacwks.dll. With multiple CLRs, we need to take into consideration that we also have multiple DAC dlls and, when using the .cordll command as suggested by the error message above, we need to specify for which CLR we are loading the DAC dll. Fortunately, .cordll has a &ldquo;-I&rdquo; option for that. So we need to load the DAC dll for CLR4: </div>
<div style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.46%; height: 100%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre id="codeSnippet" class="csharpcode"><strong>0:008<span class="kwrd">&gt;</span> .cordll<span style="background-color: #ffff00;">-I clr</span> -ve -u -l<br /></strong>Automatically loaded SOS Extension<br />CLRDLL: Loaded DLL C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscordacwks.dll<br />CLR DLL status: Loaded DLL C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscordacwks.dll</pre>
</div>
<p>Good, we loaded the DAC dll for CLR4, so commands work now: </p>
<div style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.46%; height: 100%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre id="codeSnippet" class="csharpcode"><strong>0:008<span class="kwrd">&gt;</span> !C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos.threads<br /></strong>ThreadCount:      2<br />UnstartedThread:  0<br />BackgroundThread: 2<br />PendingThread:    0<br />DeadThread:       0<br />Hosted Runtime:   no<br />                                                                                                        Lock  <br />       ID OSID ThreadOBJ           State GC Mode     GC Alloc Context                  Domain           Count Apt Exception<br />   0    1 1d80 000000000120a360    28220 Preemptive  000000001C6D5308:000000001C6D5FD0 00000000011fd530 0     MTA <br />   7    2 15b0 0000000001219060    2b220 Preemptive  0000000000000000:0000000000000000 00000000011fd530 0     MTA (Finalizer) </pre>
</div>
<p>Note the output of the !threads commands against CLR2 and CLR4: they reflect the different view that each CLR has on the process: thread 0 is known to both CLR2 and CLR4, because this thread has executed code in both. CLR2 also knows thread 2, which is unknown to CLR4. This is because this thread so far has executed CLR2 code only. Conversely, thread 7 has executed CLR4 code only.</p>
<p>Also note that, for thread 0, the thread object is different: 000000000118b750 for CLR2, 000000000120a360 for CLR4. This is because each CLR keeps its own runtime data structures, distinct from each other: therefore each CLR has its own thread object, both referencing the same OS thread. The same applies to other runtime data structures: AppDomains, Types, Method Tables, Method Descriptors, and so on.</p>
<p>If we enter again the !threads command for CLR2, however, we face the &ldquo;unexpected&rdquo;:</p>
<div style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.46%; height: 100%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre><strong>0:008&gt; !C:\Windows\Microsoft.NET\Framework64\v2.0.50727\sos.threads<br /></strong>Failed to request ThreadStore</pre>
</div>
<p>Loading the CLR4 DAC caused unload of the CLR2 DAC, hence the SOS commands directed at CLR2 no longer work. We can reload the CLR2 DAC manually:</p>
<div style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.46%; height: 100%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre><strong>0:008&gt; .cordll -I mscorwks -ve -u -l</strong><br />Automatically loaded SOS Extension<br />CLRDLL: Loaded DLL C:\Windows\Microsoft.NET\Framework64\v2.0.50727\mscordacwks.dll<br />CLR DLL status: Loaded DLL C:\Windows\Microsoft.NET\Framework64\v2.0.50727\mscordacwks.dll</pre>
</div>
<p>This will make the SOS for CLR2 work, but the SOS for CLR4 will stop working.</p>
<p>The reason of this behavior is that <span style="text-decoration: underline;"><em>only one DAC dll can be loaded in the debugger at a given time</em></span>.</p>
<p>You can load the DAC that you need at a given time. For instance, with the CLR4 DAC loaded, the call stack of thread 0 looks like this:</p>
<div style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.46%; height: 100%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre><strong>0:000&gt; kL<br /></strong>Child-SP          RetAddr           Call Site<br />00000000`0109e878 00007ffc`7b3d525e ntdll!ZwDeviceIoControlFile+0xa<br />00000000`0109e880 00007ffc`7b485400 KERNELBASE!ConsoleCallServerGeneric+0xe6<br />00000000`0109e9e0 00007ffc`7b49c318 KERNELBASE!GetConsoleInput+0x38820<br />00000000`0109ea70 00007ffc`722ca7d7 KERNELBASE!ReadConsoleInputA+0x14<br />00000000`0109eab0 00007ffc`7191a727 mscorwks!DoNDirectCall__PatchGetThreadCall+0x7b</pre>
<span style="background-color: #ffff00;">00000000`0109eb50 00007ffc`7197007d mscorlib_ni+0x8da727<br />00000000`0109ec90 00007ffc`7196fee4 mscorlib_ni+0x93007d<br />00000000`0109ed40 00007ffc`12a001c6 mscorlib_ni+0x92fee4<br />00000000`0109ed80 00007ffc`722cafb2 0x00007ffc`12a001c6</span>
<pre><br />00000000`0109ee30 00007ffc`721e0ec3 mscorwks!CallDescrWorker+0x82<br />00000000`0109ee80 00007ffc`726aa131 mscorwks!CallDescrWorkerWithHandler+0xd3<br />00000000`0109ef20 00007ffc`72239643 mscorwks!MethodDesc::CallDescr+0x2b1<br />00000000`0109f160 00007ffc`72103e84 mscorwks!ClassLoader::RunMain+0x22b<br />00000000`0109f3c0 00007ffc`7279693d mscorwks!Assembly::ExecuteMainMethod+0xbc<br />00000000`0109f6b0 00007ffc`720f7a03 mscorwks!SystemDomain::ExecuteMainMethod+0x47d<br />00000000`0109fc80 00007ffc`721143c4 mscorwks!ExecuteEXE+0x47<br />00000000`0109fcd0 00007ffc`729b7ced mscorwks!_CorExeMain+0xac<br />00000000`0109fd30 00007ffc`72a5ea5b mscoreei!_CorExeMain+0xe0<br />00000000`0109fd80 00007ffc`7be81611 MSCOREE!_CorExeMain_Exported+0xcb<br />00000000`0109fdb0 00007ffc`7dd164ad KERNEL32!BaseThreadInitThunk+0xd<br />00000000`0109fde0 00000000`00000000 ntdll!RtlUserThreadStart+0x1d</pre>
</div>
<p>The highlighted frames are not properly resolved into symbolic information because they are relative to CLR2 assemblies (this can be inferred by the fact that the caller is code in mscorwks).</p>
<p>Once we reload the CLR2 DAC, the same command gives a different (better <img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/6710.wlEmoticon-smile_617E3B9F.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/6710.wlEmoticon_2D00_smile_5F00_617E3B9F.png" alt="Smile" />) outcome:</p>
<div style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.46%; height: 100%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre><strong>0:000&gt; kL<br /></strong>Child-SP          RetAddr           Call Site<br />00000000`0109e878 00007ffc`7b3d525e ntdll!ZwDeviceIoControlFile+0xa<br />00000000`0109e880 00007ffc`7b485400 KERNELBASE!ConsoleCallServerGeneric+0xe6<br />00000000`0109e9e0 00007ffc`7b49c318 KERNELBASE!GetConsoleInput+0x38820<br />00000000`0109ea70 00007ffc`722ca7d7 KERNELBASE!ReadConsoleInputA+0x14<br />00000000`0109eab0 00007ffc`7191a727 mscorwks!DoNDirectCall__PatchGetThreadCall+0x7b</pre>
<span style="background-color: #ffff00;">00000000`0109eb50 00007ffc`7197007d mscorlib_ni!DomainNeutralILStubClass.IL_STUB(IntPtr, InputRecord ByRef, Int32, Int32 ByRef)+0xa7<br />00000000`0109ec90 00007ffc`7196fee4 mscorlib_ni!System.Console.ReadKey(Boolean)+0xfd<br />00000000`0109ed40 00007ffc`12a001c6 mscorlib_ni!System.Console.ReadKey()+0x14<br />00000000`0109ed80 00007ffc`722cafb2 ConsoleApplication3!ConsoleApplication3.Program.Main(System.String[])+0xa6<br /></span>
<pre>00000000`0109ee30 00007ffc`721e0ec3 mscorwks!CallDescrWorker+0x82<br />00000000`0109ee80 00007ffc`726aa131 mscorwks!CallDescrWorkerWithHandler+0xd3<br />00000000`0109ef20 00007ffc`72239643 mscorwks!MethodDesc::CallDescr+0x2b1<br />00000000`0109f160 00007ffc`72103e84 mscorwks!ClassLoader::RunMain+0x22b<br />00000000`0109f3c0 00007ffc`7279693d mscorwks!Assembly::ExecuteMainMethod+0xbc<br />00000000`0109f6b0 00007ffc`720f7a03 mscorwks!SystemDomain::ExecuteMainMethod+0x47d<br />00000000`0109fc80 00007ffc`721143c4 mscorwks!ExecuteEXE+0x47<br />00000000`0109fcd0 00007ffc`729b7ced mscorwks!_CorExeMain+0xac<br />00000000`0109fd30 00007ffc`72a5ea5b mscoreei!_CorExeMain+0xe0<br />00000000`0109fd80 00007ffc`7be81611 MSCOREE!_CorExeMain_Exported+0xcb<br />00000000`0109fdb0 00007ffc`7dd164ad KERNEL32!BaseThreadInitThunk+0xd<br />00000000`0109fde0 00000000`00000000 ntdll!RtlUserThreadStart+0x1d</pre>
</div>
<p>The same concept applies to references to managed objects on the stack, to the managed heap and to appdomains: commands like !dso, !dumpheap and !dumpdomain will only show managed references, managed heaps and appdomains of the CLR whose DAC dll is currently loaded in the debugger.</p>
<h4>Exceptions</h4>
<p>All managed exceptions are implemented in terms of SEH, and the SEH exception code for all clr exceptions is 0xe0434f4d, regardless the CLR version. This is good news, because this means that WinDbg knows about all the CLR exceptions, regardless which DAC dll (if any at all) is loaded.</p>
<p>The following command:</p>
<div style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.46%; height: 100%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre><strong>0:000&gt; sxe clr<br /></strong></pre>
</div>
<p>causes WInDbg to break the debugged process whenever a managed exception occurs.</p>
<p>Further investigation of the exception requires to load the right DAC dll. For instance:</p>
<div style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.46%; height: 100%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre><strong>0:000&gt; g<br /></strong>(570.1d80): CLR exception - code e0434f4d (first chance)<br />First chance exceptions are reported before any exception handling.<br />This exception may be expected and handled.<br />KERNELBASE!RaiseException+0x68:<br />00007ffc`7b3d8384 488b8c24c0000000 mov     rcx,qword ptr [rsp+0C0h] ss:00000000`0109eac0=000058c9ee5dddb4</pre>
<pre><strong>0:000&gt; kbL<br /></strong>RetAddr           : Args to Child                                                           : Call Site<br />00007ffc`7220326f : 00000000`0118b750 00000000`0118b750 00000000`0109eb30 00000000`0118b750 : KERNELBASE!RaiseException+0x68<br />00007ffc`72711cf0 : </pre>
<span style="background-color: #00ff00;">00000000`030e18a8</span>
<pre> 00000000`00000000 00000000`00000000 00000000`00000001 : mscorwks!RaiseTheExceptionInternalOnly+0x2ff<br />00007ffc`12a0020b : 00000000`70000001 00007ffc`128b33d8 00000000`00472054 00000000`011c8a20 : mscorwks!JIT_Throw+0x130<br />00007ffc`722cafb2 : 00000000`030dce80 00000000`00000000 00007ffc`128b39b8 00007ffc`721980f9 : 0x00007ffc`12a0020b<br />00007ffc`721e0ec3 : 00000000`00000002 00000000`0000000a 00007ffc`720874f0 00000000`00000000 : mscorwks!CallDescrWorker+0x82<br />00007ffc`726aa131 : 00000000`0109efb8 00000000`00000000 00000000`0109f1c0 00000000`00000008 : mscorwks!CallDescrWorkerWithHandler+0xd3<br />00007ffc`72239643 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`0109f420 : mscorwks!MethodDesc::CallDescr+0x2b1<br />00007ffc`72103e84 : 00000000`00000001 00000000`00000000 00000000`00000030 00000000`00000000 : mscorwks!ClassLoader::RunMain+0x22b<br />00007ffc`7279693d : 00000000`0109fa10 00000000`00000000 00000000`011a6f58 00000000`00000200 : mscorwks!Assembly::ExecuteMainMethod+0xbc<br />00007ffc`720f7a03 : 00000000`00000000 00000000`00000000 00000000`00000000 00007ffc`722623d2 : mscorwks!SystemDomain::ExecuteMainMethod+0x47d<br />00007ffc`721143c4 : ffffffff`fffffffe 00000000`00000000 000049e5`00000000 00000000`00000000 : mscorwks!ExecuteEXE+0x47<br />00007ffc`729b7ced : ffffffff`ffffffff 00000000`0118b750 00000000`00000000 00000000`0109fcd8 : mscorwks!_CorExeMain+0xac<br />00007ffc`72a5ea5b : 00000000`00000000 00007ffc`72114318 00000000`00000000 00000000`00000000 : mscoreei!_CorExeMain+0xe0<br />00007ffc`7be81611 : 00007ffc`729b0000 00000000`00000000 00000000`00000000 00000000`00000000 : MSCOREE!_CorExeMain_Exported+0xcb<br />00007ffc`7dd164ad : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : KERNEL32!BaseThreadInitThunk+0xd<br />00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x1d</pre>
<pre><strong>0:000&gt; !do <span style="background-color: #00ff00;">00000000`030e18a8</span><br /></strong>&lt;Note: this object has an invalid CLASS field&gt;<br />Invalid object</pre>
<pre><strong>0:000&gt; .cordll -I mscorwks -ve -u -l<br /></strong>Automatically loaded SOS Extension<br />CLRDLL: Loaded DLL C:\Windows\Microsoft.NET\Framework64\v2.0.50727\mscordacwks.dll<br />CLR DLL status: Loaded DLL C:\Windows\Microsoft.NET\Framework64\v2.0.50727\mscordacwks.dll</pre>
<pre><strong>0:000&gt; !do <span style="background-color: #00ff00;">00000000`030e18a8</span><br /></strong>Name: System.ApplicationException<br />MethodTable: 00007ffc7147c618<br />EEClass: 00007ffc710804c8<br />Size: 136(0x88) bytes<br /> (C:\WINDOWS\assembly\GAC_64\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)<br />Fields:<br />              MT    Field   Offset                 Type VT     Attr            Value Name<br />00007ffc71477df0  40000b5        8        System.String  0 instance 0000000000000000 _className<br />00007ffc71476198  40000b6       10 ...ection.MethodBase  0 instance 0000000000000000 _exceptionMethod<br />00007ffc71477df0  40000b7       18        System.String  0 instance 0000000000000000 _exceptionMethodString<br />00007ffc71477df0  40000b8       20        System.String  0 instance 00000000030e1870 _message<br />00007ffc7146f410  40000b9       28 ...tions.IDictionary  0 instance 0000000000000000 _data<br />00007ffc714780b8  40000ba       30     System.Exception  0 instance 0000000000000000 _innerException<br />00007ffc71477df0  40000bb       38        System.String  0 instance 0000000000000000 _helpURL<br />00007ffc714776e0  40000bc       40        System.Object  0 instance 0000000000000000 _stackTrace<br />00007ffc71477df0  40000bd       48        System.String  0 instance 0000000000000000 _stackTraceString<br />00007ffc71477df0  40000be       50        System.String  0 instance 0000000000000000 _remoteStackTraceString<br />00007ffc7147f060  40000bf       70         System.Int32  1 instance                0 _remoteStackIndex<br />00007ffc714776e0  40000c0       58        System.Object  0 instance 0000000000000000 _dynamicMethods<br />00007ffc7147f060  40000c1       74         System.Int32  1 instance      -2146232832 _HResult<br />00007ffc71477df0  40000c2       60        System.String  0 instance 0000000000000000 _source<br />00007ffc7147a7f8  40000c3       68        System.IntPtr  1 instance                0 _xptrs<br />00007ffc7147f060  40000c4       78         System.Int32  1 instance       -532459699 _xcode</pre>
</div>
<h3>Summary</h3>
<p>It is possible to debug multiple CLRs, but this can be done &ldquo;one CLR at a time&rdquo; in WinDbg + SOS. If you know about it and you switch among them, this can nonetheless provide for a good debugging experience. It&rsquo;s important, however, to be aware that, at any given time during debugging, you have a partial view of what&rsquo;s going on in the process, relative to one CLR only.</p>
<p>Visual Studio 2012 has the additional limitation of not allowing to switch the debugged CLR within the same debugging session.</p>]]></content:encoded>
    </item>
    <item>
      <title>Loading multiple CLR Runtimes (InProc SxS) – Sample Code</title>
      <link>https://docs.microsoft.com/archive/blogs/carlos/loading-multiple-clr-runtimes-inproc-sxs-sample-code</link>
      <pubDate>Fri, 23 Aug 2013 08:43:00 GMT</pubDate>
      <dc:creator><![CDATA[carcolo]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/carlos/2013/08/23/loading-multiple-clr-runtimes-inproc-sxs-sample-code/</guid>
      <description><![CDATA[Introduction
Starting with version 4, the CLR supports In-Process Side-by-Side (InProc SxS).
The...]]></description>
      <content:encoded><![CDATA[<h1>Introduction</h1>
<p>Starting with version 4, the CLR supports In-Process Side-by-Side (InProc SxS).</p>
<p>The topic is <a href="http://www.bing.com/search?q=clr4+inproc+sxs">extensively treated</a>. In particular, <a href="http://msdn.microsoft.com/en-us/magazine/ee819091.aspx">this blog post</a> does a very good job in explaining why CLR InProc Sxs is useful, and which scenarios it addresses.</p>
<p>However I could not find any sample code that causes multiple CLRs to be loaded into a process. I needed such a scenario in order to figure out how to do debugging with Windbg and Sos when multiple CLRs are loaded into a process.</p>
<p>So, the first step for me was to create a solution that causes multiple runtimes to be loaded into a process. The following step will then be to do managed debugging in such a process. This is the topic of a post to come, however <img class="wlEmoticon wlEmoticon-smile" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/1411.wlEmoticon-smile_3FD478F0.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/1411.wlEmoticon_2D00_smile_5F00_3FD478F0.png" alt="Smile" />. Let&rsquo;s get started and create the solution then.</p>
<p><strong>Note</strong>: there isn&rsquo;t a 1:1 mapping between the .Net Framework version and the CLR version, because different versions of the .Net Framework may use the same version of the CLR. Also, the name of the CLR dll has changed over different versions. All this is summarized in the following table:</p>
<p>&nbsp;</p>
<table style="width: 400px;" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td valign="top" width="163">.<strong>Net Framework Version</strong></td>
<td valign="top" width="118"><strong>CLR Version</strong></td>
<td valign="top" width="117"><strong>CLR DLL</strong></td>
</tr>
<tr>
<td valign="top" width="163">1.0</td>
<td valign="top" width="118">1.0</td>
<td valign="top" width="117">mscorwks, mscorsvr</td>
</tr>
<tr>
<td valign="top" width="163">1.1</td>
<td valign="top" width="118">1.1</td>
<td valign="top" width="117">mscorwks, mscorsvr</td>
</tr>
<tr>
<td valign="top" width="163">2.0</td>
<td valign="top" width="118">2.0</td>
<td valign="top" width="117">mscorwks</td>
</tr>
<tr>
<td valign="top" width="163">3.0</td>
<td valign="top" width="118">2.0</td>
<td valign="top" width="117">&nbsp;</td>
</tr>
<tr>
<td valign="top" width="163">3.5</td>
<td valign="top" width="118">2.0</td>
<td valign="top" width="117">&nbsp;</td>
</tr>
<tr>
<td valign="top" width="163">4.0</td>
<td valign="top" width="118">4.0</td>
<td valign="top" width="117">clr</td>
</tr>
<tr>
<td valign="top" width="163">4.5</td>
<td valign="top" width="118">4.0</td>
<td valign="top" width="148">&nbsp;</td>
</tr>
</tbody>
</table>
<p>and will be useful in the rest of this post. Only the CLR version is relevant for our purposes, so the &ldquo;Target Framework&rdquo; in Visual Studio projects will be just a means to actually set the CLR version. In this respect, multiple options are possible: for instance, .Net Framework 2.0, .Net Framework 3.0 and .Net Framework 3.5 all set the CLR version to 2.0. In the samples, we&rsquo;ll be using the last .Net Framework version that uses a given CLR version (.Net Framework 3.5 for CLR 2.0, .Net Framework 4.5 for CLR 4.0) at the time of this writing.</p>
<h1>Easy approaches (and why they do not work)</h1>
<p>Each assembly can reference one CLR, so obviously it&rsquo;s not possible to load multiple CLRs in one process writing one assembly only,</p>
<p>It is tempting to think, however, that by having different assemblies in one process, <span style="text-decoration: underline;"><em>each referencing a different version of the CLR</em></span>, we end up loading multiple CLRs. Let&rsquo;s try this way then.</p>
<h2>CLR2 referencing CLR4</h2>
<p>Follow these steps:</p>
<ul>
<li>Create a new solution of type &ldquo;Blank Solution&rdquo; in Visual Studio 2012</li>
<li>Add a console application (<strong>ConsoleApplication1</strong>), with Target Framework version 3.5</li>
<li>Add a class library (<strong>ClassLibrary1</strong>), with Target Framework version 4.5</li>
<li>Add a reference to ClassLibrary1 from ConsoleApplication1</li>
<li>Reference a type in ClassLibrary1 from ConsoleApplication1</li>
</ul>
<p>Even before you build this solution, you&rsquo;ll see this icon on the added reference:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/7624.Reference_5F171FC3.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/7624.Reference_5F00_5F171FC3.png"><img style="margin-right: 0px; margin-left: 0px; display: inline;" title="Reference" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/0211.Reference_thumb_2C47194F.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/0211.Reference_5F00_thumb_5F00_2C47194F.png" alt="Reference" width="240" height="171" /></a></p>
<p>Building gives an error that is pretty self-explanatory:</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4;">
<div id="codeSnippet" style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum1" style="color: #606060;"> 1:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum2" style="color: #606060;"> 2:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum3" style="color: #606060;"> 3:</span> 2<span style="color: #0000ff;">&gt;</span>------ Build started: Project: ConsoleApplication1, Configuration: Debug Any CPU ------</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum4" style="color: #606060;"> 4:</span> 2<span style="color: #0000ff;">&gt;</span>C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(1578,5): warning MSB3274: The primary reference "D:\CLR2CLR4\ClassLibrary1\bin\Debug\ClassLibrary1.dll" could not be resolved because it was built against the ".NETFramework,Version=v4.5" framework. This is a higher version than the currently targeted framework ".NETFramework,Version=v3.5".</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum5" style="color: #606060;"> 5:</span> 2<span style="color: #0000ff;">&gt;</span>C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(1578,5): warning MSB3258: The primary reference "D:\CLR2CLR4\ClassLibrary1\bin\Debug\ClassLibrary1.dll" could not be resolved because it has an indirect dependency on the .NET Framework assembly "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" which has a higher version "4.0.0.0" than the version "2.0.0.0" in the current target framework.</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum6" style="color: #606060;"> 6:</span> 2<span style="color: #0000ff;">&gt;</span>D:\SR\CLR2CLR4\ConsoleApplication1\Program.cs(5,7,5,20): error CS0246: The type or namespace name 'ClassLibrary1' could not be found (are you missing a using directive or an assembly reference?)</pre>
<!--CRLF--></div>
</div>
<p>At startup, CLR2 would be loaded, and the reference to an assembly targeting the CLR4 would force that assembly to be run in a previous version of the CLR. This is not supported.</p>
<h2>CLR4 referencing CLR2</h2>
<p>Follow these steps (you can reuse the previous solution)</p>
<ul>
<li>Add a console application (<strong>ConsoleApplication2</strong>), with Target Framework version 4.5</li>
<li>Add a class library (<strong>ClassLibrary2</strong>), with Target Framework version 3.5</li>
<li>Add a reference to ClassLibrary2 from ConsoleApplication2</li>
<li>Reference a type in ClassLibrary2 from ConsoleApplication2. Note that this time the reference is added without any warning</li>
</ul>
<p>&nbsp;</p>
<p>If you run the solution, everything works fine. A closer inspection, however, shows that only CLR4 is loaded into the process (you can attach a debugger to the process, or use Sysinternals&rsquo; Process Explroer, and check that clr.dll is loaded into the process, but mscorwks.dll is not).</p>
<p>These two tests have one thing in common: <span style="text-decoration: underline;"><em>directly referencing types between different versions of the CLR does not cause multiple CLRs to be loaded</em></span>. This is logical, because a direct reference between types implies that they live in the same AppDomain. Having different CLRs loaded, however, means that these CLRs live side-by-side in the same process, separate from each other. This means that every CLR has its own Garbage Collector, JIT Compiler, set of AppDomains, and in general all the supporting structures are separate. The obvious consequence is that two .Net objects referencing each other cannot live in different CLRs.&nbsp;</p>
<h1>A more serious approach (and why it still does not work)</h1>
<p>This <a href="http://blogs.msdn.com/b/dotnet/archive/2010/06/23/in-proc-sxs-and-migration-quick-start.aspx">excellent post</a> has valuable information on how multiple CLRs can be loaded into a process (see the section &ldquo;Our Solution Is Not&hellip;&rdquo;):</p>
<p><span style="background-color: #ffff00;">To take advantage of in-proc SxS, a managed component must be activated by a native host and interact with its environment through a native interop layer such as COM interop and P/Invoke.</span></p>
<p>So we come up with the idea of a managed application targeting a version of the CLR, and a managed assembly, exposed through COM Interoperability, targeting a different version of the CLR. Follow these steps (you can reuse the previous solution):</p>
<ul><!--StartFragment-->
<li>Add a console application (<strong>ConsoleApplication3</strong>), with Target Framework version 3.5</li>
<li>Add a class library (<strong>ClassLibrary3</strong>), with Target Framework version 4.5</li>
<li>In ClassLibrary3, expose a .Net class through COM Interop. This requires using the ComVisible attribute and registering the assembly with COM through RegAsm.</li>
<li>Build ClassLibrary3. Upon successful build, the regasm step creates the Type Library for use with COM Interop</li>
<li>Add a COM Reference in ConsoleApplication3 to the Type Library generated by building ClassLibrary3</li>
</ul>
<p>The last step fails and displays a message box with this content:</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4;">
<div id="codeSnippet" style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum1" style="color: #606060;"> 1:</span> ---------------------------</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum2" style="color: #606060;"> 2:</span> Microsoft Visual Studio</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum3" style="color: #606060;"> 3:</span> ---------------------------</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum4" style="color: #606060;"> 4:</span> A reference to 'ClassLibrary3' could not be added. </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum5" style="color: #606060;"> 5:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum6" style="color: #606060;"> 6:</span> The ActiveX type library 'D:\CLR2CLR4\ClassLibrary3\bin\Debug\bin\Debug\ClassLibrary3.tlb' was exported from a .NET assembly and cannot be added as a reference.</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum7" style="color: #606060;"> 7:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum8" style="color: #606060;"> 8:</span> Add a reference to the .NET assembly instead.</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum9" style="color: #606060;"> 9:</span> ---------------------------</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum10" style="color: #606060;"> 10:</span> OK   </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum11" style="color: #606060;"> 11:</span> ---------------------------</pre>
<!--CRLF--></div>
</div>
<p>Basically, this means that it is not possible to use managed code from managed code through COM Interop.</p>
<h1>The final solution</h1>
<p>Due to the previous limitation, we have to introduce a native intermediary in the chain of calls.</p>
<p>Follow these steps (you can reuse the previous solution):</p>
<ul>
<li>Add an ATL Project (<strong>ATLProject1</strong>) to the solution</li>
<li>Add an ATL Simple Object to ATLProject1. This object just forwards calls to the object in ClassLibrary3 exposed through COM Interop</li>
<li>Build ATLProject1</li>
<li>Add a COM Reference in ConsoleApplication3 to the Type Library generated by building ATLProject1</li>
<!--EndFragment--></ul>
<p>Build and run the solution (startup project: ConsoleApplication3). Everything works fine and, if you look at the dlls loaded into the process (again, you can either attach a debugger or use Project Explorer), you&rsquo;ll see that both mscorwks.dll (CLR2) and clr.dll (CLR4) are loaded into the project.</p>
<p>The final Visual Studio 2012 solution, including 7 projects, is attached to this post. Note that only 3 projects (ConsoleApplication3, ClassLibrary3 and ATLProject1) are needed to have multiple CLRs loaded in a process. The other projects (ConsoleApplication1, ClassLibrary1, ConsoleApplication2, ClassLibrary2) exemplify the non-working approaches.</p>
<p><strong>Note</strong>: You would get the same effect (CLR2 and CLR4 loaded) by reversing the CLR versions in the projects. In other words, if ConsoleApplication3 had Target Framework version 4.5, and ClassLibrary3 had Target Framework version 3.5, the end result would still be to have CLR2 and CLR4 loaded in the process, only in the reverse order (CLR4 first, then CLR2).</p>
<p>In the next post, we&rsquo;ll use this solution to show how managed debugging works with CLR InProc SxS. Stay tuned!</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/10/44/38/37/CLR2CLR4.zip" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-44-38-37/CLR2CLR4.zip">CLR2CLR4.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Workflow Foundation 4: Cancellation</title>
      <link>https://docs.microsoft.com/archive/blogs/carlos/workflow-foundation-4-cancellation</link>
      <pubDate>Wed, 06 Feb 2013 04:13:38 GMT</pubDate>
      <dc:creator><![CDATA[carcolo]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/carlos/2013/02/06/workflow-foundation-4-cancellation/</guid>
      <description><![CDATA[Introduction  I got an interesting question from a customer a few days ago: “Is it possible to...]]></description>
      <content:encoded><![CDATA[<h3>Introduction</h3>  <p>I got an interesting question from a customer a few days ago: “Is it possible to handle cancellation in a CodeActivity?”</p>  <p>The background for this question is the following: an activity can explicitly handle cancellation by overriding its Cancel() method. However, out of the <a href="http://msdn.microsoft.com/en-us/library/dd560893.aspx">4 activity authoring options</a> (Activity, CodeActivity, AsyncCodeActivity and NativeActivity), only AsyncCodeActivity and NativeActivity have the Cancel() virtual method. </p>  <p>Turns out that, in order to properly address the question, a bit of background information is needed. This is what this post is all about. A deep understanding of how cancellation works is useful when writing custom activities. I have seen more than one situation when “unexpected” workflow behavior was due to poor implementation of cancellation for one of its activities.</p>  <p>The post also provides a pattern for proper implementation of cancellation using the declarative (Activity) authoring option.</p>  <h3>How cancellation works</h3>  <p>Cancellation is a request from the parent for graceful, early termination of a child activity. A parent does this by calling NativeActivityContext.CancelChildren() or NativeActivityContext.CancelChild(ActivityInstance). </p>  <p><strong>Note</strong>: this same functionality is available to the host through WorkflowApplication.Cancel() and WorkflowInvoker.CancelAsync(): they request cancellation of the root ActivityInstance.</p>  <p>The workflow runtime does the following when CancelChild()/CancelChildren() are called (you can look at this logic with a .NET Reflection Tool like .Net Reflector or ILSpy, the actual logic is in ActivityExecutor.CancelActivity()):</p>  <ol>   <li>If the child ActivityInstance is in a completed state (Closed, Canceled or Faulted), nothing happens</li>    <li>If the child ActivityInstance is in the Executing state</li>    <ol>     <li>if it does not have <u><em>pending work</em></u> (children in the Executing state, outstanding bookmarks or pending asynchronous operations), the ActivityInstance is transitioned to the Canceled state without executing any work item of that ActivityInstance.</li>      <li>otherwise, a CancelActivityWorkItem for the child ActivityInstance is scheduled for execution.</li>   </ol> </ol>  <p>The important thing to note is that <u><em>only in 2.b above the cancellation of an ActivityInstance implies the execution of a work item on the ActivityInstance itself</em></u>. In cases 1 and 2.a the cancellation does not involve calling any methods on the activity.</p>  <p>Also note that 2.a above can only hold if the child ActivityInstance has been scheduled, but hasn’t executed any work item yet. This is because, as part of the post-processing of work item execution, the WF Runtime transitions the ActivityInstance to a completed state if the ActivityInstance has no pending work. This logic is in ActivityInstance.UpdateState().</p>  <p>Everything else about cancellation stems from the simple rules above, and from the fundamental rule of the WF Runtime: work items for a given WorkflowInstance are executed sequentially.</p>  <h3>What happens next?</h3>  <p>As a former colleague of mine used to say: “When I don’t know, I go and look” :-). Again, a .NET Reflection Tool is our friend here.</p>  <p>The actual function that is called by the execution of CancelActivityWorkItem is InternalCancel(): </p>  <div id="codeSnippetWrapper">   <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">internal</span> <span style="color: rgb(0, 0, 255);">class</span> <strong>CancelActivityWorkItem</strong> : ActivityExecutionWorkItem <br />{<br />    ...<br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">bool</span> <strong>Execute</strong>(ActivityExecutor executor, BookmarkManager bookmarkManager) <br />    { <br />        <span style="color: rgb(0, 0, 255);">try</span> <br />        { <br />            ActivityInstance.Cancel(executor, bookmarkManager); <br />        } <br />        <span style="color: rgb(0, 0, 255);">catch</span> (Exception exception) <br />        { <br />            <span style="color: rgb(0, 0, 255);">if</span> (Fx.IsFatal(exception)) <br />                <span style="color: rgb(0, 0, 255);">throw</span>; <br />            ExceptionToPropagate = exception; <br />        } <br />        <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">true</span>; <br />    }<br />}</pre>

  <br /></div>

<div id="codeSnippetWrapper">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">sealed</span> <span style="color: rgb(0, 0, 255);">class</span> <strong>ActivityInstance</strong> : ActivityInstanceMap.IActivityReferenceWithEnvironment, ActivityInstanceMap.IActivityReference <br />{ <br />    ...<br />    <span style="color: rgb(0, 0, 255);">internal</span> <span style="color: rgb(0, 0, 255);">void</span> <strong>Cancel</strong>(ActivityExecutor executor, BookmarkManager bookmarkManager) <br />    { <br />        Activity.InternalCancel(<span style="color: rgb(0, 0, 255);">this</span>, executor, bookmarkManager); <br />    } <br /> } </pre>
</div>

<p>So how cancellation works for the 4 different activity authoring options actually boils down to how each of them implements the virtual method InternalCancel(). Let’s look at each case.</p>

<h3>Activity</h3>

<p>&#160;</p>

<div id="codeSnippetWrapper">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">abstract</span> <span style="color: rgb(0, 0, 255);">class</span> <strong>Activity</strong><br /> { <br />    ... <br />    <span style="color: rgb(0, 0, 255);">internal</span> <span style="color: rgb(0, 0, 255);">virtual</span> <span style="color: rgb(0, 0, 255);">void</span> <strong>InternalCancel</strong>(ActivityInstance instance, ActivityExecutor executor, BookmarkManager bookmarkManager) <br />    { <br />        NativeActivityContext item = executor.NativeActivityContextPool.Acquire(); <br />        <span style="color: rgb(0, 0, 255);">try</span> <br />        { <br />            item.Initialize(instance, executor, bookmarkManager); <br />            item.Cancel(); <br />        } <br />        <span style="color: rgb(0, 0, 255);">finally</span> <br />        { <br />            item.Dispose(); <br />            executor.NativeActivityContextPool.Release(item); <br />        } <br />    } <br /> }</pre>

  <br />NativeActivityContext.Cancel() propagates the cancellation request to children:</div>

<div>&#160;</div>

<div id="codeSnippetWrapper">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">class</span> <strong>NativeActivityContext</strong> : ActivityContext <br />{ <br />    ... <br />    <span style="color: rgb(0, 0, 255);">internal</span> <span style="color: rgb(0, 0, 255);">void</span> <strong>Cancel</strong>() <br />    { <br />        ThrowIfDisposed(); <br />        CurrentInstance.BaseCancel(<span style="color: rgb(0, 0, 255);">this</span>); <br />    } <br /> }</pre>

  <br /></div>

<div id="codeSnippetWrapper">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">sealed</span> <span style="color: rgb(0, 0, 255);">class</span> <strong>ActivityInstance</strong> : ActivityInstanceMap.IActivityReferenceWithEnvironment, ActivityInstanceMap.IActivityReference <br />{ <br />    ... <br />    <span style="color: rgb(0, 0, 255);">internal</span> <span style="color: rgb(0, 0, 255);">void</span> <strong>BaseCancel</strong>(NativeActivityContext context) <br />    { <br />        performingDefaultCancelation = <span style="color: rgb(0, 0, 255);">true</span>; <br />        CancelChildren(context); <br />    } <br /> }</pre>

  <br />So we can deduce that the behavior of cancellation for Activity is “simply” to propagate cancellation to its children. Since an activity using the Activity authoring option is essentially a composition of other activities and does not provide its own logic, the activity won’t need as well to provide a cancellation logic. This behavior cannot be changed, because InternalCancel() is, as the name says:-), internal, therefore it cannot be overridden by custom activities.</div>

<div>&#160;</div>

<h3>CodeActivity</h3>

<p>&#160;</p>

<div>
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">abstract</span> <span style="color: rgb(0, 0, 255);">class</span> <strong>CodeActivity</strong> : Activity <br />{ <br />    ... <br />    <span style="color: rgb(0, 0, 255);">internal</span> <span style="color: rgb(0, 0, 255);">sealed</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">void</span> <strong>InternalCancel</strong>(ActivityInstance instance, ActivityExecutor executor, BookmarkManager bookmarkManager) <br />    { <br />    } <br />}</pre>
</div>

<div>
  <br />This effectively makes InternalCancel() a no-op, and there is no way to override this behavior. CodeActivity executes in one work item only: inside CodeActivtiy.Execute(CodeActivityContext context) it is not possible to create children or bookmarks (CodeActivityContext does not expose these functionalities) or to create pending async operations. Therefore, in the post-processing of the Execute() work item, the CodeActivity will always transition to a completed state. </div>

<div>The condition 2.b above, that would end up in a cancel work item to be executed on the to-be-cancelled activity, cannot hold for a CodeActivity. That’s why CodeActivity does not define a Cancel() method: even if it existed, it would never be called. This answers the original question.</div>

<div>&#160;</div>

<h3>AsyncCodeActivity</h3>

<p>&#160;</p>

<div id="codeSnippetWrapper">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">abstract</span> <span style="color: rgb(0, 0, 255);">class</span> <strong>AsyncCodeActivity</strong> : Activity, IAsyncCodeActivity <br />{ <br />    ...<br />    <span style="color: rgb(0, 0, 255);">protected</span> <span style="color: rgb(0, 0, 255);">virtual</span> <span style="color: rgb(0, 0, 255);">void</span> <strong>Cancel</strong>(AsyncCodeActivityContext context) <br />    { <br />    } <br /><br />    <span style="color: rgb(0, 0, 255);">internal</span> <span style="color: rgb(0, 0, 255);">sealed</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">void</span> <strong>InternalCancel</strong>(ActivityInstance instance, ActivityExecutor executor, BookmarkManager bookmarkManager) <br />    { <br />        AsyncOperationContext context; <br />        <span style="color: rgb(0, 0, 255);">if</span> (executor.TryGetPendingOperation(instance, <span style="color: rgb(0, 0, 255);">out</span> context)) <br />        { <br />            <span style="color: rgb(0, 0, 255);">using</span> (AsyncCodeActivityContext context2 = <span style="color: rgb(0, 0, 255);">new</span> AsyncCodeActivityContext(context, instance, executor)) <br />            { <br />                context.HasCalledAsyncCodeActivityCancel = <span style="color: rgb(0, 0, 255);">true</span>; <br />                Cancel(context2); <br />            } <br />        } <br />    } <br /> }</pre>
</div>

<p> This means that by default cancellation on an AsyncCodeActivity is a no-op, but the activity author has a chance to implement its own cancel semantics. According to the rules above, Cancel() for an AsyncCodeActivity will be called only if BeginExecute() has already been executed, and EndExecute() has not: in this time interval, there is a pending async operation for the activity. A typical implementation of Cancel() will consist in canceling the asynchronous operation that was issued in BeginExecute(), if it hasn’t completed yet. The WF runtime has no knowledge of this asynchronous operation and how to cancel it, so it cannot implement a meaningful cancellation logic. Therefore, it gives the activity author the option to do it.</p>

<h3>NativeActivity</h3>

<p>&#160;</p>

<div id="codeSnippetWrapper">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">abstract</span> <span style="color: rgb(0, 0, 255);">class</span> <strong>NativeActivity</strong> : Activity, IInstanceUpdatable <br /> { <br />    ... <br />    <span style="color: rgb(0, 0, 255);">protected</span> <span style="color: rgb(0, 0, 255);">virtual</span> <span style="color: rgb(0, 0, 255);">void</span> <strong>Cancel</strong>(NativeActivityContext context) <br />    { <br />        <span style="color: rgb(0, 0, 255);">if</span> (!context.IsCancellationRequested) <br />            <span style="color: rgb(0, 0, 255);">throw</span> FxTrace.Exception.AsError(<span style="color: rgb(0, 0, 255);">new</span> InvalidOperationException(SR.DefaultCancelationRequiresCancelHasBeenRequested)); <br />        context.Cancel(); <br />    } <br /><br />    <span style="color: rgb(0, 0, 255);">internal</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">void</span> <strong>InternalCancel</strong>(ActivityInstance instance, ActivityExecutor executor, BookmarkManager bookmarkManager) <br />    { <br />        NativeActivityContext context = executor.NativeActivityContextPool.Acquire(); <br />        <span style="color: rgb(0, 0, 255);">try</span> <br />        { <br />            context.Initialize(instance, executor, bookmarkManager); <br />            Cancel(context); <br />        } <br />        <span style="color: rgb(0, 0, 255);">finally</span> <br />        { <br />            context.Dispose(); <br />            executor.NativeActivityContextPool.Release(context); <br />        } <br />    } <br /> }<br /></pre>
</div>

<p>The implementation is somewhat similar to that of AsyncCodeActivity, but here Cancel() calls context.Cancel(). Context.Cancel(), as we have seen in the section on Activity above, propagates the cancellation request to children. This is necessary for NativeActivity and not for AsyncCodeActivity, because NativeActivity, unlike AsyncCodeActivity, can have children.</p>

<h3>Summary of Cancellation Behavior</h3>

<p>We can summarize the considerations above with a simple table:</p>

<table cellspacing="0" cellpadding="2" width="526" border="1"><tbody>
    <tr>
      <td valign="top" width="133">&#160;</td>

      <td valign="top" width="133">
        <p align="center"><strong>Cancels Children</strong></p>
      </td>

      <td valign="top" width="258">
        <p align="center"><strong>Can Override</strong></p>
      </td>
    </tr>

    <tr>
      <td valign="top" width="133"><strong>Activity</strong></td>

      <td valign="top" width="133">
        <p align="center"><font face="Symbol"><strong>Ö</strong></font></p>
      </td>

      <td valign="top" width="258">
        <p align="center"><font face="Symbol"><strong>c</strong></font></p>
      </td>
    </tr>

    <tr>
      <td valign="top" width="133"><strong>CodeActivity</strong></td>

      <td valign="top" width="133">
        <p align="center">n/a</p>
      </td>

      <td valign="top" width="258">
        <p align="center"><font face="Symbol"><strong>c</strong></font></p>
      </td>
    </tr>

    <tr>
      <td valign="top" width="133"><strong>AsyncCodeActivity</strong></td>

      <td valign="top" width="133">
        <p align="center">n/a</p>
      </td>

      <td valign="top" width="258">
        <p align="center"><font face="Symbol"><strong>Ö</strong></font></p>
      </td>
    </tr>

    <tr>
      <td valign="top" width="133"><strong>NativeActivity</strong></td>

      <td valign="top" width="133">
        <p align="center"><font face="Symbol"><strong>Ö</strong></font></p>
      </td>

      <td valign="top" width="258">
        <p align="center"><font face="Symbol"><strong>Ö</strong></font></p>
      </td>
    </tr>
  </tbody></table>

<p>&#160;</p>

<h3>Custom Cancellation</h3>

<p>If the default implementation of cancellation for AsyncCodeActivity and NativeActivity does not suit your needs, you can override it. Overriding NativeActivity.Cancel() is called custom cancellation, as opposed to the behavior provided by NativeActivity.Cancel(), which is called default cancellation. Here I am providing some quick considerations on custom cancellation.</p>

<h4>Cancellation of Children</h4>

<p>NativeActivity.Cancel(), as mentioned above, propagates the cancelation request to all the child ActivityInstances. If you override Cancel(), however, <u><em>it is your responsibility to propagate cancellation requests to children</em></u>, if applicable. You can do this selectively, by calling Context.CancelChild(ActivityInstance inst), or in a generalized fashion, by calling Context.CancelChildren(). Cancel() is free not to do cancellation of children, however this prevents the activity itself from transitioning to a completed state. So, in essence, such an implementation of Cancel() would not allow an early completion of the activity.</p>

<h4>Scheduling of Children</h4>

<p>You may have noted that, whenever default cancellation is carried out, as opposed to custom cancellation, the <u><em>performingDefaultCancelation</em></u> field of ActivityInstance is set to true (see the code snippet for ActivityInstance.BaseCancel() above). This setting is used because <u><em>default cancellation prevents scheduling of new child activities</em></u>. Or, better: scheduling an activity for execution when default cancellation is in progress causes NativeActivityContext.ScheduleActivity() to return an ActivityInstance whose state is Canceled. This logic is implemented in NativeActivityContext.InternalScheduleActivity(), called by NativeActivityContext.ScheduleActivity():</p>

<div id="codeSnippetWrapper">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">private</span> ActivityInstance <strong>InternalScheduleActivity</strong>(Activity activity, CompletionBookmark onCompleted, FaultBookmark onFaulted)<br />{<br />    ...<br />    <span style="color: rgb(0, 0, 255);">if</span> (currentInstance.IsPerformingDefaultCancelation)<br />    {<br />        currentInstance.MarkCanceled();<br />        <span style="color: rgb(0, 0, 255);">return</span> ActivityInstance.CreateCanceledInstance(activity);<br />    }<br />    <span style="color: rgb(0, 0, 255);">return</span> executor.ScheduleActivity(activity, currentInstance, onCompleted, onFaulted, <span style="color: rgb(0, 0, 255);">null</span>);<br />}</pre>
</div>

<p>Overriding Cancel() disables this behavior, so you’ll be able to continue scheduling child activities for execution. This is, indeed, one reason why you may want to implement custom cancellation: as part of your cancellation logic, your activity may need to execute child activities. Some OOB activities do exactly that. For instance, the <a href="http://msdn.microsoft.com/en-us/library/system.activities.statements.cancellationscope.aspx">CancellationScope</a> activity schedules the CancellationHandler child activity when its child Body is cancelled. However, if Body were cancelled as the result of default cancellation of its parent, CancellationScope would not be able to schedule CancellationHandler at that point. Therefore, CancellationScope overrides Cancel(). The <a href="http://msdn.microsoft.com/en-us/library/system.activities.statements.compensableactivity.aspx">CompensableActivity</a> OOB activity also uses this technique. Keep in mind that, if your override of Cancel() calls base.Cancel(), default cancellation kicks in and scheduling of children would again be disallowed. For this reason, base.Cancel() should not be called by an override of Cancel(), if the cancellation logic requires execution of child activities.</p>

<h4>Bookmarks</h4>

<p>Other than having running children, the other reason why a NativeActivity may stay in the Executing state is outstanding bookmarks. If your activity is in the Executing state and has outstanding bookmarks when cancellation is requested, Cancel() will be called, per rule 2.b above.</p>

<p>What happens next depends on whether default cancellation or custom cancellation is being used. Let’s experiment with this ourselves. Run the following code:</p>

<div>
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><div id="codeSnippetWrapper"><pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">class</span> Program<br />{<br />    <span style="color: rgb(0, 0, 255);">static</span> <span style="color: rgb(0, 0, 255);">void</span> Main(<span style="color: rgb(0, 0, 255);">string</span>[] args)<br />    {<br />        ManualResetEvent mre = <span style="color: rgb(0, 0, 255);">new</span> ManualResetEvent(<span style="color: rgb(0, 0, 255);">false</span>);<br />        Activity workflow1 = <span style="color: rgb(0, 0, 255);">new</span> MyActivity();<br />        WorkflowApplication wfApp = <span style="color: rgb(0, 0, 255);">new</span> WorkflowApplication(workflow1);<br />        wfApp.Completed = wacea =&gt; { Console.WriteLine(<span style="color: rgb(0, 96, 128);">&quot;Workflow Completed&quot;</span>); mre.Set(); };<br />        wfApp.Run();<br />        <span style="color: rgb(0, 128, 0);">// give root activity a chance to execute its first work item</span><br />        Thread.Sleep(1000);<br />        wfApp.Cancel(TimeSpan.MaxValue);<br />        mre.WaitOne();<br />    }<br />}<br /></pre></div><p><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">class</span> MyActivity : NativeActivity<br />{<br />    Variable&lt;Bookmark&gt; m_Bookmark;<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> MyActivity()<br />    {<br />        m_Bookmark = <span style="color: rgb(0, 0, 255);">new</span> Variable&lt;Bookmark&gt;();<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">protected</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">bool</span> CanInduceIdle<br />    {<br />        get<br />        {<br />            <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">true</span>;<br />        }<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">protected</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">void</span> CacheMetadata(NativeActivityMetadata metadata)<br />    {<br />        metadata.AddImplementationVariable(m_Bookmark);<br />    }<br />        <br />    <span style="color: rgb(0, 0, 255);">protected</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">void</span> Execute(NativeActivityContext context)<br />    {<br />        Console.WriteLine(<span style="color: rgb(0, 96, 128);">&quot;Execute called&quot;</span>);<br />        Bookmark bmk = context.CreateBookmark();<br />        context.SetValue(m_Bookmark, bmk);<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">protected</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">void</span> Cancel(NativeActivityContext context)<br />    {<br />        Console.WriteLine(<span style="color: rgb(0, 96, 128);">&quot;Cancel called&quot;</span>);<br />        <span style="color: rgb(0, 0, 255);">base</span>.Cancel(context);<br />    }<br />}</p></pre>
</div>

<div>You get this output:</div>

<div>&#160;</div>

<div><strong>Execute called 
    <br /> Cancel called 

    <br /> Workflow Completed</strong></div>

<div>
  <br /></div>

<div>The workflow completes after Cancel() is called. This means that the bookmark has been removed somehow. The logic is in ActivityInstance.UpdateState(), called by the post-processing of ActivityExecutionWorkItem:</div>

<div>&#160;</div>

<div id="codeSnippetWrapper">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">internal</span> <span style="color: rgb(0, 0, 255);">abstract</span> <span style="color: rgb(0, 0, 255);">class</span> <strong>ActivityExecutionWorkItem</strong> : WorkItem<br />{<br />    ...<br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">void</span> <strong>PostProcess</strong>(ActivityExecutor executor)<br />    {<br />        <span style="color: rgb(0, 0, 255);">if</span> ((ExceptionToPropagate != <span style="color: rgb(0, 0, 255);">null</span>) &amp;&amp; !skipActivityInstanceAbort)<br />            executor.AbortActivityInstance(ActivityInstance, ExceptionToPropagate);<br />        <span style="color: rgb(0, 0, 255);">else</span> <span style="color: rgb(0, 0, 255);">if</span> (ActivityInstance.UpdateState(executor))<br />        {<br />            Exception exception = executor.CompleteActivityInstance(ActivityInstance);<br />            <span style="color: rgb(0, 0, 255);">if</span> (exception != <span style="color: rgb(0, 0, 255);">null</span>)<br />                ExceptionToPropagate = exception;<br />        }<br />    }<br />}<br /></pre>

  <br /></div>

<div id="codeSnippetWrapper">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">sealed</span> <span style="color: rgb(0, 0, 255);">class</span> <strong>ActivityInstance</strong> : ActivityInstanceMap.IActivityReferenceWithEnvironment, ActivityInstanceMap.IActivityReference<br />{<br />    ...<br />    <span style="color: rgb(0, 0, 255);">internal</span> <span style="color: rgb(0, 0, 255);">bool</span> <strong>UpdateState</strong>(ActivityExecutor executor)<br />    {<br />        ...<br />        <span style="color: rgb(0, 0, 255);">if</span> (performingDefaultCancelation &amp;&amp; OnlyHasOutstandingBookmarks)<br />        {<br />            RemoveAllBookmarks(executor.RawBookmarkScopeManager, executor.RawBookmarkManager);<br />            MarkCanceled();<br />            SetCanceled();<br />            flag = <span style="color: rgb(0, 0, 255);">true</span>;<br />        }<br />        <span style="color: rgb(0, 0, 255);">return</span> flag;<br />    }<br />}<br /></pre>

  <br />Note that the bookmarks are removed only if 2 conditions hold:</div>

<ul>
  <li>default cancellation is used (performingDefaultCancellation is true)</li>

  <li>pending work ONLY consists of outstanding bookmarks</li>
</ul>

<p>Let’s remove one of these conditions by modifying Cancel(), so that the base Cancel() is not called:</p>

<div>
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">protected</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">void</span> Cancel(NativeActivityContext context)<br />{<br />    Console.WriteLine(<span style="color: rgb(0, 96, 128);">&quot;Cancel called&quot;</span>);<br />}<br /></pre>
</div>

<div>
  <br />Run the program again. You get this output:</div>

<div>&#160;</div>

<div><strong>Execute called 
    <br /> Cancel called</strong></div>

<div>&#160;</div>

<div>The workflow does not complete because default cancellation is not used this time, therefore the bookmark is not removed.</div>

<div>&#160;</div>

<div>You may wonder why the check for outstanding bookmarks is done in post-processing of ActivityExecutionWorkItem&#160; and not in the base Cancel(). To answer this question, let’s consider what happens if an activity that is being canceled has BOTH children AND bookmarks. Since there are active children, bookmarks are not removed at this stage (what if a running child later tries to resume one of them?). However, after all children have completed and only bookmarks have remained, we would like to get the same behavior. Therefore, the decision is postponed at work item post-processing, for any activity-related work item (all of them derive from ActivityExecutionWorkItem).</div>

<p>The bottom line, in any case, is that you don’t need to care about outstanding bookmarks, as long as you rely on default cancellation. If you are using custom cancellation, however, <u><em>it is your responsibility to remove outstanding bookmarks</em></u>, otherwise your ActivityInstance, and hence the workflow, will not complete. However, if your activity has custom cancellation, and it has executing children AND outstanding bookmarks, it is not necessarily a good idea to remove all bookmarks in the Cancel() override, because child activities that are still executing may use those bookmarks. If this is the case, a good strategy would be to remove all bookmarks once all children have completed. The parent activity can detect when all children have completed by always scheduling a completion callback every time a child activity is scheduled for execution.</p>

<p>As a side note: the components that resume bookmarks for the activity (typically the host, through WorkflowApplication.ResumeBookmark(), or other activities, through NativeActivityContext.ResumeBookmark()) should be resilient to the possibility that the bookmark is no longer there, because the ActivityInstance owning the bookmark has been canceled in the meantime. The different overrides of ResumeBookmark() return a BookmarkResumptionResult value that tells the caller if the bookmark is no longer present (BookmarkResumptionResult.NotFound).</p>

<h4>Handling the Completion States Canceled and Closed</h4>

<p><u><em>The fact that cancellation has been requested for an ActivityInstance does not imply that the ActivityInstance will complete its execution in the ActivityInstanceState.Canceled state.</em></u> Let’s review the cancellation rules defined above:</p>

<ul>
  <li>if 1. holds: no change is made to the completed state (which will typically be Closed)</li>

  <li>if 2.a holds: the completed state will always be Canceled</li>

  <li>if 2.b holds: the logic is more complex, as we are going to find out now.</li>
</ul>

<p>If 2.b holds, ActivityInstance will transition to the Canceled state if ActivityInstance.MarkCanceled() is called. MarkCanceled() is simple:</p>

<div>
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">sealed</span> <span style="color: rgb(0, 0, 255);">class</span> <strong>ActivityInstance</strong> : ActivityInstanceMap.IActivityReferenceWithEnvironment, ActivityInstanceMap.IActivityReference<br />{<br />    ...<br />    <span style="color: rgb(0, 0, 255);">internal</span> <span style="color: rgb(0, 0, 255);">void</span> <strong>MarkCanceled</strong>()<br />    {<br />        substate = Substate.Canceling;<br />    }<br />}<br /></pre>
</div>

<div>&#160;</div>

<div>Setting the substate to Canceling does not have an immediate effect, but later on, when a work item for the activity completes and its post-processing updates the state, the following happens:</div>

<div>&#160;</div>

<div id="codeSnippetWrapper">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">sealed</span> <span style="color: rgb(0, 0, 255);">class</span> <strong>ActivityInstance</strong> : ActivityInstanceMap.IActivityReferenceWithEnvironment, ActivityInstanceMap.IActivityReference<br />{<br />    ...<br />    <span style="color: rgb(0, 0, 255);">internal</span> <span style="color: rgb(0, 0, 255);">bool</span> <strong>UpdateState</strong>(ActivityExecutor executor)<br />    {<br />        ...<br />        <span style="color: rgb(0, 0, 255);">if</span> (!HasPendingWork)<br />        {<br />            <span style="color: rgb(0, 0, 255);">if</span> (!executor.IsCompletingTransaction(<span style="color: rgb(0, 0, 255);">this</span>))<br />            {<br />                flag = <span style="color: rgb(0, 0, 255);">true</span>;<br />                <span style="color: rgb(0, 0, 255);">if</span> (substate == Substate.Canceling)<br />                {<br />                    SetCanceled();<br />                    <span style="color: rgb(0, 0, 255);">return</span> flag;<br />                }<br />                SetClosed();<br />            }<br />            <span style="color: rgb(0, 0, 255);">return</span> flag;<br />        }<br />        ...<br />    }<br /></pre>

  <br />Therefore, the call to MarkCanceled() determines whether later on, when the ActivityInstance has no more pending work, it will be transitioned to the Canceled state, as opposed to the Closed state. NativeActivityContext.MarkCanceled() and AsyncCodeActivityContext.MarkCanceled() are the public interface to ActivityInstance.MarkCanceled().</div>

<div>Note that when the WF runtime handles a cancellation request for an activity that hasn’t executed yet (rule 2.a above), the same logic takes place: an empty work item is scheduled for execution:</div>

<div>&#160;</div>

<div id="codeSnippetWrapper">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">internal</span> <span style="color: rgb(0, 0, 255);">class</span> <strong>ActivityExecutor</strong> : IEnlistmentNotification<br />{<br />    ...<br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">void</span> <strong>CancelActivity</strong>(ActivityInstance activityInstance)<br />    {<br />        <span style="color: rgb(0, 0, 255);">if</span> ((activityInstance.State == ActivityInstanceState.Executing) &amp;&amp; !activityInstance.IsCancellationRequested)<br />        {<br />            activityInstance.IsCancellationRequested = <span style="color: rgb(0, 0, 255);">true</span>;<br />            <span style="color: rgb(0, 0, 255);">if</span> (activityInstance.HasNotExecuted)<br />                scheduler.PushWork(CreateEmptyWorkItem(activityInstance));<br />            <span style="color: rgb(0, 0, 255);">else</span><br />                scheduler.PushWork(<span style="color: rgb(0, 0, 255);">new</span> CancelActivityWorkItem(activityInstance));<br />            <span style="color: rgb(0, 0, 255);">if</span> (ShouldTrackCancelRequestedRecords)<br />                AddTrackingRecord(<span style="color: rgb(0, 0, 255);">new</span> CancelRequestedRecord(WorkflowInstanceId, activityInstance.Parent, activityInstance));<br />        }<br />    }<br />}</pre>

  <br />The post-processing of the empty work item calls SetCanceled() on the ActivityInstance:</div>

<div>&#160;</div>

<div id="codeSnippetWrapper">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">sealed</span> <span style="color: rgb(0, 0, 255);">class</span> <strong>ActivityInstance</strong> : ActivityInstanceMap.IActivityReferenceWithEnvironment, ActivityInstanceMap.IActivityReference<br />{<br />    ...<br />    <span style="color: rgb(0, 0, 255);">internal</span> <span style="color: rgb(0, 0, 255);">bool</span> <strong>UpdateState</strong>(ActivityExecutor executor)<br />    {<br />        <span style="color: rgb(0, 0, 255);">bool</span> flag = <span style="color: rgb(0, 0, 255);">false</span>;<br />        <span style="color: rgb(0, 0, 255);">if</span> (HasNotExecuted)<br />        {<br />            <span style="color: rgb(0, 0, 255);">if</span> (<span style="color: rgb(0, 0, 255);">this</span>.IsCancellationRequested)<br />            {<br />                <span style="color: rgb(0, 0, 255);">if</span> (<span style="color: rgb(0, 0, 255);">this</span>.HasChildren)<br />                    <span style="color: rgb(0, 0, 255);">foreach</span> (ActivityInstance instance <span style="color: rgb(0, 0, 255);">in</span> <span style="color: rgb(0, 0, 255);">this</span>.GetChildren())<br />                        executor.CancelActivity(instance);<br />                <span style="color: rgb(0, 0, 255);">return</span> flag;<br />            }<br />            SetCanceled();<br />            <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">true</span>;<br />        }<br />    }<br />    ...<br />}</pre>
</div>

<div>&#160;</div>

<div>Why is it important for an ActivityInstance to correctly report its state as Canceled or Closed? The answer is in the implementation of SetCanceled() and SetClosed(), called by UpdateState():</div>

<div>&#160;</div>

<div>
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">sealed</span> <span style="color: rgb(0, 0, 255);">class</span> <strong>ActivityInstance</strong> : ActivityInstanceMap.IActivityReferenceWithEnvironment, ActivityInstanceMap.IActivityReference<br />{<br />    ...<br />    <span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">void</span> <strong>SetClosed</strong>()<br />    {<br />        state = ActivityInstanceState.Closed;<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">void</span> <strong>SetCanceled</strong>()<br />    {<br />        TryCancelParent();<br />        state = ActivityInstanceState.Canceled;<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">void</span> <strong>TryCancelParent</strong>()<br />    {<br />        <span style="color: rgb(0, 0, 255);">if</span> ((parent != <span style="color: rgb(0, 0, 255);">null</span>) &amp;&amp; parent.IsPerformingDefaultCancelation)<br />            parent.MarkCanceled();<br />    }<br />}</pre>
</div>

<div></div>

<div>The difference rests in the call to TryCancelParent() made by SetCanceled(): if the parent is using default cancellation, the parent will be marked as canceled, so it is bound to terminate in the Canceled state. Or, said another way: once an activity marks itself as canceled, cancellation propagates back to the parent chain, as long as the activities in the parent chain use default cancelation.</div>

<div>If your custom activity implements custom cancellation AND the activity has children, <u><em>it is the responsibility of the activity to properly set its completion state</em></u>. As a rule of thumb, you may want to mimic the behavior of default cancellation, and set the parent activity state to Canceled if at least one child completes in the canceled state. The parent activity uses completion callbacks to do that. A sample should (hopefully :-)) clarify the concept. Run this code:</div>

<div>&#160;</div>

<div id="codeSnippetWrapper">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">class</span> Program<br />{<br />    <span style="color: rgb(0, 0, 255);">static</span> <span style="color: rgb(0, 0, 255);">void</span> Main(<span style="color: rgb(0, 0, 255);">string</span>[] args)<br />    {<br />        ManualResetEvent mre = <span style="color: rgb(0, 0, 255);">new</span> ManualResetEvent(<span style="color: rgb(0, 0, 255);">false</span>);<br />        Activity workflow1 = <span style="color: rgb(0, 0, 255);">new</span> MyActivity();<br />        WorkflowApplication wfApp = <span style="color: rgb(0, 0, 255);">new</span> WorkflowApplication(workflow1);<br />        wfApp.Completed = wacea =&gt; { Console.WriteLine(<span style="color: rgb(0, 96, 128);">&quot;Workflow Completed with status &quot;</span> + wacea.CompletionState); mre.Set(); };<br />        wfApp.Run();<br />        <span style="color: rgb(0, 128, 0);">// give root activity a chance to execute its first work item</span><br />        Thread.Sleep(1000);<br />        wfApp.Cancel(TimeSpan.MaxValue);<br />        mre.WaitOne();<br />    }<br />}<br /><br /><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">class</span> MyActivity : NativeActivity<br />{<br />    <span style="color: rgb(0, 0, 255);">private</span> Delay myDelayChild;<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> MyActivity()<br />    {<br />        myDelayChild = <span style="color: rgb(0, 0, 255);">new</span> Delay<br />        {<br />            Duration = <span style="color: rgb(0, 0, 255);">new</span> InArgument&lt;TimeSpan&gt;(TimeSpan.FromSeconds(10))<br />        };<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">protected</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">void</span> CacheMetadata(NativeActivityMetadata metadata)<br />    {<br />        metadata.AddImplementationChild(myDelayChild);<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">protected</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">void</span> Execute(NativeActivityContext context)<br />    {<br />        context.ScheduleActivity(myDelayChild);<br />    }<br />}</pre>

  <br /></div>

<div>You get this output:</div>

<div>&#160;</div>

<div><strong>Workflow Completed with status Canceled</strong></div>

<div>&#160;</div>

<div>The cancellation request from the host goes to the root activity. The root activity uses Default Cancellation, so the request propagates to the child Delay activity, which uses custom cancellation and terminates in the Canceled state (see the implementation of Delay.Cancel()). Since the parent uses Default Cancellation, the cancellation propagates back to it. This is the root activity of the workflow, hence the output.</div>

<div>&#160;</div>

<div>Now let’s modify the root activity to use custom cancellation and propagate the cancellation request to children:</div>

<div>&#160;</div>

<div id="codeSnippetWrapper">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">protected</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">void</span> Cancel(NativeActivityContext context)<br />{<br />    context.CancelChildren();<br />}<br /></pre>

  <br />Run the program and you get this output:</div>

<div>&#160;</div>

<div><strong>Workflow Completed with status Closed</strong></div>

<div>&#160;</div>

<div>The root activity is now using custom cancellation. Therefore, when the child Delay activity completes in the Canceled state, <u><em>there is no attempt to cancel the parent</em></u>.</div>

<div>The parent can still complete in the Canceled state if the child completed in the Canceled state, but it must do so explicitly in the child completion callback.</div>

<div>This requires these changes to the previous code:</div>

<div>&#160;</div>

<div>
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">protected</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">void</span> Execute(NativeActivityContext context)<br />{<br />    context.ScheduleActivity(myDelayChild, onDelayChildCompleted);<br />}<br /><br /><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">void</span> onDelayChildCompleted(NativeActivityContext context, ActivityInstance completedInstance)<br />{<br />    <span style="color: rgb(0, 0, 255);">if</span> (completedInstance.State == ActivityInstanceState.Canceled)<br />        context.MarkCanceled();<br />}<br /></pre>
</div>

<div>Run the program and you get this output:</div>

<div>&#160;</div>

<div><strong>Workflow Completed with status Canceled</strong></div>

<div>
  <br /></div>

<div>The rationale behind this type of implementation would be that, since the logic of a parent activity is defined in terms of the logic of its children, if at least one children cancels (that is, does not complete its work), then the parent activity also did not complete its work, hence it should cancel.</div>

<div>&#160;</div>

<div>You may want to divert from this behavior, however, if a child ending in the Canceled state does not imply that the parent did not complete its work. Among the OOB activities, <a href="http://msdn.microsoft.com/en-us/library/system.activities.statements.parallel.aspx">Parallel</a> is one such example. Parallel has a CompletionCondition child expression of Boolean type. If CompletionCondition evaluates to true when a child completes, the other branches (child activities) are canceled, but the parallel activity has completed its work and should transition to the Closed state. Therefore, in the completion callback for the CompletionCondition expression, cancellation is requested for outstanding children, but the hasCompleted flag is also set (once again, use a .Net Reflection Tool to look at the code):</div>

<div>&#160;</div>

<div id="codeSnippetWrapper">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">void</span> OnConditionComplete(NativeActivityContext context, ActivityInstance completedInstance, <span style="color: rgb(0, 0, 255);">bool</span> result)<br />{<br />    <span style="color: rgb(0, 0, 255);">if</span> (result)<br />    {<br />        context.CancelChildren();<br />        hasCompleted.Set(context, <span style="color: rgb(0, 0, 255);">true</span>);<br />    }<br />}<br /></pre>

  <br /></div>

<div>When the completion callback is called for the canceled branches, MarkCanceled() is NOT called if hasCompleted is true:</div>

<div>&#160;</div>

<div id="codeSnippetWrapper">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">void</span> OnBranchComplete(NativeActivityContext context, ActivityInstance completedInstance)<br />{<br />    <span style="color: rgb(0, 0, 255);">if</span> ((CompletionCondition != <span style="color: rgb(0, 0, 255);">null</span>) &amp;&amp; !hasCompleted.Get(context))<br />    {<br />        <span style="color: rgb(0, 0, 255);">if</span> ((completedInstance.State != ActivityInstanceState.Closed) &amp;&amp; context.IsCancellationRequested)<br />        {<br />            context.MarkCanceled();<br />            hasCompleted.Set(context, <span style="color: rgb(0, 0, 255);">true</span>);<br />        }<br />        <span style="color: rgb(0, 0, 255);">else</span><br />        {<br />            <span style="color: rgb(0, 0, 255);">if</span> (onConditionComplete == <span style="color: rgb(0, 0, 255);">null</span>)<br />                onConditionComplete = <span style="color: rgb(0, 0, 255);">new</span> CompletionCallback&lt;<span style="color: rgb(0, 0, 255);">bool</span>&gt;(OnConditionComplete);<br />            context.ScheduleActivity&lt;<span style="color: rgb(0, 0, 255);">bool</span>&gt;(CompletionCondition, onConditionComplete, <span style="color: rgb(0, 0, 255);">null</span>);<br />        }<br />    }<br />}<br /></pre>

  <br />This causes Parallel to complete in the Closed state, not the Canceled state. You may want to follow a similar pattern in your custom activity.</div>

<div>&#160;</div>

<h4>Custom Cancellation Summary</h4>

<p>If you are implementing custom cancellation, there are 3 quick takeaways:</p>

<ul>
  <li>It is your responsibility to propagate the cancellation request to running children</li>

  <li>It is your responsibility to remove outstanding bookmarks</li>

  <li>It is your responsibility to correctly set the completion state of the ActivityInstance: Closed if the ActivityInstance successfully completed its work after receiving a cancel request, Canceled otherwise.</li>
</ul>

<p>&#160;</p>

<h3>Cancellation with the Activity authoring option: CancellationScope</h3>

<div>In the previous topic we have covered custom cancellation. Custom cancellation applies when you are writing a custom activity. While there are good reasons to write custom activities, the majority of workflow-related programming takes place using the declarative (Activity) authoring option, so let’s consider the options you have in this case, when it comes to cancelation.</div>

<div>Let’s recall from the table above that activities using the Activity authoring option cannot override cancellation, so they always use default cancellation. Let’s also recall that, with default cancellation, a child completing in the Canceled state causes the parent to also complete in the Canceled state.</div>

<div>This allows for the implementation of a cancellation pattern for Activity that involves the use of CancellationScope. Let’s assume you want to implement the following logic:</div>

<div>&#160;</div>

<ul>
  <li>Do some work (possibly split into several parts)</li>

  <li>If an <strong>external</strong> condition holds that prevents the work from completing, send a notification about unsuccessful completion</li>
</ul>

<p>Using the declarative authoring option, you may create a sequence of 2 other activities:</p>

<div id="codeSnippetWrapper">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">Sequence<br />    GatherSomeData<br />    ProcessTheData<br /></pre>

  <br />GatherSomeData and ProcessTheData, together, implement the “Do some work” logic, split into two parts. Both activities implement custom cancellation and mark themselves as cancelled (MarkCanceled()) if they receive a cancellation request (which will typically come from the host, in the form of a call to WorkflowApplication,Cancel()).</div>

<p>If cancellation arrives from the host while either GatherSomeData or ProcessTheData are executing, the activities complete in the Canceled state, which causes Sequence to be canceled as well. Otherwise, if both GatherSomeData and ProcessTheData complete in the Closed state, Sequence also completes in the Closed state.</p>

<p>This gives way for wrapping Sequence in a CancellationScope activity:</p>

<div id="codeSnippetWrapper">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">CancellationScope<br />    Body = Sequence<br />        GatherSomeData<br />        ProcessTheData<br />    CancellationHandler = SendCandelDataProcessingEmail<br /></pre>

  <br /></div>

<div>This way, CancellationScope allows to implement cancellation logic in the declarative authoring option. Note that CancellationScope has some tricks up its sleeve to make this work. For instance, you may wonder what happens if a cancellation request comes in while CancellationHandler is executing. In order to implement the intended semantics, CancellationScope would need to disable the propagation of the cancellation request to its child CancellationHandler, because cancellation is already in progress and CancellationHandler must be run to completion in order to obtain the intended semantics. CancellationScope does this by setting a flag once the Body completes, so that cancellation requests received afterwards are not propagated to children:</div>

<div>&#160;</div>

<div id="codeSnippetWrapper">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><p><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">sealed</span> <span style="color: rgb(0, 0, 255);">class</span> <strong>CancellationScope</strong> : NativeActivity<br />{<br />    ...<br />    <span style="color: rgb(0, 0, 255);">protected</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">void</span> <strong>Cancel</strong>(NativeActivityContext context)<br />    {<br />        <span style="color: rgb(0, 0, 255);">if</span> (!suppressCancel.Get(context))<br />            context.CancelChildren();<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">void</span> <strong>OnBodyComplete</strong>(NativeActivityContext context, ActivityInstance completedInstance)<br />    {<br />        <span style="color: rgb(0, 0, 255);">if</span> ((completedInstance.State == ActivityInstanceState.Canceled) || </p><p>               (context.IsCancellationRequested &amp;&amp; (completedInstance.State == ActivityInstanceState.Faulted)))<br />        {<br />            suppressCancel.Set(context, <span style="color: rgb(0, 0, 255);">true</span>);<br />            context.MarkCanceled();<br />            <span style="color: rgb(0, 0, 255);">if</span> (CancellationHandler != <span style="color: rgb(0, 0, 255);">null</span>)<br />                context.ScheduleActivity(CancellationHandler, <span style="color: rgb(0, 0, 255);">new</span> FaultCallback(OnExceptionFromCancelHandler));<br />        }<br />    }<br />}<br /></p></pre>
</div>]]></content:encoded>
    </item>
    <item>
      <title>Workflow Foundation Sql Scripts</title>
      <link>https://docs.microsoft.com/archive/blogs/carlos/workflow-foundation-sql-scripts</link>
      <pubDate>Thu, 10 Jan 2013 10:01:49 GMT</pubDate>
      <dc:creator><![CDATA[carcolo]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/carlos/2013/01/10/workflow-foundation-sql-scripts/</guid>
      <description><![CDATA[If you install the .Net Framework 4.5 and you look at the folder...]]></description>
      <content:encoded><![CDATA[<p>If you install the .Net Framework 4.5 and you look at the folder %systemroot%\Microsoft.NET\Framework\v4.0.30319\SQL\en, or %systemroot%\Microsoft.NET\Framework64\v4.0.30319\SQL\en, you’ll find a number of Sql Script files:</p>  <p><img title="SqlScripts" style="display: inline;" border="0" alt="SqlScripts" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/2474.SqlScripts_100F1458.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/2474.SqlScripts_5F00_100F1458.png" width="779" height="544" /> </p>  <p>These scripts are all related to Workflow Foundation, and in this post I try to clarify what each script is used for.</p>  <p>Scripts usually come in pair, with a XxxSchema.sql file matched by a XxxLogic.sql file. The XxxSchema.sql file creates tables and views, the XxxLogic.sql file creates stored procedures, functions, triggers etc. The pairs are always meant to be executed in this order: XxxSchema.sql first, then XxxLogic.sql. Scripts in a pair should be run in the same database. </p>  <h1><strong>SqlPersistenceService_Schema.sql</strong> and <strong>SqlPersistenceService_Logic.sql</strong></h1>  <p>These scripts are used for WF3 persistence. You may wonder why these scripts, that refer to WF3, are in the folder of the .Net Framework 4.x. This is because WF3 is also in .Net 4.x, as I pointed out in my <a href="http://blogs.msdn.com/b/carlos/archive/2009/08/27/workflow-foundation-migration-from-wf3-to-wf4-notes-and-references.aspx">previous post</a>. If you are using WF3 in .Net 4, use these scripts to create the workflow persistence DB.</p>  <p>The DB schema for WF3 is relatively simple, with only 2 tables: dbo.InstanceState and dbo.CompletedScope. dbo.InstanceState hosts the actual persisted workflow instances, dbo.CompletedScope is used only in advanced scenarios (compensation).</p>  <h1>Tracking_Schema.sql and Tracking_Logic.sql</h1>  <p>WF3 ships with a tracking service, System.Workflow.Runtime.Tracking.SqlTrackingService, that writes information to a Sql Server database. You create such a database by running Tracking_Schema.sql and Tracking_Logic.sql. You need the tracking database only if you are using SqlTrackingService. It is possible, though not mandatory, to use the same database for persistence and tracking. In other words, you can run SqlPersistenceService_Schema.sql SqlPersistenceService_Logic.sql, Tracking_Schema.sql and Tracking_Logic.sql in the same database.</p>  <p>WF4 has a different tracking architecture. Also, it ships a tracking participant, EtwTrackingParticipant, that tracks information to .etl files, not to Sql Server. Consequently, there is no equivalent of Tracking_Schema.sql and Tracking_Logic.sql in WF4.</p>  <h1>SqlPersistenceProviderSchema.sql and SqlPersistenceProviderLogic.sql</h1>  <p>WF in the .Net Framework 3.5 (WF3.5) adds support for <a href="http://msdn.microsoft.com/en-us/library/vstudio/bb412197(v=vs.90).aspx">Workflow Durable Services</a>, and this requires an update to both the schema and the logic of the database. SqlPersistenceProviderSchema.sql and SqlPersistenceProviderLogic.sql update the persistence database accordingly. Note that these scripts should be executed in an existing WF3 persistence database, that is a database where SqlPersistenceService_Schema.sql and SqlPersistenceService_Logic.sql have already been run.</p>  <p>SqlPersistenceProviderSchema.sql adds the dbo.InstanceData table. SqlPersistenceProviderLogic.sql adds the dbo.DeleteInstance, dbo.InsertInstance, dbo.LoadInstance, dbo.UnlockInstance and dbo.UpdateInstance stored procedures.</p>  <h1>SqlWorkflowInstanceStoreSchema.sql and SqlWorkflowInstanceStoreLogic.sql</h1>  <p>WF4 introduces a completely new object model, and with it comes a different schema of the persistence database. SqlWorkflowInstanceStoreSchema.sql and SqlWorkflowInstanceStoreLogic.sql create a database suitable for persisting WF4 workflows. The script files are named after the class in WF4 that implements workflow persistence in SqlServer:,System.Activities.DurableInstancing.SqlWorkflowInstanceStore, The structure of the WF4 persistence database is more complex than the structure of the WF3 database. SqlWorkflowInstanceStoreSchema.sql creates a number of tables and views:</p>  <p><img title="WF40Persistence_Schema" style="display: inline;" border="0" alt="WF40Persistence_Schema" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/1212.WF40Persistence_Schema_3701D5ED.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/1212.WF40Persistence_5F00_Schema_5F00_3701D5ED.png" width="573" height="628" /> </p>  <p></p>  <p>SqlWorkflowInstanceStoreLogic.sql adds stored procedures and functions:</p>  <p><img title="WF40Persistence_Logic" style="display: inline;" border="0" alt="WF40Persistence_Logic" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/1616.WF40Persistence_Logic_3CDF0A37.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/1616.WF40Persistence_5F00_Logic_5F00_3CDF0A37.png" width="577" height="698" /> </p>  <p>&#160; </p>  <h1>SqlWorkflowInstanceStoreSchemaUpgrade.sql</h1>  <p>WF4.5 introduces <a href="http://msdn.microsoft.com/en-us/library/hh314054.aspx">versioning</a>. SqlWorkflowInstanceStoreSchemaUpgrade.sql updates the database created by SqlWorkflowInstanceStoreSchema.sql and SqlWorkflowInstanceStoreLogic.sql to accommodate for versioning information. The step-by-step procedure is documented <a href="http://msdn.microsoft.com/en-us/library/hh314054.aspx#UpdatingWF4PersistenceDatabases">here</a>.</p>  <p>Note that you can save and reload WF4.5 workflows in WF4 databases (that is, databases created with SqlWorkflowInstanceStoreSchema.sql and SqlWorkflowInstanceStoreLogic.sql, but without SqlWorkflowInstanceStoreSchemaUpgrade.sql), as long as you do not associate versioning information to them.</p>  <p>The upgrade of the database consists of these main steps:</p>  <ul>   <li>New tables are created to handle versioning: DefinitionIdentityTable and IdentityOwnerTable</li>    <li>Existing tables are altered with additional columns: InstancesTable.SurrogateIdentityId, RunnableInstancesTable.SurrogateIdentityId, LockOwnersTable.WorkflowIdentityFilter,</li>    <li>Values are inserted in new tables and in new columns of existing tables, to represent standard versioning information for the workflow instances persisted in the database</li>    <li>New views and stored procedures are created.</li> </ul>  <p>After executing the script, you’ll see the new tables:</p>  <p><img title="WF45Persistence_Schema" style="display: inline;" border="0" alt="WF45Persistence_Schema" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/05/50/metablogapi/8168.WF45Persistence_Schema_0B7847F7.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-05-50-metablogapi/8168.WF45Persistence_5F00_Schema_5F00_0B7847F7.png" width="577" height="623" /> </p>  <p>The set of stored procedures and functions is the same of the WF4 version.</p>  <h1>DropXxx.sql</h1>  <p>The DropXxx.sql scripts drop tables and other artifacts. They are useful when a database hosts something else, in addition to persistence or tracking information. In that case, deleting the entire database would cause loss of data.</p>  <h1>The versions of SqlWorkflowInstanceStoreXxx.sql</h1>  <p>There is one further consideration that applies to SqlWorkflowInstanceStoreSchema.sql and SqlWorkflowInstanceStoreLogic.sql: if you compare these scripts on a machine with the .Net Framework 4.0, and on a machine with the .Net Framework 4.5 installed, you’ll find that they are different. This is because <u><em>the .Net Framework 4.5 ships with versions of these files that directly create a WF4.5 database</em></u>. For instance, SqlWorkflowInstanceStoreSchema.sql in the 4.5 version of the .Net Framework creates the&#160; DefinitionIdentityTable, whereas the SqlWorkflowInstanceStoreSchema.sql in the 4.0 version of the .Net Framework does not.</p>  <p>Why is that? Well, if you installed the 4.5 version of the framework and subsequently create a WF Persistence Database, it makes sense to create it with a structure that is suitable for WF4.5 workflows. Note that SqlWorkflowInstanceStoreSchemaUpgrade.sql still has its own place: if you have an existing WF4 persistence database, you should run SqlWorkflowInstanceStoreSchemaUpgrade.sql against it, instead of running the 4.5 version of SqlWorkflowInstanceStoreSchema.sql and SqlWorkflowInstanceStoreLogic.sql: this way, you would preserve the workflow instances currently persisted in the database.</p>  <h1>Which scripts to use?</h1>  <p>Here is a quick summary of which scripts you need, depending on the version of WF that you are using:</p>  <p>&#160;&#160;&#160; <table cellspacing="0" cellpadding="2" width="595" border="1"><tbody>       <tr>         <td valign="top" width="271">&#160;</td>          <td valign="top" width="87">           <p align="center"><strong>WF3</strong></p>         </td>          <td valign="top" width="83">           <p align="center"><strong>WF3.5</strong></p>         </td>          <td valign="top" width="72">           <p align="center"><strong>WF4</strong></p>         </td>          <td valign="top" width="80">           <p align="center"><strong>WF4.5</strong></p>         </td>       </tr>        <tr>         <td valign="top" width="274"><strong>SqlPersistenceService_Schema.sql              <br />SqlPersistenceService_Logic.sql               <br /></strong></td>          <td valign="top" width="87">           <p align="center">X</p>         </td>          <td valign="top" width="83">           <p align="center">X</p>         </td>          <td valign="top" width="72">&#160;</td>          <td valign="top" width="80">&#160;</td>       </tr>        <tr>         <td valign="top" width="275"><strong>SqlPersistenceProviderSchema.sql              <br />SqlPersistenceProviderLogic.sql               <br /></strong></td>          <td valign="top" width="87">&#160;</td>          <td valign="top" width="83">           <p align="center">X</p>         </td>          <td valign="top" width="72">&#160;</td>          <td valign="top" width="80">&#160;</td>       </tr>        <tr>         <td valign="top" width="275"><strong>Tracking_Schema.sql              <br />Tracking_Logic.sql               <br /></strong></td>          <td valign="top" width="87">           <p align="center">X</p>         </td>          <td valign="top" width="83">           <p align="center">X</p>         </td>          <td valign="top" width="72">&#160;</td>          <td valign="top" width="80">&#160;</td>       </tr>        <tr>         <td valign="top" width="275"><strong>SqlWorkflowInstanceStoreSchema.sql              <br />SqlWorkflowInstanceStoreLogic.sql</strong></td>          <td valign="top" width="87">&#160;</td>          <td valign="top" width="83">&#160;</td>          <td valign="top" width="72">           <p align="center">X</p>         </td>          <td valign="top" width="80">           <p align="center">X</p>         </td>       </tr>        <tr>         <td valign="top" width="275"><strong>SqlWorkflowInstanceStoreSchemaUpgrade.sql</strong></td>          <td valign="top" width="87">&#160;</td>          <td valign="top" width="90">&#160;</td>          <td valign="top" width="85">&#160;</td>          <td valign="top" width="98">           <p align="center">X</p>         </td>       </tr>     </tbody></table> </p>  <p></p>  <p>Scripts that are used by WF3 are also found in previous versions of the framework. So it should not come as a surprise to you that, under the folder %systemroot%\Microsoft.NET\Framework\v3.0\Windows Workflow Foundation\SQL\en, you find 4 script files: SqlPersistenceService_Schema.sql, SqlPersistenceService_Logic.sql, Tracking_Schema.sql and Tracking_Logic.sql. Likewise, you’ll find SqlPersistenceProviderSchema.sql and SqlPersistenceProviderLogic.sql in the %systemroot%\Microsoft.NET\Framework\v3.5\SQL\EN folder. And. since WF3 that ships with the .Net Framework 4.x is the same that ships with .Net Framework 3.x, the script files with the same name on different folders are identical, save for references to assemblies: Tracking_Schema.sql in %systemroot%\Microsoft.NET\Framework\v3.0\Windows Workflow Foundation\SQL\en references mscorlib version 2.0.0.0 and System.Workflow.ComponentModel version 3.0.0.0, whereas Tracking_Schema.sql in %systemroot%\Microsoft.NET\Framework64\v4.0.30319\SQL\en references mscorlib version 4.0.0.0 and System.Workflow.ComponentModel version 4.0.0.0.</p>]]></content:encoded>
    </item>
    <item>
      <title>The “MSXML Interfaces appearing in my TLB” issue and related topics</title>
      <link>https://docs.microsoft.com/archive/blogs/carlos/the-msxml-interfaces-appearing-in-my-tlb-issue-and-related-topics</link>
      <pubDate>Tue, 06 Apr 2010 06:52:00 GMT</pubDate>
      <dc:creator><![CDATA[carcolo]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/carlos/2010/04/06/the-msxml-interfaces-appearing-in-my-tlb-issue-and-related-topics/</guid>
      <description><![CDATA[Hi all! I have been involved recently in the troubleshooting of a type library-related problem...]]></description>
      <content:encoded><![CDATA[<p>Hi all! I have been involved recently in the troubleshooting of a type library-related problem reported by a customer. Since the problem is general enough, I am sharing the basic principles in this post. The topic deals with the way type libraries reference external types, as well as the implications on type library generation and registration.</p>  <h4>The Problem</h4>  <p>Assume you have a COM interface of your own, defined in an .IDL file, which accepts method arguments of type IXMLDOMXxx. For example, let’s say your interface has a method that looks like this:</p>  <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 96.57%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; height: 54px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">   <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 96.88%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; height: 18px; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">[<font color="#0000ff">id</font>(1), <font color="#0000ff">helpstring</font>(<span style="color: #006080">&quot;method Load&quot;</span>)] HRESULT Load([<span style="color: #0000ff">in</span>] IXMLDOMNode* pXDN);</pre>

  <br /></div>

<p>For your IDL to be compiled successfully by the MIDL compiler, the reference to IXMLDOMNode needs to be resolved. This happens automatically if you use the default import statements that are generated for a new IDL file in Visual Studio:</p>

<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; height: 65px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"><font color="#0000ff">import</font> <span style="color: #006080">&quot;oaidl.idl&quot;</span>; 

  <br /><font color="#0000ff">import</font> <span style="color: #006080">&quot;ocidl.idl&quot;</span>;</div>

<p>So your .IDL file compiles successfully and everything seems to be OK.</p>

<p>Now let’s use OLEVIEW, a utility program that ships with Visual Studio and the Platform SDK, to look at the generated type library (.TLB file). If you open the type library, you’ll see that IXMLDOMNode, along with many other IXMLDOMXxx interfaces, are included in the generated .TLB file:</p>

<p>&#160;</p>
<img style="border-right-width: 0px; margin: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/carlos/WindowsLiveWriter/6fec3d82487e_F12B/image_9.png" original-url="http://blogs.msdn.com/blogfiles/carlos/WindowsLiveWriter/6fec3d82487e_F12B/image_9.png" width="773" height="565" /> 

<p>&#160;</p>

<p>This problem is more common than one may initially think, as shown by the many posts like this one out on the net:</p>

<p><a title="http://www.eggheadcafe.com/software/aspnet/30162765/msxml-interfaces-appearin.aspx" href="http://www.eggheadcafe.com/software/aspnet/30162765/msxml-interfaces-appearin.aspx">http://www.eggheadcafe.com/software/aspnet/30162765/msxml-interfaces-appearin.aspx</a></p>

<p>We will be using Visual Studio 2008 and the Platform SDK version 6.0A. I would expect, but I cannot guarantee, that the following analysis is not version-dependent.</p>

<h4>Type Library Registration</h4>

<p>You may wonder at this stage: why is it so relevant to reference IXMLDOMNode from the generated TLB, instead of embedding it?</p>

<p>The main reason is that, when the TLB is registered, the interface-related registry keys under HKCR\Interface are changed, so as to associate IXMLDOMNode with your own type library.</p>

<h5><strong><em>Note</em></strong></h5>

<p><em>As an aside, note that the registration of a type library can happen in different ways. The API </em><a href="http://msdn.microsoft.com/en-us/library/ms221570.aspx" target="_blank"><em>RegisterTypeLib</em></a><em> does the registration, but most often a type library is registered as part of a COM dll registration through regsvr32.exe, or by calling its <a href="http://msdn.microsoft.com/en-us/library/ms682162(VS.85).aspx" target="_blank">DllRegisterServer</a> exported function. Yet another way to register a type library is by calling regsvcs or regasm on a .NET Assembly which has <a href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.comvisibleattribute.aspx" target="_blank">COMVisible</a> types. In all these cases, the type library can be in a .TLB file or embedded as a resource in a .DLL.</em></p>

<p>&#160;</p>

<p>Back to the point: the registration of the type library modifies keys under HKCR\Interface, we said. In the case above, if we look at the registry key {2933BF80-7B36-11d2-B20E-00C04F983E60}, the Interface ID (IID) of IXMLDOMNode, before we register our type library:</p>&#160;&#160; <img style="border-right-width: 0px; margin: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="PermsBefore" border="0" alt="PermsBefore" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/carlos/WindowsLiveWriter/6fec3d82487e_F12B/PermsBefore_3.jpg" original-url="http://blogs.msdn.com/blogfiles/carlos/WindowsLiveWriter/6fec3d82487e_F12B/PermsBefore_3.jpg" width="911" height="193" /> 

<p>and after:</p>&#160;&#160; <a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/carlos/WindowsLiveWriter/6fec3d82487e_F12B/PermsAfter_2.jpg" original-url="http://blogs.msdn.com/blogfiles/carlos/WindowsLiveWriter/6fec3d82487e_F12B/PermsAfter_2.jpg"><img style="border-right-width: 0px; margin: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="PermsAfter" border="0" alt="PermsAfter" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/carlos/WindowsLiveWriter/6fec3d82487e_F12B/PermsAfter_thumb.jpg" original-url="http://blogs.msdn.com/blogfiles/carlos/WindowsLiveWriter/6fec3d82487e_F12B/PermsAfter_thumb.jpg" width="910" height="195" /></a> 

<p>we understand what the difference is. Note that F31AF329-0FE0-4640-80F8-40D187FF4D8B is the Library ID (LibID) of the generated type library.</p>

<p>The fact that now the XML interfaces are associated with your type library instead of the standard type library included in msxml6.dll is not going to create trouble, initially. What happens, however, if you remove your type library, typically as part of uninstalling a program? The reference, in the registry, to your type library won’t be resolved and runtime errors will occur.</p>

<h4>Changes in Vista and later OSes</h4>

<p>Actually, when speaking about registering a type library, the outcome is different depending on the operating system and the way registration occurs. Let’s go deep into this as it provides an interesting view on some nifty details.</p>

<p>In operating systems up to, and including, Windows 2003, the registry key HKCR\Interface has the permission “Full Control” for the Administrators group:</p>
<img style="border-right-width: 0px; margin: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="PermsAfter" border="0" alt="PermsAfter" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/carlos/WindowsLiveWriter/6fec3d82487e_F12B/PermsAfter_5.jpg" original-url="http://blogs.msdn.com/blogfiles/carlos/WindowsLiveWriter/6fec3d82487e_F12B/PermsAfter_5.jpg" width="371" height="447" /> 

<p>Also, the “Full Control” permission is inherited by subkeys, so any user in the local Administrators group can do the registration and successfully update the keys.</p>

<p>From Vista, Administrators have “Read” permission on the registry keys representing LibIDs, and only TrustedInstaller has “Full Control” permission by default:</p>
<img style="border-right-width: 0px; margin: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="PermsVista" border="0" alt="PermsVista" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/carlos/WindowsLiveWriter/6fec3d82487e_F12B/PermsVista_3.jpg" original-url="http://blogs.msdn.com/blogfiles/carlos/WindowsLiveWriter/6fec3d82487e_F12B/PermsVista_3.jpg" width="834" height="577" /> 

<p>&#160;</p>

<p>This means that, even if you are doing the registration with elevated privileges, or with UAC disabled, those registry keys cannot be changed – only setup programs, by having the TrustedInstaller credentials, will be able to do the registration.</p>

<p>So what happens if you do the registration through RegisterTypeLib, or by running regsvr32.exe from the command prompt, or if you call DllRegisterServer directly, in Vista and later OSes? Turns out the outcome is fairly interesting.</p>

<ul>
  <li>RegisterTypeLib() fails with error 0x8002801c (TYPE_E_REGISTRYACCESS: “Error accessing the OLE registry”). </li>

  <li>DllRegisterServer(): this really depends on how DllRegisterServer() is implemented in the DLL that includes the type library. The default ATL implementation returns the HRESULT of RegisterTypeLib unchanged, so it also returns TYPE_E_REGISTRYACCESS. Other implementations may turn the error into a more generic HRESULT like E_FAIL. </li>

  <li>regsvr32.exe succeeds and shows the message box “DllRegisterServer in D:\ATLDll\Release\atldll.dll succeeded”. Uh? How can it be, if all it does is to call DllRegisterServer? First of all, we can double-check that the registry keys have not been changed. So what happens is that the call to DllRegisterServer failed, but nonetheless regsvr32.exe reported a successful return. This “magic” happens by means of the <a href="http://technet.microsoft.com/en-us/library/dd837644(WS.10).aspx" target="_blank">Shim Technology</a>: if the hosting process is regsvr32.exe, the return value of the RegSetValueEx() API is changed through a shim. </li>
</ul>

<p>The logic behind the tightening of security permissions on these registry keys should be fairly clear: if any registration of a COM Dll is allowed to overwrite the registry keys related to a system TLB like msxml6.dll (Windows 2003 behavior), the system may misbehave as soon as this Dll is removed. This is one of those scenarios where re-registering msxml6.dll (or another system dll) mysteriously fixed the problem until Windows 2003.</p>

<p>The logic behind the shim in regsvr32.exe is more subtle and has to do with compatibility. Let’s assume we re-register a dll like msxml6.dll by running regsvr32.exe. Since the registration tries to write values to those protected registry keys, the registration would fail. Keep in mind, however, that those registry keys already have those values from the registration that occurred at installation time, when a principal with the TrustedInstaller credentials wrote them. Reporting a failure from regsvr32 would make the user think that something went wrong, which is not the case here. The same behavior takes place if we are registering a custom TLB that happens to embed the definition of the IXMLDOMXxx interfaces.</p>

<p>All right, we came to know the details of type library registration and the “magic” of shims, so it is time to go back to our main topic.</p>

<h4>import and importlib</h4>

<p>There are essentially 2 ways you can make a type visible within a type library: <a href="http://msdn.microsoft.com/en-us/library/aa367047(v=VS.85).aspx" target="_blank">import</a> and <a href="http://msdn.microsoft.com/en-us/library/aa367050(v=VS.85).aspx" target="_blank">importlib</a>. </p>

<p>import really imports the types in the current .IDL and, as a consequence, in the generated type library (in other words, it does what its name advertises <img alt="Smile" src="http://messenger.msn.com/MMM2006-04-19_17.00/Resource/emoticons/regular_smile.gif" />). </p>

<p>importlib reads the types from a type library and makes them available for type resolution. If type resolution happens successfully, the generated type library will contain a reference to the original type defined in the external type library. Note that importlib can only be used inside the <a href="http://msdn.microsoft.com/en-us/library/aa367069(v=VS.85).aspx" target="_blank">library block</a> of an IDL file.</p>

<p>What happens if a type is referenced by both import and importlib? The MIDL compiler resolves agains the first type, which means the type imported through the import statement (importlib can be used within the library block, whereas import is typically used at the beginning of the IDL file).</p>

<p>With reference to the problem at hand, if we use both “import <span style="color: #006080"><font color="#000000">&quot;ocidl.idl&quot; and importlib(“msxml6.dll”), </font></span><span style="color: #006080"><font color="#000000">the generated type library will still embed the IXMLDOMXxx interfaces. This information, however, gives us an easy solution to our problem: use importlib(“msxml6.dll”) without import(“ocidl.idl”). So the following IDL file:</font></span></p>

<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 95.84%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; height: 507px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 98.93%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; height: 470px; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><font color="#0000ff">import</font> <span style="color: #006080">&quot;oaidl.idl&quot;</span>;<br /><span style="color: #008000">//import &quot;ocidl.idl&quot;;</span><br /><br />[<br />    <font color="#0000ff">uuid</font>(F31AF329-0FE0-4640-80F8-40D187FF4D8B),<br />    <font color="#0000ff">version</font>(1.0),<br />    <font color="#0000ff">helpstring</font>(<span style="color: #006080">&quot;MyItfLib 1.0 Type Library&quot;</span>)<br />]<br /><font color="#0000ff">library</font> MyItfLib<br />{<br />    <font color="#0000ff">importlib</font>(<span style="color: #006080">&quot;stdole32.tlb&quot;</span>);<br />    <font color="#0000ff">importlib</font>(<span style="color: #006080">&quot;stdole2.tlb&quot;</span>);<br />    <font color="#0000ff">importlib</font>(<span style="color: #006080">&quot;msxml6.dll&quot;</span>);<br />    [<br />        <span style="color: #0000ff">object</span>,<br />        <font color="#0000ff">uuid</font>(BBA99D28-318E-4d69-A835-822EBDCEDA29),<br />        <font color="#0000ff">oleautomation</font>,<br />        <font color="#0000ff">helpstring</font>(<span style="color: #006080">&quot;IMyItf Interface&quot;</span>),<br />        <font color="#0000ff">pointer_default</font>(<font color="#0000ff">unique</font>)<br />    ]<br />    <span style="color: #0000ff">interface</span> IMyItf : IUnknown<br />    {<br />         [<font color="#0000ff">id</font>(1), <font color="#0000ff">helpstring</font>(<span style="color: #006080">&quot;method Load&quot;</span>)] HRESULT Load([<span style="color: #0000ff">in</span>] IXmlDOMNode* querySettingsNode);<br />    };<br />};</pre>

  <br /></div>

<p><span style="color: #006080"><font color="#000000">will generate a type library with only the IMyItf interface defined.&#160; IXMLDOMNode is referenced from the external TLB:</font></span></p>

<p><span style="color: #006080"><font color="#000000"></font></span></p>
<img style="border-right-width: 0px; margin: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/carlos/WindowsLiveWriter/6fec3d82487e_F12B/image_10.png" original-url="http://blogs.msdn.com/blogfiles/carlos/WindowsLiveWriter/6fec3d82487e_F12B/image_10.png" width="773" height="565" /> 

<p>&#160;</p>

<p>Unfortunately, this is not the end of the story <img alt="Confused" src="http://messenger.msn.com/MMM2006-04-19_17.00/Resource/emoticons/confused_smile.gif" />. There are special cases (not so special, actually) where this simple approach does not work. Read on…</p>

<h4>Forward Declarations and Type Dependencies</h4>

<p>Using import without importlib in the previous section did the job. This does not work, however, if we define interfaces outside the library block (forward declaration). For example:</p>

<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; height: 530px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 99.13%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; height: 493px; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><font color="#0000ff">import</font> <span style="color: #006080">&quot;oaidl.idl&quot;</span>;<br /><span style="color: #008000">//import &quot;ocidl.idl&quot;;</span><br /><br />[<br />    <span style="color: #0000ff">object</span>,<br />    <font color="#0000ff">uuid</font>(BBA99D28-318E-4d69-A835-822EBDCEDA29),<br />    <font color="#0000ff">oleautomation</font>,<br />    <font color="#0000ff">helpstring</font>(<span style="color: #006080">&quot;IMyItf Interface&quot;</span>),<br />    <font color="#0000ff">pointer_default</font>(<font color="#0000ff">unique</font>)<br />]<br /><span style="color: #0000ff">interface</span> IMyItf : IUnknown<br />{<br />    [<font color="#0000ff">id</font>(1), <font color="#0000ff">helpstring</font>(<span style="color: #006080">&quot;method Load&quot;</span>)] HRESULT Load([<span style="color: #0000ff">in</span>] IXmlDOMNode* querySettingsNode);<br />};<br /><br />[<br />    <font color="#0000ff">uuid</font>(F31AF329-0FE0-4640-80F8-40D187FF4D8B),<br />    <font color="#0000ff">version</font>(1.0),<br />    <font color="#0000ff">helpstring</font>(<span style="color: #006080">&quot;MyItfLib 1.0 Type Library&quot;</span>)<br />]<br /><font color="#0000ff">library</font> MyItfLib<br />{<br />    <font color="#0000ff">importlib</font>(<span style="color: #006080">&quot;stdole32.tlb&quot;</span>);<br />    <font color="#0000ff">importlib</font>(<span style="color: #006080">&quot;stdole2.tlb&quot;</span>);<br />    <font color="#0000ff">importlib</font>(<span style="color: #006080">&quot;msxml6.dll&quot;</span>);<br /><br />    <span style="color: #0000ff">interface</span> IMyItf;<br />};</pre>

  <br /></div>

<p>in this case, since we are referencing IXMLDOMNode outside the library block, the reference to IXMLDOMNode cannot be resolved and we get the following error:</p>

<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.95%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; height: 73px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 98.99%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; height: 56px; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">1&gt;.\MyItf.idl(13) : error MIDL2025 : syntax error : expecting a type specification <font color="#000000">near <span style="color: #006080"><font color="#000000">&quot;IXmlDOMNode&quot;</font></span><br />1</font>&gt;.\MyItf.idl(13) : error MIDL2026 : cannot recover from earlier syntax errors; aborting compilation <br /></pre>
</div>

<p>If you are the author of the IDL file, the solution here is pretty easy: avoid the forward declaration and place everything in the library block. Unless you have a complex set of dependencies (for example, interface A uses interface B in some of its methods, and interface B uses interface A in some of its methods), this is doable and effectively addresses the problem.</p>

<p>There is another potential issue though: what if your IDL file needs another type that is defined (either directly or indirectly) in ocidl.idl? If this happens, you need to import ocidl.idl, but by doing that you are also including msxml.idl and hence embedding the IXMLDOMXxx interfaces in your TLB again!!</p>

<p>Here is an example of such an interface (IOleControl is defined directly in ocidl.idl):</p>

<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; height: 271px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 99.14%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; height: 235px; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">[<br />    <span style="color: #0000ff">object</span>,<br />    <font color="#0000ff">uuid</font>(BBA99D28-318E-4d69-A835-822EBDCEDA29),<br />    <font color="#0000ff">oleautomation</font>,<br />    <font color="#0000ff">helpstring</font>(<span style="color: #006080">&quot;IMyItf Interface&quot;</span>),<br />    <font color="#0000ff">pointer_default</font>(<font color="#0000ff">unique</font>)<br />]<br /><span style="color: #0000ff">interface</span> IMyItf : IUnknown<br />{<br />    [<font color="#0000ff">id</font>(1), <font color="#0000ff">helpstring</font>(<span style="color: #006080">&quot;method Load&quot;</span>)] HRESULT Load([<span style="color: #0000ff">in</span>] IXMLDOMNode* querySettingsNode);<br />    [<font color="#0000ff">id</font>(2), <font color="#0000ff">helpstring</font>(<span style="color: #006080">&quot;method InitControl&quot;</span>)] HRESULT InitControl([<span style="color: #0000ff">in</span>] IOleControl* pControl);<br />};<br /></pre>

  <br /></div>

<p>Ok, this is admittedly the trickiest part, so let’s take a deep breath before we go on <img alt="Smile" src="http://messenger.msn.com/MMM2006-04-19_17.00/Resource/emoticons/regular_smile.gif" />.</p>

<h4>DO_NO_IMPORTS to the rescue</h4>

<p>Some of you may legitimately wonder: why do we need to import ocidl.idl to have the definition of IOleControl? Couldn’t we follow the same steps that we used for IXMLDOMNode and use importlib against the type library that defines IOleControl?</p>

<p>Yes, we could. The problem is that there is no type library in the sytem that defines IOleControl. This may seem strange, but there is a reason (there is a reason for everything, isn’t there? <img alt="Smile" src="http://messenger.msn.com/MMM2006-04-19_17.00/Resource/emoticons/regular_smile.gif" />): type libraries are used mainly for type-library (also known as OleAutomation, or Universal) marshaling. If an interface defines its own marshaling, there is no need for a type library. Here is how the registry looks like for IOleControl:</p>
<img style="border-right-width: 0px; margin: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/carlos/WindowsLiveWriter/6fec3d82487e_F12B/image_11.png" original-url="http://blogs.msdn.com/blogfiles/carlos/WindowsLiveWriter/6fec3d82487e_F12B/image_11.png" width="1093" height="342" /> 

<p>As you can see, there is no TypeLib subkey. So we really need to import ocidl.idl in order to have the definition of IOleControl.</p>

<p>Let’s have a look at how ocidl.idl imports the IXMLDOMXxx interfaces. At the beginning of ocidl.idl we have:</p>

<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; height: 143px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 99.22%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; height: 104px; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><font color="#0000ff">#ifndef</font> DO_NO_IMPORTS<br /><font color="#0000ff">import</font> <span style="color: #006080">&quot;oleidl.idl&quot;</span>;<br /><font color="#0000ff">import</font> <span style="color: #006080">&quot;oaidl.idl&quot;</span>;<br /><font color="#0000ff">import</font> <span style="color: #006080">&quot;servprov.idl&quot;</span>;<br /><font color="#0000ff">import</font> <span style="color: #006080">&quot;urlmon.idl&quot;</span>;<br /><span style="color: #cc6633"><font color="#0000ff">#endif</font></span><br /></pre>

  <br /></div>

<p>and near the beginning of urlmon.idl we have:</p>

<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; height: 109px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 99.55%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; height: 71px; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><font color="#0000ff">import</font> <span style="color: #006080">&quot;objidl.idl&quot;</span>;<br /><font color="#0000ff">import</font> <span style="color: #006080">&quot;oleidl.idl&quot;</span>;<br /><font color="#0000ff">import</font> <span style="color: #006080">&quot;servprov.idl&quot;</span>;<br /><font color="#0000ff">import</font> <span style="color: #006080">&quot;msxml.idl&quot;</span>;</pre>

  <br /></div>

<p>msxml.idl defines the IXMLDOMXxx interfaces. So it seems that we may be able to achieve our goal by using the preprocessor definition DO_NO_IMPORTS. If we do that (best way is to specify it in the “Preprocessor Definitions” test box in the .IDL file properties, equivalent to the <a href="http://msdn.microsoft.com/en-us/library/aa367321(v=VS.85).aspx" target="_blank">/D command-line option</a>, instead of using #define in the .IDL file), however, we get the following output from the MIDL compiler:</p>

<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.66%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; height: 97px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100.41%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; height: 44px; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">1&gt;C:\Program Files\Microsoft SDKs\Windows\v6.0A\include\oaidl.idl(64) : error MIDL2025 : syntax error : expecting a type specification near <span style="color: #006080"><font color="#000000">&quot;ULONG&quot;</font></span><br />1&gt;C:\Program Files\Microsoft SDKs\Windows\v6.0A\include\oaidl.idl(65) : error MIDL2026 : cannot recover from earlier syntax errors; aborting compilation</pre>

  <br /></div>

<p>Note that the errors are generating while compiling oaidl.idl, which is imported before ocidl.idl. The reason is clear if we look near the beginning of oaidl.idl:</p>

<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; height: 88px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 98.97%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; height: 52px; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><font color="#0000ff">#ifndef</font> DO_NO_IMPORTS<br /><font color="#0000ff">import</font> <span style="color: #006080">&quot;objidl.idl&quot;</span>;<br /><span style="color: #cc6633"><font color="#0000ff">#endif</font></span><br /></pre>

  <br /></div>

<p>Since objidl.idl defines some basic types like ULONG, we need to include it explicitly before objidl.idl. Once we do this, we still get errors because of unresolved types. We can fine-tune import of other IDL files until we get to this:</p>

<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; height: 143px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 98.47%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; height: 107px; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><font color="#0000ff">import</font> <span style="color: #006080">&quot;wtypes.idl&quot;</span>;<br /><font color="#0000ff">import</font> <span style="color: #006080">&quot;unknwn.idl&quot;</span>;<br /><font color="#0000ff">import</font> <span style="color: #006080">&quot;objidl.idl&quot;</span>;<br /><font color="#0000ff">import</font> <span style="color: #006080">&quot;oaidl.idl&quot;</span>;<br /><font color="#0000ff">import</font> <span style="color: #006080">&quot;oleidl.idl&quot;</span>;<br /><font color="#0000ff">import</font> <span style="color: #006080">&quot;ocidl.idl&quot;</span>;<br /></pre>

  <br /></div>

<p>With this sequence of imports we still get a MIDL compiler error:</p>

<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; height: 97px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100.08%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; height: 44px; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">1&gt;C:\Program Files\Microsoft SDKs\Windows\v6.0A\include\ocidl.idl(1830) : error MIDL2025 : syntax error : expecting a type specification near <span style="color: #006080">&quot;IBindHost&quot;</span><br />1&gt;C:\Program Files\Microsoft SDKs\Windows\v6.0A\include\ocidl.idl(1830) : error MIDL2026 : cannot recover from earlier syntax errors; aborting compilation <br /></pre>

  <br /></div>

<p>IBindHost is defined in urlmon.idl, which is imported conditionally in ocidl.idl (see first code snippet in this section). However, importing urlmon.idl before ocidl.idl is not a solution, because urlmon.idl imports msxml.idl, as shown by this import sequence at the beginning of urlmon.idl:</p>

<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; height: 106px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 98.59%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; height: 70px; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">import <span style="color: #006080">&quot;objidl.idl&quot;</span>;<br />import <span style="color: #006080">&quot;oleidl.idl&quot;</span>;<br />import <span style="color: #006080">&quot;servprov.idl&quot;</span>;<br />import <span style="color: #006080">&quot;msxml.idl&quot;</span>;<br /></pre>

  <br /></div>

<p>So here we are apparently at a dead end: we would need to import urlmon.idl because ocidl.idl needs the definition of IBindHost, but if we do that we also import msxml.idl, which will cause the embedding of the IXMLDOMXxx interfaces in our type library.</p>

<p>One possible way out here is to create your own custom IDL file, say MyBindHost.idl, which includes IBindHost and its dependencies, and then to import it in your IDL file in place of urlmon.idl:</p>

<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; height: 195px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 97.96%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; height: 155px; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><font color="#0000ff">import </font><span style="color: #006080">&quot;wtypes.idl&quot;</span>;<br /><font color="#0000ff">import</font> <span style="color: #006080">&quot;unknwn.idl&quot;</span>;<br /><font color="#0000ff">import</font> <span style="color: #006080">&quot;objidl.idl&quot;</span>;<br /><font color="#0000ff">import</font> <span style="color: #006080">&quot;oaidl.idl&quot;</span>;<br /><font color="#0000ff">import</font> <span style="color: #006080">&quot;oleidl.idl&quot;</span>;<br /><font color="#0000ff">import</font> <span style="color: #006080">&quot;mybindhost.idl&quot;</span>;<br /><font color="#0000ff">import</font> <span style="color: #006080">&quot;servprov.idl&quot;</span>;<br /><font color="#0000ff">import</font> <span style="color: #006080">&quot;ocidl.idl&quot;</span>;<br /></pre>

  <br /></div>

<p>This works and the IDL file compiles successfully to a TLB which does not include the definition of the IXMLDOMXxx interfaces. The TLB does include the definition of IOleControl, but this is not an issue: since the interface is not declared with the <a href="http://msdn.microsoft.com/en-us/library/aa366807(VS.85).aspx" target="_blank">dual</a> or <a href="http://msdn.microsoft.com/en-us/library/aa367129(v=VS.85).aspx" target="_blank">oleautomation</a> attributes, it won’t register itself as the marshaler of IOleControl.</p>

<p>A suitable MyBindHost.idl is attached at the end of this post.</p>

<h4>IUnknown is a special case</h4>

<p>At this point you may wonder about the interface IUnknown, which seems to have a different behavior: we need IUnknown in our IDL because it is the base interface of our interface:</p>



<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; height: 136px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 99.02%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; height: 100px; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">...<br /><span style="color: #0000ff">interface</span> IMyItf : IUnknown<br />{<br />    ...<br />};</pre>

  <br /></div>



<p>IUnknown is defined in unknwn.idl, which we are importing either directly or indirectly. IUnknown is also made available through importlib of stdole32.tlb and stdole2.tlb. In such a case, you would expect that the first definition is matched, and so we should see IUnknown in the generated type library, but this is not the case.</p>

<p>The reason is that the MIDL considers IUnknown (and potentially other interfaces) differently, and therefore a reference to it is generated in these cases, instead of embedding IUnknown in the generated type library.</p>

<h4>Summary</h4>

<p>Some key points of this post:</p>

<ul>
  <li>If you are authoring IDL files, you need to understand the difference between referencing a type in the type library you generate, and embedding it. </li>

  <li>It is very important to avoid embedding system types into your own type library. A common case when this may happen is with the IXMLDOMXxx interfaces. </li>

  <li>In Vista and later operating systems, permissions on registry keys prevent the association of a system interface with a different type library. However, type library registration may fail if not done through regsvr32.exe. </li>

  <li>If your solution consists of several type libraries, the same principles apply: you should define a type in one type library only, and reference it from other type libraries by using importlib. If this causes circular references, factor out the involved types into one type library and reference it from the other type libraries. </li>
</ul>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/99/11/32/MyBindHost.idl" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-09-99-11-32/MyBindHost.idl">MyBindHost.idl</a></p>]]></content:encoded>
    </item>
  </channel>
</rss>