Monday, June 12, 2006

Announcing msdnman

When Kim, Tim, and I were working on MSDN2 - or more accurately, the Microsoft/Technet Publishing System (MTPS), the system behind MSDN2 - way back when, we always had in mind that it was important to create a system where the content could be leveraged in ways other than to power the MSDN2 website. And we did - every time you hit F1 in Visual Studio 2005, you're accessing the MTPS system. Now that the MTPS Content Service is publicly available, we expect other applications of the data to start popping up.


To get the ball rolling, and because we always thought it would be cool, I've written the first one. I call it msdnman, and users of *nix systems should find it fairly familiar: it's written as an analog of the man command. The idea is to provide command-line access to the MTPS content. I'm a big command-line guy myself, so I really like the concept.


For now, I've posted the binaries and source here. I'm working on getting it shoved over to SourceForge, but there are a few administrative hurdles to clear first, so it might take me a few weeks.


Because I wrote this in my spare time over a couple of days, it's still a bit rough. But it's still pretty servicable for those times where you don't want to fire up a browser, and I think it makes a reasonable demonstration of how to use the web service, too.


It's pretty straightfoward to use. Simply grab the binaries and run something like


msdnman System.Xml.XmlReader


in a console window, and you should see something like this:


msdnman screenshot


There are a bunch of options that you can specify, too. You can get a list of them by running


msdnman -?


but briefly, you'll generally either do this:




or this


msdnman -k KEYWORD


where IDENTIFIER identifies some content item in the MTPS system. See here for more information, but usually this will be the name of the namespace, class, method you're looking up, like System.Xml.XmlReader or System.Security.Cryptography.


The "-k" option is a nifty little add-on that I did (at the request of John Mollman - this is your blog, right?), which does a keyword search against the MSDN content. So you can do


msdnman -k web.config


to get back a list of links having something to do with web.config.


I implemented the search part by wiring up to the same web service that Visual Studio 2005 uses, as the MTPS web service does not currently support search.


So download and enjoy, and let me know if you have any ideas for how to improve it.


  1. Awesome, awesome, awesome. Exactly what we CLI-Heads need. Thanks!

    The only thing I would throw in if I had a mind to improve it would be a "head" switch, allowing display of only n lines returned.

    Thanks again,


  2. Sean: have you checked out the docs on the MSDNMAN_PAGER environment variable? If specified, it'll automatically pipe the output through the pager of your choice. That would let you stop at (say) one screenful. There's also MSDNMAN_LANG, which you can set to (say) C# to only see C# declarations and examples.

  3. I love the idea, but it seems it would be useful if it could fall back on en-us whenever there is no content available in the user's UI language. Alternatively, have an environment variable for the -loc argument.

    Being on a Norwegian version of XP, it seems I will have to provide the -loc argument for every invocation (and Powershell isn't all that happy about arguments containing hyphens...).

  4. That's a pretty easy fix. I'll see if I can't find a few minutes to roll it in this week. In the meantime, might I suggest just hardcoding it in your copy? Source is available after all.

    Either way - thanks for the suggestion. It's something I've been meaning to do anyway, and I can see where it would quickly get annoying.

    BTW, you can use a slash or a hyphen for any argument.

  5. > That's a pretty easy fix. I'll see if I can't find a few minutes to roll it in this week.

    Great. I think this is pretty much a must for people that aren't on en-us boxes. First time I tried it I thought the tool didn't work at all.

    > In the meantime, might I suggest just hardcoding it in your copy? Source is available after all.

    I just did that - works beautifully :-)

    > BTW, you can use a slash or a hyphen for any argument.

    Well, it's not the - in -loc that's giving me problems, it's the one in "en-us". Seems somehow Powershell's command line parsing has trouble with that. Only way I could get it to work was by doing $loc="en-us";msdnman -loc $loc System.String

    Now, what would be even more neat is if someone wrote a Powershell commandlet on top of msdnman that gave you an object graph as output... ;-)

  6. You're not the first one to ask for a commandlet. :) But I think there's essentially no chance of me doing one unless I win the lottery. However, I open-sourced the thing for several reasons, and this is one of them...

  7. I did not think it was possible. So much so that I thought "man" for MSDN was a new cartoon character to represent the MSDN library!

    Nevertheless this is a great tool for those of us who use the command line in development.

    If you have MSDN installed already, why does the MSDN2 final URN differ from the local URN

    For example: Chr, ChrW functions



    Or the real question is, will the MSDN subscription be made compatible with MSDN online and eventually carry the same URNs? In this way you could use the MSDNMAN with a local service if you do not have access to the Internet.

  8. The reason the two URLs differ is that MSDN2 was a rewrite of the content system at MSDN, and one of the big things we fixed was the URL scheme. The chm version of MSDN doesn't get generated from that system right now.

    The problem you'd run into with trying to run against the local content is that it's not XHTML. We had to do a lot of scrubbing to get the XHTML even as clean as it is. A lot. Running a transform against straight HTML would be painful.

    But you never know - maybe someone will get inspired and pull it off. Failing that, the web service would allow you to write a scraper that would pull all the content you care about into a local cache. I don't think I'll implement anything like this, but someone might.

  9. Craig Andera has been working with my team on a set of web services exposing MSDN2 content hosted by...

  10. On May 19, 2003, I said "I have always admired Mike's ability to look at the world out there and put...


  11. Two pretty cool MSDN related tools:


    A very nifty command line utility for accessing MSDN2...

  12. Se, come me, avete l'allergia ai tempi di risposta dell'help di Visual Studio e del sito di MSDN, non...

  13. I happened upon this post from Craig Andera announcing a handly utility - msdnman.  Like man...

  14. A few Microsoft-related news items of interest that occurred over the past week: The stories of Bill


  15. 'msdnman CreateProcess'

    'msdnman -k CreateProcess' indicates that the desired link is the #1 ranked item.

    Is there a way to ask msdnman to just present the #1 ranked item?

  16. Not in the release bits, but I just checked in a change contributed by someone else that adds a -results switch, whereby you can say "I only want n results". And the default is now 10 rather than 100.

    You can grab the source off of CodePlex if you want, or wait until I release a new binary drop (something like a week or so, I think).

  17. Adam: I see I misunderstood your question. The answer is still 'no', however the part about it being addressed in the recent change is not true.

    I've considered adding this feature - I'll write it down and see about including it. It's a bit complicated because the search service and the MTPS service don't know anything about each other, and consequently you're not always going to be able to retrieve the topic that the search returns as #1.


  18. I'm not sure I understand this... the successful queries used as examples do work where as CreateProcess does those just happen to match exactly with topics?

    so was msdn2 done on contract to msft? <it wasn't clear originally whether you were msft or not, i gather not>

  19. The problem is that CreateProcess is not defined in MTPS as an alias for any topic. Had you used System.Diagnostics.Process.CreateProcess (the namespace-qualified name) it would work fine.

    MSDN2 was indeed done on contract to MSFT, as were the MTPS Content Services. I'm not a MSFT employee, and never have been. I work for myself.

  20. A few Microsoft-related news items of interest that occurred over the past week: The stories of Bill