Scott Hanselman

Mapping a CVS user to a real user (SSPI to PSERVER)

April 7, '06 Comments [0] Posted in Subversion
Sponsored By

I recently moved a machine from our MAIN domain to a LAB domain (another domain with a hardened filewall for R&D and crazy stuff.)

We use Subversion for most of our Source Control, but a lot of legacy stuff is still in CVS and uses SSPI (Security Service Provider Interface enabling NTLM for CVS). So, when I do an update from Tortoise it automatically sends my Windows User details over there and authenticates me against the domain.

However, now I'd moved the machine and it was in another domain. The LAB domain is fairly harded and doesn't have a way for a MAIN domain user to login. Consequently updating CVS via SSPI is/was a problem.

I wrote a lame little batch file that's used like this:

addcvsuser.bat MYREPO labcvsuser

It looks like this:

IF "%1"=="" GOTO USAGE
IF "%2"=="" GOTO USAGE
SET CVSROOT=:sspi:MYCVSSERVERNAME:/%1
cvs passwd -a -r MAIN\somewindowsuser %2
SET CVSROOT=
GOTO EXIT
:USAGE
ECHO Usage: addcvsuser REPOSITORY NEWUSERNAME
:EXIT

Assuming the admin is logged in as a legit user, this file temporarily sets the CVSROOT Environment Variable with the name of the Repository you want to add a user to. The user will be added to the passwd file in that repository and won't be a real Windows User. It might be a user named labcvsuser that doesn't exist on the domain. That user is mapped to MYCVSSERVERNAME\somewindowsuser that IS a real Windows User, on the real MAIN domain.

Then, in Tortoise I change the CVSROOT used by Tortoise to :pserver: instead of :sspi: and open up ports 2401 and 2402. Now the LAB TortoiseCVS can use a username/password combo that's not on the domain and get mapped to a domain (or local) user and crisis averted.

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

IBM Laptop Wireless Adapter Turns Off Automatically Without Asking

April 7, '06 Comments [8] Posted in Musings
Sponsored By

IBMSoftwareInstallerI updated all the IBM (Lenovo) ThinkPad Craplets with the IBM Virus Software Installer this week. Mistake.

My wireless adapter started turning off every 3 minutes. Not losing signal, not disabling, TURNING OFF. The internal hardware would switch off.

Global SettingsWindows was/is set up to manage the Wireless Connection, but it seems that the IBM Access Connections (their view of networking) still influences things. Kind of a wireless "shadow government."

Automatic Location SwitchingI don't see this documented anywhere, but I figured out that you have to run the Access Connections and go to Configure|Automatic Location Switching and TURN OFF "Enable automatic location switching." You also have to go Configure|Global Settings and TURN OFF "Enable automatic wireless LAN radio control."

And all is well. Today.

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

Coloring Windows Folders with Custom Icons

April 7, '06 Comments [5] Posted in Musings
Sponsored By

FolderIcons1Cool DOTNET Code PropertiesRecently folks were pointing to iColorFolder, a freeware application that "let's you add some color to your folders." I think it's cool that this guy wrote an application do this, but the funtionality is built into Windows.

Just right-click on the folder you want to mess with, select Properties, the the Customize Tab. Select "Change Icon" and set the folder icon.

Here's my zip file of collected folder icons.

File Attachment: foldericons.zip (113 KB)

This is what happens in the hidden Desktop.ini file when you do this:

[.ShellClassInfo]
IconFile=%SystemDrive%\icons\Snow.ico
IconIndex=0

I may be the utils guy, but if I can avoid loading something, I will. I figure this fellow's iColorFolder application just edits the desktop.ini of the folder anyway.

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

Debugging the ASP.NET worker process running at 100%

April 6, '06 Comments [5] Posted in ASP.NET | XML | Bugs
Sponsored By

Aspdebug1A co-worker stopped by this week with a strange problem in one of our Web Applications. Sometimes I'm Chief Debugger more than Chief Architect, but I enjoy the forensics.

He found that when developing one of our web sites, the ASP.NET worker process on his machine would hang at around 100%. He'd made a few changes and couldn't check in until he figured out what was up.

Aspdebug2I installed Process Explorer and right-clicked on the worker process and went to the Threads Tab (a darned useful tab). It said that ReleaseFusionInterfaces was doing all the work. (I don't know the internals of the CLR to know what it's doing. Fusion is the Assembly Loader and I know what Release does. ;) I suspect that Suzanne Cook might know.) It seemed to me at this point that work WAS being done, but we were in an infinite or very long running loop.

Aspdebug3We tried selecting Debug | Break from Visual Studio.NET, but the IDE became confused and dropped into the editor with the instruction pointer (represented by a the selected yellow line) ending up inside of an XML Comment. It was totally confused.

When you select the Call Stack from the Debug Windows Menu, code that (basically) you didn't write will be marked as <Non-User Code> and hidden/collapsed within the stack view, as seen in the screenshot to the right.

As with almost all things within Windows, right-click will set you free. Right-click on everything. If you right-click within the Call-Stack Window you can select "show non-user code." and you'll see the full stack. (This is one of many places that the IDE tries to make things easier by "lying" to you. Another is the DebuggerStepThrough Attribute.)

In the final screenshot with the non-user code visible within the stack, you can see that we're stuck on RegexInterpreter.Go(). It's very possible to create Regular Expressions that will run until the Sun burns out. It may seem like we're stuck in a loop, and perhaps this Regex would have eventually finished at some point, but of course it really needs to take just a few milliseconds.

Aspdebug4We have a layer on top of ResourceManager.GetString() that is called GetStringMacro(). Some resources might have references to other resources, using a custom "macro" format we developered. A resource might be: "For assistance call [PhoneNumber]" where PhoneNumber is another resource that we'll need to resolve with another call to GetString. The regular expression pulls the stuff embedded within []'s out.

If you look at the last sceenshot at the first/top black line, you'll notice that the string literal being passed into ParseMacroString is missing the final ] bracket. Apparently our regular expression REALLY didn't like the lack of symmetry in this string. We'll need to fix the RegEx to be more robust, but for this problem, as soon as we fixed the string, everything worked and the RegEx executed in milliseconds again.

Now playing: Rent - Goodbye Love

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

Ruby as Cross Platform Monad

April 5, '06 Comments [4] Posted in PowerShell | Ruby | Watir
Sponsored By

Ted Neward and Glenn Vanderburg are having lines-of-code measuring contest between Ruby and Monad (MSH). They've taken Lee Holmes' clever Encarta Answers script and Glenn's written it in Ruby.

Ted says:

"...notice how we're making use of the vast power underneath the .NET framework to lay out a pretty straightforward use of the code, in a way that's entirely dynamic and loosely-typed, including the assumed return value from the if/else block, and so on."

Using Ted's own words against him, Glenn says:

[when considering lines of code/syntactic tokens]...Ruby is clearly the winner.
Ruby: 17 lines, 76 tokens
Monad: 37 lines, 217 tokens

Personally, I'm Switzerland in this argument. Learn them both, you'll be a better person. I know .NET better so the Monad version makes more sense to me.

One thing I would suggest that Glenn do, if he really wants to get into some fun, is take a good hard look at John Lam's RubyCLR. Sure, there've been some cursory attempts at bridging the CLR and Ruby before as well as current work to get Ruby code compiling to IL. However, for the Windows world at least, Ruby's success on our platform will be (I predict) measured by two things:

  • Watir - A Ruby Interop layer on top of IE (and now Firefox with FireWatir)
  • John's RubyCLR - I'm convinced that John is doing the whole world a service with this bridge.

RubyCLR is elegant in that it doesn't attempt something so lofty (or perhaps ultimately tilting at windmills) as compiling Ruby to IL. Instead it does what Watir did - it opens another whole world to the already great Ruby interpreter. Will there be a Ruby/Mono bridge? There should be, and then Glenn would have something to smack Ted over the head with as then the IRB (Ruby Interactive Shell) starts looking like cross-platform Monad.

Me? I don't care, I'll just run them both in a Tabbed Console like the Console Project at SF.NET.
(Note the screen shot above, it's the Console Demo 15 drop. Support this project!)

UPDATE: Lee Holmes has retorted brilliantly with a rewrite of the original get-answer script. Here's his rewrite along with the ruby version.

param([string] $question = $(throw "Please ask a question."))

[void] [Reflection.Assembly]::LoadWithPartialName("System.Web")
$webClient = new-object System.Net.WebClient

$text =  $webClient.DownloadString("http://search.msn.com/encarta/results.aspx
q=$([Web.HttpUtility]::UrlEncode($question))")

if($text -match "<div id=`"results`">(.+?)</div></div><h2>Results</h2>")
{
   $partialText = $matches[1]
   $partialText = $partialText -replace "<\s*a.*?>.+?</a>", ""
   $partialText = $partialText -replace "</(div|span)>", "`n"
   $partialText = $partialText -replace "<[^>]*>", ""
   $partialText = ($partialText -replace "`n`n","`n").TrimEnd()
   $partialText
}
else
{
  "No answer found."
}

And the Ruby version...

#!/usr/bin/env ruby

require 'open-uri'
require 'cgi'

fail "Please ask a question." unless ARGV.size > 0
question = ARGV.join(" ")
query = "
http://search.msn.com/encarta/results.aspx
?q=#{CGI::escape(question
)}"
page = URI(query).read or fail "Couldn't get response."

puts

if page =~ %r{<div id="results">(.+?)</div></div><h2>Results</h2>}
  response = $1
  response.gsub! %r{<\s*a.*?>.+?</a>}, ""  # remove links
  response.gsub! %r{</(div|span)>}, "\n"  # insert newlines
  response.gsub! %r{<.*?>}, ""  # remove tags
  puts response.squeeze("\n").rstrip  # collapse adjacent newlines and trim whitespace
else
  puts "No answer found."
end

Clearly Lines of Code is a ridiculous metric to measure just about anything, and this is more proof that both Ruby and Monad kick the llama's ass.

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.