Scott Hanselman

A New Private Browser - I mean Browzar - does not work as advertised

September 1, '06 Comments [18] Posted in Reviews
Sponsored By

Browzar_skinsUPDATE: Looks like I was mentioned on the BBC.  I'm afraid they miss the point:

However, some computer experts say they have already identified flaws in Browzar. Scott Hanselman, writing on his blog Computer Zen, claims to have been able to find records of websites he had visited with the program installed.

"Browzar, at least this version, is totally not doing what it says it does," he writes.

The newly released software is entering a market dominated by Internet Explorer.

Of course, the joke here is that Browzar is a wrapper around Internet Explorer.

I had a 2 gig USB Drive, but it was huge and I didn't use it as much as I could. Then I picked up one of these OCZ 2GB Flash for $40 $31 after rebate (that's not a typo!) at Omar's recommendation. It's freaking small.

Then I secured it - you'd be a fool not to, IMHO. Now I'm getting all my Portable Apps moved over to it as well.

Portable apps mean that they can be run directly from a USB Drive without installation. There's a portable version of Firefox, for example.

However, I noticed this little browser, called Browzar, mentioned in this InformationWeek article, that is a single 265k EXE that basically wraps IE 5.5 or above (works fine with 7.0) and is a "private browser." That means it doesn't save cookies or history or autocomplete. Sounds like a convenient thing to have on one's USB drive if one didn't want to leave (blatent) footprints.

Well, since it's hosting IE, I want to see what it's doing. So, I fired it up and visited the naughtiest site I could think of, Pl*yboy, while running Filemon. Here's a screenshot of the cached naughty gifs going in my Temporary Internet Files folder. Notice that Browzar deletes the gifs as soon as it sees them.

Browzar1

Then I closed the browser...You can see here that it deleted a bunch of cookies and such, trying to clean up. However, while it deleted the cookies, it didn't delete the page itself, just closed it.

Browzar3

Notice here, later, I find the file in my IE Cache:

Browzar2

So, Browzar, at least this version, is totally not doing what it says it does. That's a bummer. Maybe next version.

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 twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

How to Programmatically Detect if an Assembly is Compiled in Debug or Release mode

August 30, '06 Comments [12] Posted in Programming
Sponsored By

Nagaraj from my company made this little util recently to run against a compiled assembly and see if it is a Debug or Release version. I added the DOS ErrorLevel return codes.

using System;

using System.IO;

using System.Diagnostics;

using System.Reflection;

 

namespace Foo.Tools

{

    class BuildFind

    {

        public static int GetBuildType(string AssemblyName)

        {

            Assembly assm = Assembly.LoadFrom(AssemblyName);

            object[] attributes = assm.GetCustomAttributes(typeof(DebuggableAttribute), false);

 

            if (attributes.Length == 0)

            {

                Console.WriteLine(String.Format("{0} is a RELEASE Build....", AssemblyName));

                return 0;

            }

            foreach (Attribute attr in attributes)

            {

                if (attr is DebuggableAttribute)

                {

                    DebuggableAttribute d = attr as DebuggableAttribute;

                    Console.WriteLine(
                       String.Format("Run time Optimizer is enabled : {0}", !d.IsJITOptimizerDisabled));

                    Console.WriteLine(
                        String.Format("Run time Tracking is enabled : {0}", d.IsJITTrackingEnabled));

                    if (d.IsJITOptimizerDisabled == true)

                    {

                        Console.WriteLine(String.Format("{0} is a DEBUG Build....", AssemblyName));

                        return 1;

                    }

                    else

                    {

                        Console.WriteLine(String.Format("{0} is a RELEASE Build....", AssemblyName));

                        return 0;

                    }

                }

            }

            return 3;

        }

 

        [STAThread]

        static int Main(string[] args)

        {

            if (args.Length == 0)

            {

                Console.WriteLine("Usage GetBuildType <assemblyName>");

                return 2;

            }

            return BuildFind.GetBuildType(args[0]);

        }

    }

}

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 twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

SOLVED: How to Force IIS to load a certain version of the .NET CLR

August 30, '06 Comments [4] Posted in ASP.NET | HttpModule | Web Services
Sponsored By

Micky McQuade turned me on to some code (from MSPSS) to solve my How to FORCE IIS to load a certain version of the CLR/.NET Framework. Greg Menounos also mentioned this solution in the comments.

PROBLEM: As discussed before, you can't use requiredRuntime or any .config changes (any that you ought to) to influence what version of the .NET Framework gets loaded into the IIS worker process. If you are using a .NET object as a COM object within Classic ASP, you'll always get the very latest .NET Framework installed on the machine. The values associated with the (fake) COM Object in the Registry are ignored. NOTE, this problem in with IIS/ASP/ASP.NET. If you're doing other things like calling .NET objects from VB6 Clients or something like that, you can always create a .exe.config and influence things with requiredRuntime like I talked about here.

SOLUTION: The solution is a clever hack. What's the first opportunity to "jump in" and affect IIS? When the ISAPI Filters are loaded. Which ISAPI Filter method is called only once? Why GetFilterVersion(), in fact.

This is one of those 'slap your forehead' solutions because it makes sense when you hear it, but it sounds SO tedious when you come up with it and have to actually sully your nails with C++ again. Sigh, I coded in C++ for 8 years and now not only have I forgotten my ninja skills but I feel slightly dirty when I'm back in there. 

DISCLAIMER: This code of course assumes that there isn't some other higher-priority ISAPI filter doing crazy stuff in .NET. Unlikely, but worth mentioning. It's also totally unsupported, and you didn't get it here. In fact, you don't know where you got it. Who is this? What are you doing here? Move along, nothing to see here! No warranty expressed or implied as I didn't write it. Don't bug Micky or ask MS about it.  There's also no guarantee that this, or anything like this, is a solution for your problem(s).

But it's interesting to read.

BOOL CNativeISAPIFilter::GetFilterVersion(PHTTP_FILTER_VERSION pVer)
{

    LPWSTR pszVer = L"v1.1.4322";

    //or "svr" if you're on a multiproc box and you want the server GC in this process.

    LPWSTR pszFlavor = L"wks";

    ICorRuntimeHost *pHost = NULL;

 

    HRESULT hr = CorBindToRuntimeEx(

        //version

        pszVer,

        // svr or wks

        pszFlavor,

        //domain-neutral"ness" and gc settings - see below.

        STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN | STARTUP_CONCURRENT_GC,

            CLSID_CorRuntimeHost,

        IID_ICorRuntimeHost,

        (void **)&pHost);

 

    // Call default implementation for initialization

    CHttpFilter::GetFilterVersion(pVer);

 

    // Clear the flags set by base class

    pVer->dwFlags &= ~SF_NOTIFY_ORDER_MASK;

 

    // Set the flags we are interested in

    pVer->dwFlags |= SF_NOTIFY_SECURE_PORT | SF_NOTIFY_NONSECURE_PORT |
          SF_NOTIFY_END_OF_NET_SESSION | SF_NOTIFY_END_OF_REQUEST;

 

    // Set Priority

    pVer->dwFlags |= SF_NOTIFY_ORDER_HIGH;

 

    // Load description string

    TCHAR sz[SF_MAX_FILTER_DESC_LEN+1];

 

    ISAPIVERIFY(::LoadString(AfxGetResourceHandle(),

    IDS_FILTER, sz, SF_MAX_FILTER_DESC_LEN));

    _tcscpy(pVer->lpszFilterDesc, sz);

 

    return TRUE;

}

File Attachment: NativeISAPI.zip (558 KB)

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 twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Good Exception Management Rules of Thumb

August 30, '06 Comments [13] Posted in ASP.NET | Learning .NET
Sponsored By

I was coming up with Good Exception Management Rules of Thumb for .NET. Here's what my brainstorming came up with. What do you have as good Rules o' Thumb?

  • Exceptions are exceptional and should be treated as such. If something exceptional, unusual, or generally "not supposed to ordinarily happen" then an exception is a reasonable thing to do.
    • You shouldn't throw exceptions for things that happen all the time. Then they'd be "ordinaries".
  • If your functions are named well, using verbs (actions) and nouns (stuff to take action on) then throw an exception if your method can't do what it says it can.
    • For example, SaveBook(). If it can't save the book - it can't do what it promised - then throw an exception. That might be for a number of reasons.
  • If you can, throw an exception that means something, and if there's an exception that already exists that matches what happened semantically, throw that.
    • Don't create a HanselmanException just because you're writing the Hanselman module unless you're adding data or valuable semantics to the type.
      If you are building a framework (or even if you're not) throw ArgumentExceptions and ArgumentNullExceptions liberally. Just as your method should throw if it can't do what it promised, it should throw if you supplied it with crap input.
  • If something horrible happens (something exceptional) then you need to decide if you can keep going.
    • Don't catch exceptions you can't do anything about. It's likely if you could do something about it, it wouldn't be exceptional, and you might consider calling TryParse, or File.Exists, or whatever it takes to prevent that exception.
  • There are reasons to swallow exceptions (catch (Exception ex)) but they are few and far between and they should be logged if appropriate and documented liberally.
    • Remember always if you do catch an exception and intend to rethrow it, then use throw; not throw ex; lest you lose your call stack and good bits of context.
  • Create a global error handler that logs everything.
    • A user shouldn't ever see an exception dialog or ASP.NET Yellow Screen of Death, but if they do, let them know that you've been notified.
    • {smartassembly} is an easy way to make this happen. So is ELMAH for ASP.NET. (I freakin' love ELMAH)
  • Yes Response.Redirect in ASP.NET causes an internal exception. Yes, it's a bummer, but there's a reason. It was an easy way to stop execution. If you don't like it, call its overload and stop page execution yourself. Personally, I don't sweat that one, but then I avoid Redirects, too.

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 twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Hanselminutes Podcast 31 - Test Driven Development

August 30, '06 Comments [4] Posted in NUnit | Podcast
Sponsored By

My thirty-first Podcast is up. This episode is about Test Driven Development.

We're listed in the iTunes Podcast Directory, so I encourage you to subscribe with a single click (two in Firefox) with the button below. For those of you on slower connections there are lo-fi and torrent-based versions as well.

Subscribe: Feed-icon-16x16 Subscribe to my Podcast in iTunes

This show was FULL of links, so here they are again. They are also always on the show site. Do also remember the archives are always up and they have PDF Transcripts, a little known feature.

Links from the Show

NUnit
NSPEC
TestDriven.NET
NCover
Fowler's Refactoring
MBUnit
NCover Explorer
Intro to TDD
Peli's original article on MBUnit
Guidelines for Test-Driven Development (Psyche!)
TDD Interview with Fowler
CSUnit
Unit Testing in .NET Projects
Resharper
Jay Flower's Doubler
Write Naive Test Code
RoyO - The Art of Unit Testing
Guidelines for Test-Driven Development
Apoorva Muralidhara Essay on TDD
Refactor! from DevExpress
Software Tester Team Center
Refactor Ruthlessly
CodeRush NUnit Templates

NEW COUPON CODE EXCLUSIVELY FOR HANSELMINUTES LISTENERS: The folks at XCeed are giving Hanselminutes listeners that is Coupon Code "hm-20-20." It'll work on their online shop or over the phone. This is an amazing deal, and I encourage you to check our their stuff. The coupon is good for 20% off any component or suite, with or without subscription, for 1 developer all the way up to a site license.

Our sponsors are XCeed, CodeSmith Tools, PeterBlum and the .NET Dev Journal. There's a $100 off CodeSmith coupon for Hanselminutes listeners - it's coupon code HM100. Spread the word, now's the time to buy.

As I've said before this show comes to you with the audio expertise and stewardship of Carl Franklin. The name comes from Travis Illig, but the goal of the show is simple. Avoid wasting the listener's time. (and make the commute less boring)

  • The basic MP3 feed is here, and the iPod friendly one is here. There's a number of other ways you can get it (streaming, straight download, etc) that are all up on the site just below the fold. I use iTunes, myself, to listen to most podcasts, but I also use FeedDemon and it's built in support.
  • Note that for now, because of bandwidth constraints, the feeds always have just the current show. If you want to get an old show (and because many Podcasting Clients aren't smart enough to not download the file more than once) you can always find them at http://www.hanselminutes.com.
  • I have, and will, also include the enclosures to this feed you're reading, so if you're already subscribed to ComputerZen and you're not interested in cluttering your life with another feed, you have the choice to get the 'cast as well.
  • If there's a topic you'd like to hear, perhaps one that is better spoken than presented on a blog, or a great tool you can't live without, contact me and I'll get it in the queue!

Enjoy. Who knows what'll happen in the next show?

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 twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

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