<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2762480305572920625</id><updated>2024-10-08T18:56:32.466-07:00</updated><category term=".NET"/><category term="C#"/><category term="Config-file"/><category term="DuplexChannel"/><category term="Extensibility"/><category term="Lazy"/><category term="Plugins"/><category term="WCF"/><title type='text'>Thread.Sleep()</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://thread-sleep.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2762480305572920625/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://thread-sleep.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>pablito900</name><uri>http://www.blogger.com/profile/08864451540305086582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3dGkwRMkKvgLy4-1hXd3zW1QaU94M2BeNIrl9US4zFsElUHGtlI7BTRTmC-kLz3KPIq4hP1TngfBFUFrBIndFWd8ePvqYmpjTtepo0XNrpyGr4kxQOWzBsJ8jcMxU8NU/s220/pab.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>2</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2762480305572920625.post-7204010269190447192</id><published>2010-01-25T01:24:00.000-08:00</published><updated>2010-01-25T01:38:23.530-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="Extensibility"/><category scheme="http://www.blogger.com/atom/ns#" term="Lazy"/><category scheme="http://www.blogger.com/atom/ns#" term="Plugins"/><title type='text'>Attach to process for lazies</title><content type='html'>&lt;div&gt;Attaching to a process is something that developers use very often to debug, but what happens when the process (A) you want to debug is launched from another process (B) and you want to debug is the initialization of process A,  Supposing that process A can only run within the context of process B in that case the only way to start process A is to do so from process so classic F5 won&#39;t help us to debug the initialization of A.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;I had this scenario at work so at first I &quot;trained&quot; myself to do a very fast Alt+Ctrl+P select the process and press Attach button, of course this training didn&#39;t help much, after googling a little I found this macro&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;Vb&quot;&gt;&lt;br /&gt;  Sub AttachProcess()&lt;br /&gt;        Dim process As EnvDTE.Process&lt;br /&gt; &lt;br /&gt;        If Not (DTE.Debugger.DebuggedProcesses Is Nothing) Then&lt;br /&gt;            For Each process In DTE.Debugger.DebuggedProcesses&lt;br /&gt;                If (process.Name.IndexOf(&quot;aspnet_wp.exe&quot;) &lt;&gt; -1) Then&lt;br /&gt;                    Exit Sub&lt;br /&gt;                End If&lt;br /&gt;            Next&lt;br /&gt;        End If&lt;br /&gt; &lt;br /&gt;        For Each process In DTE.Debugger.LocalProcesses&lt;br /&gt;            If (process.Name.IndexOf(&quot;myprocess.exe&quot;) &lt;&gt; -1) Then&lt;br /&gt;                process.Attach()&lt;br /&gt;                Exit Sub&lt;br /&gt;            End If&lt;br /&gt;        Next&lt;br /&gt;    End Sub &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;but still it would have to wait for the process to start and then attach to it, so finally I created this Visual Studio add-in, which have this option.&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;The main idea is to wait for the process to start and then attach to it:&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;CSharp&quot;&gt;&lt;br /&gt;private AttachResult PessimisticAttach(AttachType attachType)&lt;br /&gt;{&lt;br /&gt;     AttachResult res = Attach(attachType);&lt;br /&gt;     DateTime timeout = DateTime.Now.AddSeconds(WaitTimeout);&lt;br /&gt;   &lt;br /&gt;     while(res == AttachResult.NotRunning &amp;&amp; timeout &gt; DateTime.Now)&lt;br /&gt;     {&lt;br /&gt;           res = Attach(attachType);&lt;br /&gt;           System.Threading.Thread.Sleep(100);&lt;br /&gt;     }&lt;br /&gt;     return res;&lt;br /&gt;}&lt;br /&gt;   &lt;br /&gt;private AttachResult Attach(AttachType attachType)&lt;br /&gt;{&lt;br /&gt;     string engine =attachTypesMap[attachType];&lt;br /&gt;     if(IsBeingDebugged())&lt;br /&gt;     {&lt;br /&gt;          return AttachResult.BeingDebugged;&lt;br /&gt;     }&lt;br /&gt;   &lt;br /&gt;     Debugger2 dbg = dte.Debugger as Debugger2;&lt;br /&gt;     Transport trans = dbg.Transports.Item(&quot;Default&quot;);&lt;br /&gt;     Engine eng;&lt;br /&gt;   &lt;br /&gt;     eng = trans.Engines.Item(engine);&lt;br /&gt;   &lt;br /&gt;     EnvDTE80.Process2 proc = null;&lt;br /&gt;   &lt;br /&gt;     try&lt;br /&gt;     {&lt;br /&gt;          proc = dbg.GetProcesses(trans, &quot;&quot;).Item(processName) &lt;br /&gt;              as EnvDTE80.Process2;&lt;br /&gt;     }&lt;br /&gt;     catch(Exception ex)&lt;br /&gt;     {&lt;br /&gt;          if(ex.Message.Contains(&quot;Invalid index.&quot;))&lt;br /&gt;          {&lt;br /&gt;              return AttachResult.NotRunning;&lt;br /&gt;          }&lt;br /&gt;     }&lt;br /&gt;   &lt;br /&gt;     proc.Attach2(eng);&lt;br /&gt;     return AttachResult.Attached;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;I wrote the add-in using &lt;a href=&quot;/rosherove/archive/2008/08/02/declarative-visual-studio-addin-buttons-with-icons.aspx&quot; class=&quot;&quot; title=&quot;Declarative Visual Studio addin buttons with icons&quot; mce_href=&quot;/rosherove/archive/2008/08/02/declarative-visual-studio-addin-buttons-with-icons.aspx&quot;&gt;Declarative Visual Studio addin buttons with icons&lt;/a&gt;&amp;nbsp;which saved me a lot of time and pain.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;p&gt;You can &lt;a href=&quot;http://www.codeplex.com/lazy/SourceControl/ListDownloadableCommits.aspx&quot; class=&quot;&quot; title=&quot;download plug in source here&quot; target=&quot;_blank&quot; mce_href=&quot;http://www.codeplex.com/lazy/SourceControl/ListDownloadableCommits.aspx&quot;&gt;download&amp;nbsp;add in&amp;nbsp;source here&lt;/a&gt;.&amp;nbsp; &lt;/p&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thread-sleep.blogspot.com/feeds/7204010269190447192/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://thread-sleep.blogspot.com/2010/01/attaching-to-process-is-something-that.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2762480305572920625/posts/default/7204010269190447192'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2762480305572920625/posts/default/7204010269190447192'/><link rel='alternate' type='text/html' href='http://thread-sleep.blogspot.com/2010/01/attaching-to-process-is-something-that.html' title='Attach to process for lazies'/><author><name>pablito900</name><uri>http://www.blogger.com/profile/08864451540305086582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3dGkwRMkKvgLy4-1hXd3zW1QaU94M2BeNIrl9US4zFsElUHGtlI7BTRTmC-kLz3KPIq4hP1TngfBFUFrBIndFWd8ePvqYmpjTtepo0XNrpyGr4kxQOWzBsJ8jcMxU8NU/s220/pab.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2762480305572920625.post-5006575620258758370</id><published>2010-01-25T00:14:00.000-08:00</published><updated>2010-01-25T01:21:39.824-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET"/><category scheme="http://www.blogger.com/atom/ns#" term="Config-file"/><category scheme="http://www.blogger.com/atom/ns#" term="DuplexChannel"/><category scheme="http://www.blogger.com/atom/ns#" term="WCF"/><title type='text'>Override WCF client settings for custom config file using DuplexChannel</title><content type='html'>WCF config files are a great thing, once you have everything configured you just need 2 or 3 lines of code and everything get parsed and you are able to consume the service. By default WCF configuration is stored in the app.config or web.config of the main application, but sometimes (as was my case) the client is in-process of another unknown application, if so the WCF config file will have to be named SomeApp.exe.config and would need to be placed in the same folder as the application. Dealing with this can make things difficult, this is when you have to create your own ChannelFactory, this way you can provide your own config file. The solution I found after doing some goggling was to inherit from ChannelFactoryand the pass the config file to the constructor&lt;br /&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;CSharp&quot;&gt;&lt;br /&gt;public CustomChannelFactory(string configurationPath): base(typeof(T))&lt;br /&gt;{&lt;br /&gt;this.configurationPath = configurationPath;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;and the override CreateDescription method in which we set our config file. This works great, but not for my case since I was using a DuplexChannel, so when we inherith from DuplexChannelFactory&lt;t&gt; we must call the base constructor with the CallBackInstance parameter, so the CreateDescription will be called before we can initialize the configurationPath member. The only solution I had in mind was make ConfigurationPath to be static member and then we initialize this before we create the instance of our CustomDuplexChannel, this solution seemed &quot;ugly&quot; for me at first but then I realized that the configuration can be stored in a static member since we are planning to use one configuration file for consuming all our services.&lt;br /&gt;&lt;br /&gt;&lt;/t&gt;&lt;/p&gt;&lt;br /&gt;&lt;div style=&quot;text-align: left;line-height: 12pt;overflow:auto;padding:0px;  width: 97.5%;  max-height: 200px;  border: silver 1px solid; cursor: text; margin:0&quot;  id=&quot;codeSnippetWrapper&quot;&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;CSharp&quot;&gt;&lt;br /&gt;public class CustomDuplexChannelFactory&amp;lt;TChannel&amp;gt; : DuplexChannelFactory&amp;lt;TChannel&amp;gt;&lt;br /&gt; {&lt;br /&gt;     public static string ConfigurationPath { get; set; }&lt;br /&gt;&lt;br /&gt;     public CustomDuplexChannelFactory(InstanceContext callbackInstance)&lt;br /&gt;         : base(callbackInstance)&lt;br /&gt;     {&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     protected override ServiceEndpoint CreateDescription()&lt;br /&gt;     {&lt;br /&gt;         ServiceEndpoint serviceEndpoint = base.CreateDescription();&lt;br /&gt;         if(ConfigurationPath == null || !File.Exists(ConfigurationPath))&lt;br /&gt;             return base.CreateDescription();&lt;br /&gt;&lt;br /&gt;         ExeConfigurationFileMap executionFileMap = new ExeConfigurationFileMap();&lt;br /&gt;         executionFileMap.ExeConfigFilename = ConfigurationPath;&lt;br /&gt;&lt;br /&gt;         System.Configuration.Configuration config =&lt;br /&gt;             ConfigurationManager.OpenMappedExeConfiguration(&lt;br /&gt;             executionFileMap, ConfigurationUserLevel.None);&lt;br /&gt;         ServiceModelSectionGroup serviceModeGroup =&lt;br /&gt;             ServiceModelSectionGroup.GetSectionGroup(config);&lt;br /&gt;&lt;br /&gt;         ChannelEndpointElement selectedEndpoint = null;&lt;br /&gt;&lt;br /&gt;         foreach(ChannelEndpointElement endpoint in serviceModeGroup.Client.Endpoints)&lt;br /&gt;         {&lt;br /&gt;             if(endpoint.Contract == serviceEndpoint.Contract.ConfigurationName)&lt;br /&gt;             {&lt;br /&gt;                 selectedEndpoint = endpoint;&lt;br /&gt;                 break;&lt;br /&gt;             }&lt;br /&gt;         }&lt;br /&gt;&lt;br /&gt;         if(selectedEndpoint != null)&lt;br /&gt;         {&lt;br /&gt;             if(serviceEndpoint.Binding == null)&lt;br /&gt;             {&lt;br /&gt;                 serviceEndpoint.Binding = CreateBinding(selectedEndpoint.Binding, serviceModeGroup);&lt;br /&gt;             }&lt;br /&gt;&lt;br /&gt;             if(serviceEndpoint.Address == null)&lt;br /&gt;             {&lt;br /&gt;                 serviceEndpoint.Address = new EndpointAddress(selectedEndpoint.Address,&lt;br /&gt;                     GetIdentity(selectedEndpoint.Identity), selectedEndpoint.Headers.Headers);&lt;br /&gt;             }&lt;br /&gt;&lt;br /&gt;             if(serviceEndpoint.Behaviors.Count == 0 &amp;amp;&amp;amp;&lt;br /&gt;                 !String.IsNullOrEmpty(selectedEndpoint.BehaviorConfiguration))&lt;br /&gt;             {&lt;br /&gt;                 AddBehaviors(selectedEndpoint.BehaviorConfiguration,&lt;br /&gt;                     serviceEndpoint, serviceModeGroup);&lt;br /&gt;             }&lt;br /&gt;&lt;br /&gt;             serviceEndpoint.Name = selectedEndpoint.Contract;&lt;br /&gt;         }&lt;br /&gt;&lt;br /&gt;         return serviceEndpoint;&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     #region private&lt;br /&gt;&lt;br /&gt;     private Binding CreateBinding(string bindingName, ServiceModelSectionGroup group)&lt;br /&gt;     {&lt;br /&gt;         BindingCollectionElement bindingElementCollection = group.Bindings[bindingName];&lt;br /&gt;         if(bindingElementCollection.ConfiguredBindings.Count &amp;gt; 0)&lt;br /&gt;         {&lt;br /&gt;             IBindingConfigurationElement be = bindingElementCollection.ConfiguredBindings[0];&lt;br /&gt;&lt;br /&gt;             Binding binding = GetBinding(be);&lt;br /&gt;             if(be != null)&lt;br /&gt;             {&lt;br /&gt;                 be.ApplyConfiguration(binding);&lt;br /&gt;             }&lt;br /&gt;&lt;br /&gt;             return binding;&lt;br /&gt;         }&lt;br /&gt;&lt;br /&gt;         return null;&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     private void AddBehaviors(string behaviorConfiguration, ServiceEndpoint serviceEndpoint,&lt;br /&gt;         ServiceModelSectionGroup group)&lt;br /&gt;     {&lt;br /&gt;         EndpointBehaviorElement behaviorElement =&lt;br /&gt;             group.Behaviors.EndpointBehaviors[behaviorConfiguration];&lt;br /&gt;         for(int i = 0; i &amp;lt; behaviorElement.Count; i++)&lt;br /&gt;         {&lt;br /&gt;             BehaviorExtensionElement behaviorExtension = behaviorElement[i];&lt;br /&gt;             object extension = behaviorExtension.GetType().InvokeMember(&quot;CreateBehavior&quot;,&lt;br /&gt;             BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance,&lt;br /&gt;             null, behaviorExtension, null);&lt;br /&gt;             if(extension != null)&lt;br /&gt;             {&lt;br /&gt;                 serviceEndpoint.Behaviors.Add((IEndpointBehavior)extension);&lt;br /&gt;             }&lt;br /&gt;         }&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     private EndpointIdentity GetIdentity(IdentityElement element)&lt;br /&gt;     {&lt;br /&gt;         EndpointIdentity identity = null;&lt;br /&gt;         PropertyInformationCollection properties = element.ElementInformation.Properties;&lt;br /&gt;         if(properties[&quot;userPrincipalName&quot;].ValueOrigin != PropertyValueOrigin.Default)&lt;br /&gt;         {&lt;br /&gt;             return EndpointIdentity.CreateUpnIdentity(element.UserPrincipalName.Value);&lt;br /&gt;         }&lt;br /&gt;         if(properties[&quot;servicePrincipalName&quot;].ValueOrigin != PropertyValueOrigin.Default)&lt;br /&gt;         {&lt;br /&gt;             return EndpointIdentity.CreateSpnIdentity(element.ServicePrincipalName.Value);&lt;br /&gt;         }&lt;br /&gt;         if(properties[&quot;dns&quot;].ValueOrigin != PropertyValueOrigin.Default)&lt;br /&gt;         {&lt;br /&gt;             return EndpointIdentity.CreateDnsIdentity(element.Dns.Value);&lt;br /&gt;         }&lt;br /&gt;         if(properties[&quot;rsa&quot;].ValueOrigin != PropertyValueOrigin.Default)&lt;br /&gt;         {&lt;br /&gt;             return EndpointIdentity.CreateRsaIdentity(element.Rsa.Value);&lt;br /&gt;         }&lt;br /&gt;         if(properties[&quot;certificate&quot;].ValueOrigin != PropertyValueOrigin.Default)&lt;br /&gt;         {&lt;br /&gt;             X509Certificate2Collection supportingCertificates = new X509Certificate2Collection();&lt;br /&gt;             supportingCertificates.Import(Convert.FromBase64String(element.Certificate.EncodedValue));&lt;br /&gt;             if(supportingCertificates.Count == 0)&lt;br /&gt;             {&lt;br /&gt;                 throw new InvalidOperationException(&quot;UnableToLoadCertificateIdentity&quot;);&lt;br /&gt;             }&lt;br /&gt;             X509Certificate2 primaryCertificate = supportingCertificates[0];&lt;br /&gt;             supportingCertificates.RemoveAt(0);&lt;br /&gt;             return EndpointIdentity.CreateX509CertificateIdentity(primaryCertificate,&lt;br /&gt;                 supportingCertificates);&lt;br /&gt;         }&lt;br /&gt;&lt;br /&gt;         return identity;&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     private Binding GetBinding(IBindingConfigurationElement configurationElement)&lt;br /&gt;     {&lt;br /&gt;         if(configurationElement is CustomBindingElement)&lt;br /&gt;             return new CustomBinding();&lt;br /&gt;         else if(configurationElement is BasicHttpBindingElement)&lt;br /&gt;             return new BasicHttpBinding();&lt;br /&gt;         else if(configurationElement is NetMsmqBindingElement)&lt;br /&gt;             return new NetMsmqBinding();&lt;br /&gt;         else if(configurationElement is NetNamedPipeBindingElement)&lt;br /&gt;             return new NetNamedPipeBinding();&lt;br /&gt;         else if(configurationElement is NetPeerTcpBindingElement)&lt;br /&gt;             return new NetPeerTcpBinding();&lt;br /&gt;         else if(configurationElement is NetTcpBindingElement)&lt;br /&gt;             return new NetTcpBinding();&lt;br /&gt;         else if(configurationElement is WSDualHttpBindingElement)&lt;br /&gt;             return new WSDualHttpBinding();&lt;br /&gt;         else if(configurationElement is WSHttpBindingElement)&lt;br /&gt;             return new WSHttpBinding();&lt;br /&gt;         else if(configurationElement is WSFederationHttpBindingElement)&lt;br /&gt;             return new WSFederationHttpBinding();&lt;br /&gt;&lt;br /&gt;         return null;&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thread-sleep.blogspot.com/feeds/5006575620258758370/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://thread-sleep.blogspot.com/2010/01/override-wcf-client-settings-for-custom.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2762480305572920625/posts/default/5006575620258758370'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2762480305572920625/posts/default/5006575620258758370'/><link rel='alternate' type='text/html' href='http://thread-sleep.blogspot.com/2010/01/override-wcf-client-settings-for-custom.html' title='Override WCF client settings for custom config file using DuplexChannel'/><author><name>pablito900</name><uri>http://www.blogger.com/profile/08864451540305086582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3dGkwRMkKvgLy4-1hXd3zW1QaU94M2BeNIrl9US4zFsElUHGtlI7BTRTmC-kLz3KPIq4hP1TngfBFUFrBIndFWd8ePvqYmpjTtepo0XNrpyGr4kxQOWzBsJ8jcMxU8NU/s220/pab.jpg'/></author><thr:total>0</thr:total></entry></feed>