Scott Hanselman

How to add a .REG file to your Registry silently

March 18, 2005 Comment on this post [5] Posted in Programming
Sponsored By

How to add a .REG file to your Registry silently? This question came up today. As is the case usually /s is for silent and /q is for quiet. One will usually work.

regedit /s foo.reg

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Rory and Scott design some software - TechEd - Revenge of the Sith

March 17, 2005 Comment on this post [10] Posted in TechEd | ASP.NET | Javascript | Speaking | Web Services
Sponsored By

Rory and I are REALLY talented software designers. We know all the acronyms and technical terms. DOS. WS-This and WS-That. ASP.NET. Packet. SOAP. PostBack. See?

Here's video number two in the ongoing saga. This is WAY better than the Star Wars Trilogy. WAY. BETTER.

Please spread it around and Trackback/Pingback it. If you can't view it below, you can download it here.

Remember, if you're blogging TechEd this year, make sure to register your blog at TechEd Bloggers.NET and get your content aggregated!


play video stop video indicatorhandleamount downloaded toggle sound launch in external player
Launch the streaming media file

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Yes, it WILL run differently under the Debugger

March 17, 2005 Comment on this post [1] Posted in ASP.NET | Web Services | Bugs
Sponsored By

It seems like an obvious thing to say, but I know that *I* totally forgot it. Running under the Debugger (not just when compiled in Debug Mode, but literally during Interactive Debugging) is a totally different universe than running 'normally.'

Recently my buddy Adam Cogan forwarded me an interesting thread that was going on at his company.

For an internal application, Mark Liu noticed when he called a Web Service in response to a WinForms event, say Key Down, but when that even had a 'partner event' on the way, like Key Up, that the Key Up would occur immediately, without waiting for the Synchronously-called Web Service to return.

He might see something like this in his call stack. Red is the event he expected to come later, and Purple is the Web Services call he was counting on blocking.

[<Non-user Code>]  
MySystem.windowsui.dll!MySystem.WindowsUI.Forms.PointOfSaleForm.SelectLineRow
MySystem.windowsui.dll!MySystem.WindowsUI.Forms.PointOfSaleForm.AddInventoryLine
MySystem.windowsui.dll!MySystem.WindowsUI.Forms.PointOfSaleForm.AddInventoryLine
MySystem.windowsui.dll!MySystem.WindowsUI.Components.PointOfSale.ProductKeyPad.b_Click
[<Non-user Code>]  
MySystem.windowsui.dll!MySystem.WindowsUI.Components.HotKeyProvider.ContainerForm_KeyUp
[<Non-user Code>]  
MySystem.webservicewrapper.dll!MySystem.
  WebServiceWrapper.somekindofWebService.SomeService.calculate_Some

MySystem.webservicewrapper.dll!MySystem.
  WebServiceWrapper.somekindofWebServiceWrapper.CalculateLines
MySystem.windowsui.dll!MySystem.WindowsUI.Components.SomeCalculator.Line_RowChanging
MySystem.data.dll!MySystem.Data.SomeDataSet.SomeDataTable.OnRowChanging
[<Non-user Code>]  
MySystem.windowsui.dll!MySystem.WindowsUI.Forms.PointOfSaleForm.AddNewInventoryOrderLine
MySystem.windowsui.dll!MySystem.WindowsUI.Forms.PointOfSaleForm.AddInventoryLine
MySystem.windowsui.dll!MySystem.WindowsUI.Forms.PointOfSaleForm.AddInventoryLine
MySystem.windowsui.dll!MySystem.WindowsUI.Components.PointOfSale.ProductKeyPad.b_Click
[<Non-user Code>]  
MySystem.windowsui.dll!MySystem.WindowsUI.Components.HotKeyProvider.ContainerForm_KeyUp

Without arguing the merits of the desired ordering of events, it appeared to everyone involved that the hidden "this.Invoke" that was doing the Web Services call was releasing control to the calling thread and allowing the KeyUp event to show up immediately.

I said I know that SoapHttpClientProtocol wouldn't be doing such evil since it's likely just calling BeginInvoke itself and waiting on the response. My less than useful answer was "don't do that." I figured that the UI thread wasn't going to block, but I was wrong. We all went back and forth and there was some scratching and biting. I only cried once.

Then George Doubinski from SolutionsNet said (wisely):

I think the debate somewhat degraded and everyone has forgotten the basics – get the simplest test case. I was very suspicious about this event processing business in a first place. So I whipped a bit of code of my own. Guess what – the thread blocks as it should and there is no funny KeyUp business (not that I would personally hook anything to KeyUp anyway). Did a bit of digging with Reflector and confirmed that Invoke in the end calls BeginWebResponse which is exactly what BeginInvoke calls (the difference is the first one does not provide a callback and waits on event explicitly). Started debugging – oops – got the described behaviour. Eureka!

Ah yes, back to basics. The VS.NET Stack Window has a context menu item called "Show Non-User Code." When he did this, the newly illuminated call stack showed:

WindowsApplication1.exe!WindowsApplication1.Form1.Form1_KeyUp(System.Object sender = {WindowsApplication1.Form1}, System.Windows.Forms.KeyEventArgs e = {KeyData=Return}) Line 168        C#
<snip>
system.windows.forms.dll!ControlNativeWindow.OnMessage(System.Windows.Forms.Message m = {System.Windows.Forms.Message}) + 0x13 bytes 
system.windows.forms.dll!ControlNativeWindow.WndProc(System.Windows.Forms.Message m = {System.Windows.Forms.Message}) + 0xda bytes
system.windows.forms.dll!System.Windows.Forms.NativeWindow.
  DebuggableCallback(int hWnd = 1445384, int msg = 257, int wparam = 13, int lparam = -1071906815) + 0x3d bytes    
system.web.services.dll!System.Web.Services.UnsafeNativeMethods.OnSyncCallOut
  (System.Web.Services.Interop.INotifySink2 sink = {System.__ComObject}, System.Web.Services.Interop.CallId callId = {System.Web.Services.Interop.CallId}, int out_ppBuffer = 0, int inout_pBufferSize = 0) + 0x37 bytes 
system.web.services.dll!System.Web.Services.Protocols.WebClientProtocol.GetWebRequest
  (System.Uri uri = {System.Uri}) + 0xdd bytes        
<snip>
  system.web.services.dll!System.Web.Services.Protocols.SoapHttpClientProtocol.BeginInvoke
(string methodName = "listCountries", System.Object[] parameters = {Length=0}, System.AsyncCallback callback = <undefined value>, System.Object asyncState = <undefined value>) + 0x53 bytes    

The interesting stuff is of course the method DebuggableCallback appearing in the call stack. This is our first hint that something different is happening at Debug Time.

Here is an interesting snippet from GetWebRequest:

if (RemoteDebugger.IsClientCallOutEnabled())
{
   this.debugger = new RemoteDebugger();
   this.debugger.NotifyClientCallOut(request1);
   return request1;
}

Ah. What's IsClientCalloutEnabled?

internal static bool IsClientCallOutEnabled()
{
      bool flag1 = false;
      try
      {
            flag1 = (!CompModSwitches.DisableRemoteDebugging.Enabled && Debugger.IsAttached) && (RemoteDebugger.Connection != null);
      }
      catch (Exception){}      
      return flag1;
}

So, message pumping is neccessary for Remote Debugging to occur. At this point, it's voodoo.

Moral: Debugging under VS.NET is amazing, but it is a different code path than at runtime. A good reminder from George.

Sample: Mark Liu thoughtfully includes sample code.

Now playing: DJ Bolivia - Memory Leak - www.djbolivia.ca

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

A Boilerplate HttpHandler

March 17, 2005 Comment on this post [8] Posted in ASP.NET | HttpHandler
Sponsored By

I've been writing HttpHandlers lately for such things as Check Images and Statement Downloads. Remember, an HttpHandler is the kind of thing you want to use when an HttpRequest is going to return a file or image to the browser. Basically anything other than a standard page. True, you could use a page, remove all the HTML from the ASPX part, and return stuff in Page_Load, but that's not really what pages are for, right? Also, Pages are themselves an HttpHandler (returned by PageHandlerFactory) so why not write your own HttpHandler?

Here's a boilerplate template I like to use for an HttpHandler. IMHO, an HttpHandler should always return appropriate HTTP Status Codes like you see below. Make sure the semantics of the status code(s) you choose match what you're trying to express. 404 for Not Found, 403 for Forbidden, 500 for Holy Crap!, etc.

One day I'll be more organized and make an abstract base class to handle this kind of boilerplate stuff. For now, it's on my blog.

    1 public class MyHandler : IHttpHandler

    2 {

    3     private const string CONSTSOMEPARAM = "SomeParam";

    4 

    5     public MyHandler(){}

    6 

    7     public void ProcessRequest(HttpContext context)

    8     {

    9         // Don't allow this response to be cached by the browser.

   10         // Note, you MIGHT want to allow it to be cached, depending on what you're doing.

   11         context.Response.Cache.SetCacheability(HttpCacheability.NoCache);

   12         context.Response.Cache.SetNoStore();

   13         context.Response.Cache.SetExpires(DateTime.MinValue);

   14 

   15         if (ValidateParameters(context) == false)

   16         {   

   17             //Internal Server Error

   18             context.Response.StatusCode = 500;

   19             context.Response.End();

   20             return;

   21         }

   22 

   23         if (context.User.Identity.IsAuthenticated == false)

   24         {

   25             //Forbidden

   26             context.Response.StatusCode = 403;

   27             context.Response.End();

   28             return;

   29         }

   30 

   31         string someParam = context.Request.QueryString[CONSTSOMEPARAM];

   32 

   33         SomethingReponse response = SomeService.SomeImportantThing(someParam);

   34         if(response.Header == null || response.Header.Success == false)

   35         {

   36             //Whatever wasn't found

   37             context.Response.StatusCode = 404;

   38             context.Response.End();

   39             return;

   40         }

   41 

   42         context.Response.ContentType = "somespecific/mimetype";

   43 

   44         context.Response.BinaryWrite();

   45         //or

   46         context.Response.Write();

   47         //or

   48         context.Response.WriteFile();

   49         //or

   50         someImageStream.Save(context.Response.OutputStream);

   51     }

   52 

   53     public bool ValidateParameters(HttpContext context)

   54     {

   55         //Validate some stuff...true if cool, false if not

   56         return false;

   57     }

   58 

   59     /// <summary>

   60     /// True if this handler can be reused between calls. That's cool if you don't have any class instance data.

   61     /// False if you'd rather get a fresh one.

   62     /// </summary>

   63     public bool IsReusable

   64     {

   65         get

   66         {

   67             return true;

   68         }

   69     }

   70 }

HttpHandlers are nice because their endpoint (fancy word for URL) is configurable in your web.config.

<httpHandlers>
   <add verb="GET,POST,WHATEVER" path="SomeEndPoint.ashx" type="MyNamespace.MtHandler, MyAssemblyName" />
</httpHandlers>

 

 

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

My new theme

March 17, 2005 Comment on this post [1] Posted in Musings
Sponsored By

Lots of nice complements on my Blog's new theme. It was done by Jon Dennis at http://www.aesthetixdesign.net/, and he was great to work with. Scott Swigart gave him his name. He also gives a small discount if you pay via PayPal which makes him even cooler. Highly recommended.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.