tools

April 17, 2025 tools

How to Write Actionable Bug Reports

How to Write Actionable Bug Reports

I often find myself maintaining open source projects. I’ve contributed to many over the years, even hosting multi-person source available” projects on this very website in zip files before there were such things as GitHub or Pull Requests or Open Source Software. No matter what mechanism I’m using to manage the project, if it’s popular, I get issues filed against that project. Those issues break down into two categories:

  1. Feature Requests
  2. Bug Reports

Feature Requests: Include Why

If it’s a feature request, I’ll ask that you include why you’re asking for a feature as well as what you’re asking for. It’s pretty typical for an engineer to have a problem, wish for a particular solution and then ask for it. However, it’s often the case that someone using the project doesn’t quite have the entire architecture in mind when they ask for a solution, which means that the requested solution might not fit in well with the rest of the project.

On the other hand, if you can include why you’re asking for a specific solution, i.e. what problem are you trying to solve, then the maintainer of the project can say no, but…” with an alternative solution that does fit in with the architecture.

A good maintainer will ask why before saying no, but if you provide the why out of the gate, you could save yourself a round trip in the issue’s comments.

Bug Reports: Include a Minimal Repo Project

If the project in question does something that you thought the project should already do but it doesn’t work the way you expect, e.g. sets fire to your garage, then that’s a bug report. For a bug report to be useful, it has to be actionable.

More sophisticated projects will include a template that asks pertinent questions like:

  • What behavior did you see?
  • What behavior did you expect to see?
  • What error message did you get?

However, for me, the biggest thing that makes a bug report actionable is the inclusion of a minimal reproduction project. Each one of the words in that phrase is important and we’ll go through them back to front:

  • Project: I’m looking for the code for an entire project, ideally in a zip file, that I can download, unzip, load up into my IDE, resolve dependencies and run. The project should have everything in there that I need or, if there is something I need to add, like an API key, there should be a clear and prominent comment that makes that clear.

    In a pinch, I’ll take a single source code file where the rest of the project is implied, but it needs to be self-contained and complete.

    The goal is that I can take your code and run it with no muss or fuss. The more popular the project I’m working on is, the more bug reports I’m going to get and the less time I have to spend on each one. Please make it quick and easy for me to run the code that demonstrates your issue, which brings me to…

  • Reproduction: The code you send me should reproduce your issue! And it should put it in my face loud and proud. If it’s an intermittent problem and I can’t get it to happen with a reasonable number of runs, then there’s not a lot I can do to fix it. The goal is to make it clear what the issue is and if it’s not, I’m going to have to drop a comment into the conversation and move on.

  • Minimal: Please please please do not copy and paste your personal or — even worse — your company’s proprietary code into a project issue. I don’t want to see that stuff! And there’s often so so much of it! I want you to spend time removing anything domain-specific and trimming out the code that does not contribute to the problem. I do this for several reasons:

    1. I don’t want your lawyers suing me for someday building something that is similar to something you once posted in a bug on one of my projects.
    2. I want you to have done the legwork to verify that the problem is in my code and not yours. If you trim away the extraneous, then you’ll either figure out that it’s your problem or mine.
    3. If the problem is mine, your minimal repro project is going to make it clear to me that it is my problem, because you’ve cleared away everything that isn’t contributing to the issue. And this helps me to fix it more quickly.

Just One Example

As an example, I saw a bug report recently on the Flutter AI Toolkit, a project I’m working on with the Flutter team. A very nice person posted an issue which seemed like a bug to me, if it’s true, so I wanted to get to work on it right away. However, the bug wasn’t actionable because it didn’t have a minimal repro project, so I posted a comment asking for one.

The person responded quickly with a repro project, but I suspected that it was not minimal because it had domain-specific details in it and there were style settings used. The style settings were a dead giveaway because the issue had nothing to do with look n’ feel. So I asked the person to work on the minimal” part of the minimal reproduction project” and moved on to my next task.

And then they got back to me with a minimal repro project so I could get to work on their issue.

Where Are We?

I am a huge fan of people reporting issues in my projects. Every one of them is an opportunity to make it more useful for a wider set of people, which is why I enjoy working on OSS projects in the first place. If you don’t post issues that are actionable, that’s OK — I’ll ask for the info I need. But if you’d like to move things along a little bit more quickly for yourself, you work put yourself in the maintainer’s shoes and provide the same info you’d need if you were going to fix the issue yourself.

Or, even better, consider a PR. : )

February 29, 2012 tools win8 telerik

What’s New in the Beta Metro/JS Templates for VS11

What’s New in the Beta Metro/JS Templates for VS11

The Consumer Preview of Windows 8 (aka the Win8 beta) is now available for download, along with the matching Visual Studio 11 beta. You can download them both from the Developer Center for Metro style Apps and at least when I did the downloading this morning, it was smooth and worked well. In case you’re interested, I downloaded the ISO, not the setup, and I am currently writing this blog entry in Windows Live Writer running inside a WMWare Workstation 8.0 virtual machine running on the Windows 7 host OS running inside Boot Camp on my MacBook Pro. As someone said to me this morning: That’s a lot of VMs!” Maybe so, but the Win8 and VS11 betas are running surprisingly well inside of my Inception-box.

Metro/JS Templates for VS11 in BUILD

If you played around with the Metro/JS templates in VS11 from the BUILD conference in September, you’ll have noticed that the generated apps were compliant with the Windows 8 UX style guidelines, but that two of the templates — Grip and Split — generated large amounts of code. That’s because these are pretty much the biggest apps that Microsoft has ever shipped as templates. They each have multiples pages and they work hard at being simple but feature complete Metro style apps.

However, as well as the BUILD templates implemented the Win8 UX, their code wasn’t the greatest, for the following reasons:

  • The templates were attempting to codify best practices for a brand-new app model. That’s always going to take time to get right.
  • There was only so much time to get it right before BUILD — it was either have great code or implement a great UX, so the template team chose the latter.
  • The bonehead PM in charge at the time (me) decided it was a better choice to push the data model into each page instead of centralizing it. That was a bad idea.
  • The data model, spread as it was across nearly every JS file in the templates, was assumed to be static. However, the vast majority of apps get their data dynamically from some external source and the template-generated code made that very hard to implement.
  • There were a number of features that the templates needed that didn’t exist directly in the platform, either in WinJS, the IE DOM or in the WinRT libraries, so the templates needed to provide those features.

All of these reasons meant that the functionality of the generate Grid and Split apps made for an instructional start to building your own Metro style apps, assuming you were willing to wade through a great deal of code. The new templates in the Win8 beta solve nearly all of these problems.

Get-VS-11-BetaMetro/JS Templates for VS11 Beta

Out of the box, the Metro/JS templates in the VS11 beta (made available today, Feb 29, 2012), get more betterer as they get more complex.Let’s start simple and work our way up.

image

Blank Application

The Blank Application template is almost the smallest Metro/JS app you can build, except that it includes a reference to the Microsoft Windows Library for JavaScript (aka WinJS):

image

And to be clear, this is a brand new feature. Including WinJS as a reference instead of dropping the code into each project means that MS can shipped a single shared implementation instead of every app in the store duplicating the code. If you want to duplicate the code into your project, you can do so, but you’ll also have to update the URL references to the JS and CSS files from your HTML files, like this snippet from the generated default.html:

default.html
  1. <link href=“//Microsoft.WinJS.0.6/css/ui-dark.css” rel=“stylesheet”>
  2. <script src=“//Microsoft.WinJS.0.6/js/base.js”></script>
  3. <script src=“//Microsoft.WinJS.0.6/js/ui.js”></script>

In addition to the new syntax with the leading double-slashes, that the number of WinJS files to include is a far smaller number in the Beta. Now it’s just base.js and ui.js, which makes it easy to decide which one(s) you want and in what order to include them, fixing a common problem in the BUILD bits.

One other thing that’s new in the Blank Application template is that there are stubs for implementing tomb-stoning to easily save and restore your app’s session state in the default.js:

default.js
  1. var app = WinJS.Application;
  2.  
  3. app.onactivated = function (eventObject) {
  4.     if (eventObject.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
  5.         if (eventObject.detail.previousExecutionState !== Windows.ApplicationModel.Activation.ApplicationExecutionState.terminated) {
  6.             // TODO: This application has been newly launched. Initialize
  7.             // your application here.
  8.         } else {
  9.             // TODO: This application has been reactivated from suspension.
  10.             // Restore application state here.
  11.         }
  12.         WinJS.UI.processAll();
  13.     }
  14. };
  15.  
  16. app.oncheckpoint = function (eventObject) {
  17.     // TODO: This application is about to be suspended. Save any state
  18.     // that needs to persist across suspensions here. You might use the
  19.     // WinJS.Application.sessionState object, which is automatically
  20.     // saved and restored across suspension. If you need to complete an
  21.     // asynchronous operation before your application is suspended, call
  22.     // eventObject.setPromise().
  23. };

The handling of the terminated state in the onactivated event on line 3 and the checkpoint event handler on like 16 are for reactivating and saving your app state respectively.

And finally, the handy TODO comments are something you’ll find sprinkled throughout the templates based on usability feedback conducted to determine what developers really need help with as they add their own functionality to the app.

Fixed Layout Application

Moving up the complexity scale, the Fixed Layout Application template is meant to do just what it says — provide a jumping off point for apps that are logically fixed layout. The crux of this code is the use of the ViewBox control in the default.html:

default.html
  1. <body>
  2.     <div data-win-control=“WinJS.UI.ViewBox”>
  3.         <div class=“fixedlayout”>
  4.             <p>Content goes here</p>
  5.         </div>
  6.     </div>
  7. </body>

Line 2 wraps the content of the app in a ViewBox control, which will scale everything inside of it to the size of the content, which is defined in the default.css file with the fixedLayout style:

default.css
  1. .fixedlayout {
  2.     -ms-grid-columns: 1fr;
  3.     -ms-grid-rows: 1fr;
  4.     display: -ms-grid;
  5.     height: 768px;
  6.     width: 1024px;
  7. }

You’ll see in lines 5 and 6 that the height and width of the div contained in the ViewBox is 768x1024, which means that the content can be created using absolute positioning and sizing. The job of the ViewBox is as the app is resized, either the computer’s resolution changes or more likely the app is moved between landscape, portrait, split and full sizes, the ViewBox will scale the content to take up as much room as possible, keeping the aspect ratio constant and scaling the content such that the app itself can think of itself as logically 768x1024 (or whatever the top-level div’s size is). This is very handy for building things like casual games where you want scaling, but generally not flowing — you want to control where the Scrabble tiles are or the tic-tac-toe pieces and it’s much easier to do that with a fixed size.

And now that I’ve described it, I’ll tell you that this template is the only one that’s structurally identical between BUILD and Beta. Still, it is useful.

Navigation Application

The next one up the ladder is the Navigation Application template, which is where we get the Back button and the support for moving HTML fragments into and out of the DOM just like the user was logically navigation page-to-page. In the BUILD bits, this navigation functionality was packaged in the default.js file, but in the Beta, default.js is just the same as the simpler templates. Instead, the navigation functionality is packaged into a new file: navigator.js. The reason this file is separate is to make it clear if you’d like to implement a different navigation policy, e.g. MVC, then this is the file to start with. Further, while this functionality would seem a shoe-in to be included in WinJS, it’s not quite baked” enough, which means that MS hasn’t yet decided that this is the way” to do navigation.

Still, it’s a way” to do navigation in a Metro/JS app and a pretty useful one. Essential the way it works is that there is a singleton PageControlNavigator in the default.html file that holds the pages as they’re swapped in. The default.html is also where navigator.js is included:

default.html
  1. <script src=“/js/navigator.js”></script>
  2. <div id=“contenthost” data-win-control=“Application7.PageControlNavigator” data-win-options=“{home: /html/homePage.html’}“></div>

The navigator.js file defines the PageControlNavigator control, which holds the logical pages as the user clicks around in the application. The home parameter is where to start the navigation. Navigation is to a Page, which is really a mapping between an HTML file and a set of events to handle over the lifetime of that Page:

homePage.js
  1. // This function is called whenever a user navigates to this page. It
  2. // populates the page elements with the app’s data.
  3. function ready(element, options) {
  4.     // TODO: Initialize the fragment here.
  5. }
  6.  
  7. WinJS.UI.Pages.define(/html/homePage.html”, {
  8.     ready: ready
  9. });

Of course, navigating to the home page is going to be rare compared to navigating between pages. The easiest way to get a new page to add to your app is to right-click on your project in the Solution Explorer and select Add | New Item:

image

The last item three item templates on the list are for shell contract implementations, which are beyond the scope of this blog post, but the first one is a Page Control, which gives us a triad of HTML, JS and CSS that fits exactly into the navigation model provided by the PageControlNavigator control:

page2.html
  1. DOCTYPE html>
  2. <html>
  3. <head>
  4.     <meta charset=“utf-8”>
  5.     <title>page2</title>
  6.  
  7.    
  8.     <link href=“//Microsoft.WinJS.0.6/css/ui-dark.css” rel=“stylesheet”>
  9.     <script src=“//Microsoft.WinJS.0.6/js/base.js”></script>
  10.     <script src=“//Microsoft.WinJS.0.6/js/ui.js”></script>
  11.    
  12.     <link href=“page2.css” rel=“stylesheet”>
  13.     <script src=“page2.js”></script>
  14. </head>
  15. <body>
  16.     <div class=“page2 fragment”>
  17.         <header aria-label=“Header content” role=“banner”>
  18.             <button class=“win-backbutton” aria-label=“Back” disabled></button>
  19.             <h1 class=“titlearea win-type-ellipsis”>
  20.                 <span class=“pagetitle”>Welcome to page2</span>
  21.             </h1>
  22.         </header>
  23.         <section aria-label=“Main content” role=“main”>
  24.             <p>Content goes here.</p>
  25.         </section>
  26.     </div>
  27. </body>
  28. </html>

 

page2.cs
  1. .page2 p {
  2.     margin-left: 120px;
  3. }

 

page2.js
  1. // This function is called whenever a user navigates to this page. It
  2. // populates the page elements with the app’s data.
  3. function ready(element, options) {
  4.     // TODO: Initialize the fragment here.
  5. }
  6.  
  7. function updateLayout(element, viewState) {
  8.     // TODO: Respond to changes in viewState.
  9. }
  10.  
  11. WinJS.UI.Pages.define(/page2.html”, {
  12.     ready: ready,
  13.     updateLayout: updateLayout
  14. });

Navigating to this new control defined by these files is a simple matter of calling the navigate method:

homePage.html
  1. <a onclick=“WinJS.Navigation.navigate(‘/page2.html’)“>Page 2</a>

As far as the user is concerned, the anchor tag shows up as a link like any other:

image

Clicking on Page 2” fires the onclick event, which calls the navigate method, passing in the path to the HTML file and causes the Page control defined in page2.html, page2.js and page2.css to be loaded:

image 

In addition to whatever content on your Page control, notice that the Back button shows up automatically. The Back button manages navigation via clicking, touching and the browser keys; Ctrl+Left Arrow and Ctrl+Right Arrow work as Back and Forward respectively.

Grid and Split Application

At this point, we’ve covered almost all of the core concepts that make up the Grid and Split applications: they bring in WinJS by reference, they use controls and they use navigation via the Page controls. In fact, even though the Grid app has three pages and the Split app has two, they’re really just the navigation template with the pages to implement the Grid and Split app patterns that MS decided were the major app patterns appropriate for Win8. However, the Grid and Split application templates do have two major features that the other templates don’t have: support for multiple view states and a centralized data model.

Multiple view state support means that as the app is moved between portrait, landscape, full and split, the app adjusts itself to look good in all states. The view state management is mostly handled with CSS styles associated with media modes, like in the Split App’s itemsPage.css:

itemsPage.css
  1. @media screen and (-ms-view-state: snapped) {
  2.     .itemspage .itemslist .win-vertical.win-viewport .win-surface {
  3.         margin-bottom: 30px;
  4.     }

In Metro/JS apps, MS has provided a media query predicate called -ms-view-state, which can be one of the four view states and the styles in the media query block will be applied when the app moves to that state. In addition, if you want to handle the view state change in JS, you can do so with updateLayout event in your Page control, like this snippet from itemsPage.js:

itemsPage.js
  1. // This function updates the page layout in response to viewState changes.
  2. updateLayout: function (element, viewState) {
  3.     var listView = element.querySelector(″.itemslist”).winControl;
  4.     if (viewState === Windows.UI.ViewManagement.ApplicationViewState.snapped) {
  5.         listView.layout = new ui.ListLayout();
  6.     } else {
  7.         listView.layout = new ui.GridLayout();
  8.     }
  9. }

In this case, the updateLayout event is called when the control is initially created and as the app moves through the view states so it can change the layout style for the ListView control showing the contents of the page:

imageimage

Landscape vs. Snapped view state layout for the itemsPage ListView control

The other major feature of the Grid and Split app templates — and this feature is new in the Beta bits — is the centralized data model, which is where the data for all pages comes from. This data model is defined in data.js and it contains the static group and item data as you just saw. The core of the data is exposed from data.js like so:

data.js
  1. WinJS.Namespace.define(data”, {
  2.     items: groupedItems,
  3.     groups: groupedItems.groups,
  4.     getItemsFromGroup: getItemsFromGroup
  5. });

These three members of the data object are used throughout the templates, e.g. in the itemsPage.js ready event handler:

itemsPage.js
  1. // This function is called whenever a user navigates to this page. It
  2. // populates the page elements with the app’s data.
  3. ready: function (element, options) {
  4.     var listView = element.querySelector(″.itemslist”).winControl;
  5.     ui.setOptions(listView, {
  6.         itemDataSource: data.groups.dataSource,
  7.         itemTemplate: element.querySelector(″.itemtemplate”),
  8.         oniteminvoked: this.itemInvoked.bind(this),
  9.     });
  10.     this.updateLayout(element, Windows.UI.ViewManagement.ApplicationView.value);
  11. },

Notice that the data.groups property is used on line 6 to perform a data binding operation. That data binding is against the dataSource property of the object returned from data.groups, which itself is created by a method on the WinJS.Binding.List object that holds the grouped item data. It’s this binding list, a new feature in WinJS for the Beta, that makes it easy to move from the static data provided by the templates and dynamic data that your app defines.

The binding list is a binding data source, which means that as you add items to it, it notifies any control that happens to be bound to it. This is especially handy when your app starts up with zero data, but you need to initialize the ListViews such that as the data is available (perhaps from an asynchronous network call), it will be shown.

If you open up the data.js, you’ll see the static sample data:

static sample data
  1. // Each of these sample groups must have a unique key to be displayed
  2. // separately.
  3. var sampleGroups = [
  4.     { key: group1”, title: Group Title: 1”, subtitle: Group Subtitle: 1”, backgroundImage: darkGray, description: groupDescription },
  5.    
  6. ];
  7.  
  8. // Each of these sample items should have a reference to a particular
  9. // group.
  10. var sampleItems = [
  11.     { group: sampleGroups[0], title: Item Title: 1”, subtitle: Item Subtitle: 1”, description: itemDescription, content: itemContent, backgroundImage: lightGray },
  12.    
  13. ];

The group data has a unique key, a title, a subtitle, a background image and a description, which are all fields that the data templates used in the Split and Grid apps depend upon (although you can change them if you like). The item data has a reference to the group to which it belongs, a title, a subtitle, a description, a background image and the content for the item itself.

The code that populates the binding list with the sample data looks like this:

statically bound data
  1. var list = new WinJS.Binding.List();
  2. var groupedItems = list.createGrouped(groupKeySelector, groupDataSelector);
  3.  
  4. // TODO: Replace the data with your real data.
  5. // You can add data from asynchronous sources whenever it becomes available.
  6. sampleItems.forEach(function (item) {
  7.     list.push(item);
  8. });

As the comment makes clear, it’s this code you’re most likely to want to change. Instead of pulling in static data from the sampleItems array, we want to pull the items in asynchronously, perhaps from an RSS feed or two just like my earlier post:

dynamically bound data
  1. var list = new WinJS.Binding.List();
  2. var groupedItems = list.createGrouped(groupKeySelector, groupDataSelector);
  3.  
  4. // RSS feeds
  5. var feeds = [
  6.     { key: feed1”, title: Scott Hanselman”, subtitle: a blog”, backgroundImage: darkGray, description: a blog”, url: http://feeds.feedburner.com/ScottHanselman” },
  7.  
  8.     { key: feed2”, title: Raymond Chen”, subtitle: a blog”, backgroundImage: lightGray, description: a blog”, url: http://blogs.msdn.com/b/oldnewthing/rss.aspx” },
  9.  
  10.     { key: feed3”, title: Chris Sells”, subtitle: a blog”, backgroundImage: mediumGray, description: a blog”, url: http://sellsbrothers.com/posts/?format=rss” },
  11. ];
  12.  
  13. feeds.forEach(function (feed) {
  14.     WinJS.xhr({ url: feed.url }).then(function (request) { processPosts(feed, request); });
  15. });
  16.  
  17. function processPosts(feed, request) {
  18.     // parse the RSS
  19.     var nodes = request.responseXML.selectNodes(//item”);
  20.     for (var i = 0, len = nodes.length; i < len; i++) {
  21.         var node = nodes[i];
  22.         var item = {
  23.             group: feed,
  24.             title: node.selectNodes(title”)[0].text,
  25.             subtitle: node.selectNodes(pubDate”)[0].text,
  26.             description: a post”,
  27.             content: node.selectNodes(description”)[0].text,
  28.             backgroundImage: feed.backgroundImage
  29.         };
  30.         list.push(item);
  31.     }
  32. }

In this case, our group data is a set of RSS feeds, being careful to continue to use the same group field names so I don’t have to update the data templates in the rest of the app. When the app loads, I still create a binding list, but instead of filling it directly, I start an async xhr call (the WinJS XMLHttpRequest wrapper) for each feed, creating an item for each RSS post I find upon a successful completion. Because I’ve left the data model alone and because I’m using the binding list, that’s all I have to change and now the entire app has been updated to support that data:

image

The items page with the set of feeds in the Split app template

image

The split page with the posts from the selected feed

Where Are We?

As you can see, the Metro/JS templates in the VS11 beta start simple and add features with navigation, pages with specific app pattern functionality, multiple view state support and a unified data model. The main difference is the Beta versions of this templates is that code has been simplified, beautified and pushed into WinJS as much as possible to make the inside of your app just as pretty and easy to use as the outside.

Translation

This article has been translated into Serbo-Croatian by Jovana Milutinovich. Enjoy.

December 27, 2011 spout tools

GUI REPL for Roslyn

GUI REPL for Roslyn

If you recall from REPL for the Rosyln CTP 10/2011, I’ve been playing around building a little C# REPL app using Roslyn. That version was built as a Console application, but I’ve refactored and rebuilt it as a WPF application:

image

You can download the source code for both the Console and the WPF versions here:

RoslynRepl Sample Download

The benefit of a real GUI app is that output selection makes a lot more sense and that you could imagine real data visualization into data controls instead of just into strings. However, implementing a REPL shell in a GUI environment requires doing things considerably differently than in a Console app. Besides the stupid things I did, like doing a lot of Console.Write, and things that don’t make sense, like #exit or #prompt, there are a few interesting things that I did with this code, including handling partial submissions, rethinking history and rewiring Console.Write (just cuz it’s stupid when I do it doesn’t mean that it shouldn’t work).

Partial Submissions

In this REPL, I decided that Enter means execute” or newline” depending on whether the submission is complete enough, according to Roslyn, to execute or not. If it is, I execute it, produce the output and move focus to either the next or a new submission TextBox. If the submission isn’t yet complete, e.g. void SayHi() {”, then I just put in a newline. Further, I do some work to work properly with selections, i.e. if you press Enter when there’s a selection, the selection will be replaced with the Enter key.

So far I like this model a lot, since I don’t have to something like separate execute” and newline” into Enter and Alt+Enter or some such.

Rethinking History

In a GUI shell with partial submissions and multi-line editing, the arrows are important editing keys, so can’t be used for access to previous lines in history. Further, a GUI apps makes it very easy to simply scroll to the command that you want via the mouse or Shift+Tab, so there’s not a lot of use for Alt+Arrow keys. Pressing Enter again replaces the old output (or error) with new output (or error):

imageimage

Currently when you re-execute a command from history, the command stays where it is in the history sequence, but it could as easily move to the end. I haven’t yet decided which I like better.

Redirecting Console.Write

Since this is a REPL environment works and acts like a shell, I expect that Console.Write (and it’s cousins like Console.WriteLine) to work. However, to make that work, I need to redirect standard output:

Console.SetOut(new ReplHostTextWriter(host));

The ReplTextWriterClass simply forwards the text onto the host:

class ReplHostTextWriter : TextWriter {
  readonly IReplHost host;

public ReplHostTextWriter(IReplHost host) { this.host = host; } public override void Write(char value) { host.Write(value.ToString()); } public override Encoding Encoding { get { return Encoding.Default; } } }

The hosts implementation of IReplHost.Write simply forwards it onto the currently executing submission (the ReplSubmissionControl represents both a submission’s input and output bundled together). You’ll notice that the TextWriter takes each character one at a time. It would be nice to do some buffering for efficiency, but you’d also like the output to appear as its produced, so I opted out of buffering.

However, one thing I don’t like is the extra newline at the end of most string output. I want the main window to decide how things are output, setting margins and the newline looks like a wacky margin, so the trailing CR/LF had to go. That’s an interesting algorithm to implement, however, since the characters come in one at a time and not line-by-line. I want separating newlines to appear, just not trailing newlines. I implement this policy with the TrimmedStringBuilder class:

// Output a stream of strings with \r\n pairs potentially spread across strings,
// trimming the trailing \r and \r\n to avoid the output containing the extra spacing.
class TrimmedStringBuilder {
  readonly StringBuilder sb;

  public TrimmedStringBuilder(string s = "") {
    sb = new StringBuilder(s);
  }

  public void Clear() {
    sb.Clear();
  }

  public void Append(string s) {
    sb.Append(s);
  }

  public override string ToString() {
    int len = sb.Length;

    if (len >= 1 && sb[len - 1] == '\r') {
      len -= 1;
    }
    else if (len >= 2 && sb[len - 2] == '\r' && sb[len - 1] == '\n') {
      len -= 2;
    }

    return sb.ToString(0, len);
  }
}

Usage inside the ReplSubmissionControl.Write method is like so:

public partial class ReplSubmissionControl : UserControl {
...
  TrimmedStringBuilder trimmedOutput = new TrimmedStringBuilder();

  public void Write(string s) {
    if (s == null) { trimmedOutput.Clear(); }
    else { trimmedOutput.Append(s); }

    consoleContainer.Content = GetTextControl(trimmedOutput.ToString());
  }
}

Now, as the input comes in one character at a time, the trailing newlines are removed but separating newlines are kept. Also, you may be interested to know that the GetTextControl function builds a new read-only TextBox control on the fly to host the string content. This is so that the text can be selected, which isn’t possible when you set the content directly.

Right now, there’s no support for Console.Read, since I don’t really know how I want that to happen yet. Pop-up a dialog box? Something else?

Completions, Syntax Highlighting and Auto-indent

I was a few hundred lines into implementing completions using Roslyn with the help of the Roslyn team when I realized two things:

  1. Implementing completions to mimic the VS editor is hard.
  2. Completions aren’t enough — I really want an entire C# editor with completions, syntax highlighting and auto-indentation.

Maybe a future release of Roslyn will fix one or both of these issues, but for now, both are out of scope for my little REPL project.

December 14, 2011 spout tools data

Moving My Data To The Cloud: Stormy Weather

Moving My Data To The Cloud: Stormy Weather

For years, I’ve maintained a single main” computer. It was the computer that was the central authority of all of the personal data I’d accumulated over the years and from which it made me uncomfortable to be separated. Because I needed a single computer for everything, it had to work on my couch, on a plane, on a desk and everywhere else I ever needed to go. Also, it couldn’t have a giant monitor or multiple monitors, because it had to go everywhere. All of this was because I needed all of my data with me all of the time.

My process for moving to a new computer used to include a lot of manual copying of files from the old D hard drive (D is for Data) to my new hard drive, which was also carefully partitioned into C for Windows, Office, Visual Studio, etc. and D for a lifetime of books and articles, coding projects and utilities I’ve collected over the years, e.g. LinqPad, Reflector, WinMerge, etc. This is 30GB of stuff I wanted access to at all times. I was also backing up via Windows Home Server, keeping photos and music on the WHS box (another 30GB), then backing that up to the cloud via KeepVault. And finally, as I upgraded HDs to go bigger or go to solid state, I kept each old HD around as another redundant backup.

All of that gave me some confidence that I was actually keeping my data safe right up until my Windows Home Server crashed the system HD and I found out that the redundancy of WHS doesn’t quite work the way you’d like (this was before I installed KeepVault). This was a first generation HP Home Server box and when it went down, I took it apart so I could attach a monitor, keyboard and mouse to diagnose it, pulled the HDs out so I could read what files I could and ultimately had to drop it off in Redmond with the WHS team so I could get it up and running again.

There are some files I never got back.

KeepVault gave me back some of the confidence I’d had before WHS crashed, but they didn’t provide me a way to see what files they were backing up, so I didn’t have the transparency I wanted to be confident. Further, they don’t have clients on every kind of platform like Dropbox does.

Of course, simply sync’ing files isn’t enough — sync’ing my 10GB Outlook PST file every time I got a new email was not a good way to share 20 years of contacts, email and calendar items.

The trick is to sync each kind of data in the right way, be confident that it’s safe and have access to it across the various platforms I use: Windows, Windows Phone 7, iOS and possibly Android (you know, if I feel like walking on the wild side!). And since I’m currently under employed (my new gig doesn’t start till the new year), I figured I’d do it once and do it right. I almost got there.

Files

Let’s start easy: files. Dropbox has made this a no-brainer. You install the software on any platform you care to use, drop everything you want into the folder and it just works, keeping files in sync on the cloud and across platforms, giving you adequate (although not great) status as it does so. Most platforms are supported natively, but even on platforms that aren’t, there are often alternative clients, e.g. I’m using Boxfiles for Windows Phone 7. When I gave up my Microsoft laptop, instead of doing the dance of the copy fairy to my new Mac Book Air, I installed Dropbox on both computers, dropped everything I want backed up and sync’d between computers into the Dropbox folder. 36 hours and 30GB later, all of it was copied into the cloud and onto my new laptop, at which point I reformatted my Microsoft laptop and handed it into my boss.

Further, as a replacement for WHS and KeepVault, I now keep all of the files that I was keeping just on my WHS server — photos and music primarily — into Dropbox.

image

This keeps me the confidence I need to know that my files are safe and backed up to the cloud, while making it very easy to keep it backed up locally by simply running Dropbox on more than one computer at my house. If at any time, I don’t want those files on any one computer, I tell Dropbox to stop sync’ing those folders, delete the local cache and I’m all done.

There are two tricks that I used to really make Dropbox sing for me. The first is to change my life: I no longer partition my HDs into C and D. The reason I’d always done that was so that I could repave my C with a fresh Windows, Office and VS install every six months w/o having to recopy all my data. Windows 7 makes this largely unnecessary anyway (bit rot is way down on Win7), but now it doesn’t matter — I can blow any computer away at will now, knowing that Dropbox has my back. In fact, Dropbox is my new D drive, but it’s better than that because it’s dynamic. The C drive is my one pool of space instead of having to guess ahead of time how to split the space between C and D.

The other thing I did was embrace my previous life: I wanted to keep D:\ at my fingertips as my logical Data” drive. Luckily, Windows provides the subst” command to do just that. Further, ntwind software provides the fabulous VSubst utility to do the mapping and keep it between reboots:

image

Now, I’ve got all the convenience of a dedicated data” drive backed up to the cloud and sync’d between computers. Because I needed 60GB to start, I’m paying $200/year to Dropbox for their 100GB plan. This is more expensive than I’d like, but worth it to me for the data I’m storing.

There is a hitch in this story, however. Right now on Dropbox, data and metadata is available to Dropbox employees and therefore to anyone that hacks Dropbox (like the government). I don’t like that and for my very most sensitive data, I keep it off of Dropbox. When Dropbox employees themselves aren’t able to read Dropbox data or metadata, then I’ll move the sensitive data there, too.

Music

I’m not actually very happy with how I’m storing music. I can play all my music on any PC, but I can only play it one song at a time on my WP7 because there’s no Dropbox music client. I could use the Amazon cloud drive that provides unlimited music storage for $20/year, but there’s no WP7 client for that, either. Or I could spend $100/year on Amazon and get my 100GB of storage, but their client isn’t as widely available as Dropbox. Ironically, Dropbox is using Amazon as their backend, so hopefully increased pressure in this space will drop Dropbox’s prices over time.

Photos

I’m not using Facebook or Flicr for my photos simply because I’m lazy. It’s very easy to copy a bunch of files into Dropbox and have the sync’ing just happen. I don’t want to futz with the Facebook and Flickr web interfaces for 15GB worth of photos. Right now, this is the digital equivalent of a shoebox full of 8x10s, but at least I’ve got it all if the house burns down.

imageNotes and Tasklist

For general, freeform notes, I moved away from Evernote when they took the search hotkey away on the Windows client (no Ctrl+F? really?) and went to OneNote. The web client sucks, but it’s better than nothing and the Windows and WP7 clients rock. I have a few notes pinned to my WP7 home screen that I use for groceries, tasks, etc., and I have all of my favorite recipes in there, too, along with my relatives’ wi-fi passwords that they don’t remember themselves, a recording of my son snoring, etc. It’s a fabulous way to keep track of random data across platforms.

On the task list side, I only sorta use OneNote for that. I also send myself emails and write little TODO.txt files every time I get a little bee in my bonnet. I’ve never found that the Exchange tasks sync well enough between platforms to invest in them. Maybe someday.

imageMail, Contacts and Calendar

And speaking of Exchange, that’s a piece of software that Microsoft spoiled me on thoroughly. This is sync that works very well for contacts, emails and calendar items. IMAP does email folders, but server implementations are spotty. For years, I used Exchange for my personal contacts and calendar, only keeping my personal email separate in a giant PST file, pulling it down via POP3. This can sorta be made to work, but what I really wanted was hosted Exchange.

However, what I found cost between $5 and $11 a month per user. I’d probably have gone with Office 365 for sellsbrothers.com mail, even at $5/month except for two reasons. The first is that Microsoft requires you to move your entire DNS record to them, not just the MX record, which means there is all kinds of hassle getting sellsbrothers.com working again. They do this so that they can get all of the DNS records working easily for Lync, Sharepoint, etc., but I don’t want those things, so it’s just a PITA for me. If they change this, I’d probably move except for the other problem: I’m not the only user on sellsbrothers.com.

For years to be the big shot at family gatherings, I’ve been offering up permanent, free email addresses on my domain. That’s all well and good, but now to maintain my geek cred, I need to keep my mom, my step-mom, my brother, my sons, etc., in an email server that works and one that they don’t have to pay for. So, while I was willing to pay $5/month for hosted exchange for me, I wasn’t willing to pay it for my relatives, too!

One option I tried was asking securewebs.com (my rocking ISP!) to upgrade to SmarterMail 8.x, but that didn’t work. I even footed the one-time fee of $200 for the ActiveSync support for SmarterMail, but I couldn’t make that sync from Outlook on the desktop or the phone either.

Eventually I made an imperfect solution work: Hotmail. The nice thing about Hotmail is that it’s free for 25GB (yay webmail storage wars!) and it syncs contacts, mail and calendar items just like I want. Further, with some effort (vague error messages are not useful!), I was able to get Hotmail to pull in my personal email. And, after installing the Outlook Hotmail Connector (explicitly necessary because my Windows Live ID is not a @live.com or an @hotmail.com email address), I was able to sync almost everything, including the folders I copied from my giant PST file, via hotmail to both my desktop and phone Outlook. However, there are a few downsides:

  • There is an intrinsic delay between when someone sends me an email and when it syncs to any device because Hotmail is polling via POP3. This polling is annoying and sometimes sends me directly to the web mail frontend where I can interact with my personal email directly.
  • The Outlook Hotmail Connector sync’ing progress indication is terrible in that it seems to stack every time I press F9 (a bad habit from years of POP3 usage) and I can’t tell what it’s working or or when it will finish. Because of this, I’ve trimmed the set of email folders I sync to the ones I really use, using the PST file as an archive for days gone by.
  • Hotmail does the right thing with the Reply To”, but sometimes weird @hotmail addresses with random characters shows up in email threads, which breaks the fourth wall. That’s annoying.
  • My RSS Folders don’t sync to my phone, which is a shame because I really loved having my Hacker News folder pinned to my WP7 home page letting me know where there were new items. None of the RSS readers on WP7 seem to work as well as a simple pinned email folder.

The good news is that this all works for free and my relatives continue to have working email. The bad news is that it doesn’t work nearly as well as the Exchange server I’m used to. Hopefully I will be able to revisit this in the future and get it working correctly.

imagePC Games

I purchase all of my games via Steam now and install them as the mood strikes me. I love being able to reinstall Half-Life 2 or Portal on demand, then blow it away again when I need the hard drive space. Steam is the only viable app store for Windows right now, although I am looking forward to have the Microsoft app store in Windows 8.

imageBackups

I no longer maintain backups” in the sense that I can slap in a new HD, boot from a USB stick and have my computer restored in 30 minutes or less (that never worked between WHS and Dell laptops anyway). I’ve had HD problems, of course, but they’re so rare that I no longer care about that scenario. Instead, what I do is keep all of the software that I normally install on a file server (the new job of my WHS box). If the file server goes down, then most of the software I install, i.e. Windows 7, Office and Visual Studio, is available for download via an MSDN Subscription. The rest is easily available from the internet (including Telerik tools and controls!) and I just install it as I need it.

Where Are We?

In order to free myself from any specific PC, I needed to pick a new centralized authority for my data: the cloud. The experience I was after for my PCs was the same one I already have on my phone — if I lose it, I can easily buy a new one, install the apps on demand and connect to the data I already had in Exchange, Hotmail, Skydrive, etc. Now that I’ve moved the rest of my world to Dropbox, I can treat my PCs and tablets like phones, i.e. easily replaceable. It’s not a perfect experience yet, but it’s leaps and bounds ahead of where it was even a few years ago.

Hardware and software comes and goes; data is forever.

November 26, 2011 tools .net

REPL for the Rosyln CTP 10/2011

REPL for the Rosyln CTP 10/2011

I don’t know what it is, but I’ve long been fascinated with using the C# syntax as a command line execution environment. It could be that PowerShell doesn’t do it for me (I’ve seriously tried half a dozen times or more). It could be that while LINQPad comes really close, I still don’t have enough control over the parsing to really make it work for my day-to-day command line activities. Or it may be that my friend Tim Ewald has always challenged csells to sell C shells by the sea shore.

Roslyn REPL

Whatever it is, I decided to spend my holiday time futzing with the Roslyn 2011 CTP, which is a set of technologies from Microsoft that gives you an API over your C# and VB.NET code.

Why do I care? Well, there are all kinds of cool code analysis and refactoring tools I could build with it and I know some folks are doing just that. In fact, at the BUILD conference, Anders showed off a Paste as VB command built with Roslyn that would translate C# to VB slick as you please.

For me, however, the first thing I wanted was a C# REPL environment (Read-Evaluate-Print-Loop). Of course, Roslyn ships out of the box with a REPL tool that you can get to with the View | Other Windows | C# Interactive Window inside Visual Studio 2010. In that code, you can evaluate code like the following:

> 1+1 2
> void SayHi() { Console.WriteLine("hi"); }
> SayHi();
hi

Just like modern dynamic languages, as you type your C# and press Enter, it’s executed immediately, even allowing you to drop things like semi-colons or even calls to WriteLine to get output (notice the first 1+1” expression). This is a wonderful environment in which to experiment with C# interactively, but just like LINQPad, it was a closed environment; the source was not provided!

The Roslyn team does provide a great number of wonderful samples (check the Microsoft Codename Roslyn CTP - October 2011” folder in your Documents folder after installation). One in particular, called BadPainting, provides a text box for inputting C# that’s executed to add elements to a painting.

But that wasn’t enough for me; I wanted at least a Console-based command line REPL like the cool Python, JavaScript and Ruby kids have. And so, with the help of the Roslyn team (it pays to have friends in low places), I built one:

RoslynRepl Sample Download

Building it (after installing Visual Studio 2010, Visual Studio 2010 SP1, the Visual Studio 2010 SDK and the Roslyn CTP) and running it lets you do the same things that the VS REPL gives you:

RoslynRepl

In implementing my little RoslynRepl tool, I tried to stay as faithful to the VS REPL as possible, including the help implementation:

replhelp

If you’re familiar with the VS REPL commands, you’ll notice that I’ve trimmed the Console version a little as appropriate, most notably the #prompt command, which only has inline” mode (there is no margin” in a Console window). Other than that, I’ve built the Console version of REPL for Roslyn such that it works just exactly like the one documented in the Roslyn Walkthrough: Executing Code in the Interactive Window.

Building a REPL for any language is, at you might imagine, a 4-step process:

  1. Read input from the user
  2. Evaluate the input
  3. Print the results
  4. Loop around to do it again until told otherwise

Read

Step 1 is a simple Console.ReadLine. Further, the wonder and beauty of a Windows Console application is that you get complete Up/Down Arrow history, line editing and even obscure commands like F7, which brings up a list of commands in the history:

replbeauty

The reading part of our REPL is easy and has nothing to do with Roslyn. It’s evaluation where things get interesting.

Eval

Before we can start evaluating commands, we have to initialize the scripting engine and set up a session so that as we build up context over time, e.g. defining variables and functions, that context is available to future lines of script:

using Roslyn.Compilers;
using Roslyn.Compilers.CSharp;
using Roslyn.Compilers.Common;
using Roslyn.Scripting;
using Roslyn.Scripting.CSharp;
...
// Initialize the engine
string[] defaultReferences = new string[] { "System", ... }; string[] defaultNamespaces = new string[] { "System", ... }; CommonScriptEngine engine = new ScriptEngine(defaultReferences, defaultNamespaces);
// HACK: work around a known issue where namespaces aren't visible inside functions
foreach (string nm in defaultNamespaces) {
  engine.Execute("using " + nm + ";", session);
}

Session session = Session.Create();

Here we’re creating a ScriptEngine object from the Roslyn.Scripting.CSharp namespace, although I’m assigning it to the base CommonScriptEngine class which can hold a script engine of any language. As part of construction, I pass in the same set of assembly references and namespaces that a default Console application has out of the box and that the VS REPL uses as well. There’s also a small hack to fix a known issue where namespaces aren’t visible during function definitions, but I expect that will be unnecessary in future drops of Roslyn.

Once I’ve got the engine to do the parsing and executing, I creating a Session object to keep context. Now we’re all set to read a line of input and evaluate it:

ParseOptions interactiveOptions =
new ParseOptions(kind: SourceCodeKind.Interactive,
languageVersion: LanguageVersion.CSharp6);
... while (true) { Console.Write("> "); var input = new StringBuilder(); while (true) { string line = Console.ReadLine(); if (string.IsNullOrWhiteSpace(line)) { continue; } // Handle #commands ... // Handle C# (include #define and other directives) input.AppendLine(line); // Check for complete submission if (Syntax.IsCompleteSubmission(
SyntaxTree.ParseCompilationUnit(
input.ToString(), options: interactiveOptions))) {
break;
}
Console.Write(". "); } Execute(input.ToString()); }

The only thing we’re doing that’s at all fancy here is collecting input over multiple lines. This allows you to enter commands over multiple lines:

replmultiline

The IsCompleteSubmission function is the thing that checks whether the script engine will have enough to figure out what the user meant or whether you need to collect more. We do this with a ParseOptions object optimized for interactive” mode, as opposed to script” mode (reading scripts from files) or regular” mode (reading fully formed source code from files). The interactive” mode lets us do things like 1+1” or x” where x” is some known identifier without requiring a call to Console.WriteLine or even a trailing semi-colon, which seems like the right thing to do in a REPL program.

Once we have a complete command, single or multi-line, we can execute it:

public void Execute(string s) {
  try {
    Submission<object> submission = engine.CompileSubmission<object>(s, session);
    object result = submission.Execute();
    bool hasValue;
    ITypeSymbol resultType = submission.Compilation.GetSubmissionResultType(out hasValue);

    // Print the results
    ...
  }
  catch (CompilationErrorException e) {
    Error(e.Diagnostics.Select(d => d.ToString()).ToArray());
  }
  catch (Exception e) {
    Error(e.ToString());
  }
}

Execution is a matter of creating a submission,” which is a unit of work done by the engine against the session. There are helper methods that make this easier, but we care about the output details so that we can implement our REPL session.

Print

Printing the output depends on the type of a result we get back:

ObjectFormatter formatter =
new ObjectFormatter(maxLineLength: Console.BufferWidth, memberIndentation: " ");
...
Submission
<object> submission = engine.CompileSubmission<object>(s, session); object result = submission.Execute(); bool hasValue; ITypeSymbol resultType =
submission.Compilation.GetSubmissionResultType(out hasValue); // Print the results if (hasValue) { if (resultType != null && resultType.SpecialType == SpecialType.System_Void) { Console.WriteLine(formatter.VoidDisplayString); } else { Console.WriteLine(formatter.FormatObject(result)); } }

As part of the result output, we’re leaning on an instance of an object formatter” which can trim things for us to the appropriate length and, if necessary, indent multi-line object output.

In the case that there’s an error, we grab the exception information and turn it red:

void Error(params string[] errors) {
  var oldColor = Console.ForegroundColor;
  Console.ForegroundColor = ConsoleColor.Red;
  WriteLine(errors);
  Console.ForegroundColor = oldColor;
}
public void Write(params object[] objects) {
  foreach (var o in objects) { Console.Write(o.ToString()); }
}

void WriteLine(params object[] objects) {
  Write(objects);
  Write("\r\n");
}

replerror

Loop

And then we do it all over again until the program is stopped with the #exit command (Ctrl+Z, Enter works, too).

Where Are We?

Executing lines of C# code, the hardest part of building a C# REPL, has become incredibly easy with Roslyn. The engine does the parsing, the session keeps the context and the submission gives you extra information about the results. To learn more about scripting in Roslyn, I recommend the following resources:

Now I’m off to add Intellisense support. Wish me luck!

December 11, 2010 tools

Using LINQPad to Run My Life: Budgeting

Using LINQPad to Run My Life: Budgeting

I use LINQPad all the time for a bunch of stuff, but most recently and most relevant, I’ve been using it for a personal chore that isn’t developer-related: I’ve been using it to do budgeting.

What is LINQPad?

LINQPad is an interactive execution environment for LINQ queries, statements or programs. The typical usage model is that you point LINQPad at a SQL database or an OData endpoint via a dialog box and then start writing queries against the tables/collections exposed by that connection, e.g.

clip_image002

Here, you can see that I’ve added a connection on the left to the Northwind database, typed a query into the text box (I paid the $25 for the auto-completion module), executed the query and got the table of results below. If I want to operator over multiple results, including dumping them for inspection, I can do so by switch from C# Expression to C# Statements:

clip_image004

Notice the use of Dump” to see results along the way. If I want to, I can switch to C# Program, which gives me a main and allows me to create my own types and methods, all of which can be executed dynamically.

To save queries, notice the My Queries” tab in the lower left. I use this for things I run periodically, like the ads on my web site that are going to expire, some data cleanup I want to get back to and, the subject of today: budgeting.

Budgeting with Mint.com and LINQPad

For the uninitiated, mint.com is a free online personal financial management site. At its core, it uses financial account, loan and asset information that lets it log into various financial sites and grab my data for me, e.g. 1sttech.com, usbank.com, wcb.com, etc. It uses this to let me categorize transactions so that it can do budgeting for me. However, it doesn’t give me the control I want, so I write programs against this unified transaction information. Essentially, I re-categorize each transaction to my own set using a map I maintain in an Excel file, then compare the amount I spend each month against what my budget amount is, maintained in another sheet in that same Excel file. Because mint.com doesn’t provide a programmatic API (OData would be a godsend!), I pull down my transaction history as a CSV file that the web site provides for me, which I then translate to an Excel file.

Once I have these three Excel sheets, the translation history, the category map and the category budget amounts, I bring these pieces of data into my LINQPad script:

void Main() {
    var mintExcel = ExcelProvider.Create(@"D:\data\finances\2010-08-25 mint transactions.xlsx");
    var minDate = new DateTime(2010, 8, 1);
    var txs = mintExcel.GetSheet<Tx>().Where(t=>t.Date>=minDate);
    var debits = txs.Where(tx => tx.Type == "debit");

    var classExcel = ExcelProvider.Create(@"d:\data\finances\2010-08-03 mint category map.xlsx");
    var map = classExcel.GetSheet<CategoryClass>().ToList();
    var classBudget = classExcel.GetSheet<ClassBudget>().ToList();
    var unclassified = new ClassBudget() { Class = "UNCLASSIFIED" };
    classBudget.Add(unclassified);
    var classifiedDebits = debits.
      Select(d => new { d.Date, d.Description, Amount = d.Amount, d.Category, Class = GetClass(map, d) }).
      Where(d => d.Class != null);
    
    // TODO: break this down by month
    // TODO: sum this by ytd
    var classifiedTotals =
        from d in classifiedDebits
        group d by d.Class into g
        let b = classBudget.FirstOrDefault(b=>b.Class == g.Key) ?? unclassified
        let total = g.Sum(d=>d.Amount)
        select new {
            Class = b.Class,
            BudgetAmount = b.Amount,
            ActualAmount = total,
            AmountLeft = b.Amount - total,
            TxCount = g.Count(),
            Transactions = from tx in g.OrderBy(tx=>tx.Date)
                select new { Date = tx.Date.ToString("M/d/yy"), tx.Description, tx.Category, tx.Amount }
        };
    classifiedTotals.OrderBy(d=>d.Class).Dump(2);
    //classifiedTotals.OrderBy(d=>d.Class).Dump();
}

static string GetClass(List<CategoryClass> map, Tx tx) {
  CategoryClass cc = map.FirstOrDefault(m => m.Category == tx.Category);
  if( cc != null ) { return cc.Class; }
  tx.Category.Dump("UNCLASSIFIED MINT CATEGORY");
  return null;
}

[ExcelSheet(Name = "transactions(1)")]
public class Tx {
    [ExcelColumn()] public DateTime Date { get; set; }
    [ExcelColumn()] public string Description { get; set; }
    [ExcelColumn()] public decimal Amount { get; set; }
    [ExcelColumn(Name = "Transaction Type")] public string Type { get; set; }
    [ExcelColumn()] public string Category { get; set; }
    [ExcelColumn(Name = "Account Name")] public string AccountName { get; set; }
}

[ExcelSheet(Name = "Sheet1")]
public class CategoryClass {
    [ExcelColumn()] public string Category { get; set; }
    [ExcelColumn(Name="Classification")] public string Class { get; set; }
}

[ExcelSheet(Name = "Sheet2")]
public class ClassBudget {
    [ExcelColumn(Name="Classification")] public string Class { get; set; }
    [ExcelColumn()] public decimal Amount { get; set; }
    public int Transactions { get; set; }
}

There are some interesting things to notice about this script:

  • I needed to make it a full-fledged program so that I could define the shape of my data in Excel. LINQPad has no native support for Excel data, so I had modify an Excel LINQ provider I found on the interwebtubes. The types are needed to map the Excel columns to C# types so that I can query against them.
  • This script isn’t pretty; it’s been built up over time and it works. I’ve been using it for a month and this month my task is to split it work across multiple months.
  • I’ve built up error output over time to make sure I’m not dropping data in my queries. I spent an hour a coupla weeks ago tracking down 3 transactions.
  • I’m doing slow look-ups cuz at the time I wrote this script, I wasn’t sure how to write joins in LINQ. It’s more than fast enough for my needs, so I’ve only dug into LINQ for accuracy, not efficiency.

LINQPad Output

By default, the output from my budgeting program looks like this (w/ my personal financial details blacked out):

clip_image006

Some things to notice:

  • The output is spit into a table w/o me having to do anything except dump the data.
  • The number columns have an automatic bar graph glyph on them that shows proportions when clicked.
  • The number columns are automatically totally.
  • The Transactions column is turned off because I said Dump(2)”, which only dumps to the 2nd level. By default it would drill down further, e.g.

clip_image008

Bringing in Excel

To bring my Excel data into LINQPad, which supports LINQ to SQL, EF and OData natively but not Excel, I have to right-click on the design surface, choose query properties and tell it about where the source code and namespace is that defines the Excel LINQ Query Provider:

image

image

Impressions

The thing that makes this app really work for me is the REPL nature. It’s very immediate and I can see where my money is going with very little ceremony. It’s really the intelligence of the Dump command that keeps me from moving this app to WPF. Dump gives me the view I need to understand where my money goes and it gives me the programming surface to slice/dice the data the way I want to. I have no control out of the box in WPF that’s even close to as useful.

However, Even though I could extend LINQPad myself, there is no integrated support for Excel or CSV files. Further, for some stupid reason, I have to load the files into a running instance of Excel for them to load in LINQPad, which pisses me off because the error messages are ridiculous. Also, there is no intrinsic support for multiple data sources; instead I need to build that myself.

Further, I had one case where I couldn’t figure out an error (it was that I forgot to load the data into Excel) and had to have a real debugger, which LINQPad didn’t have. The good news was that I was able to copy/paste my code into a console application and debug it, but the bad news was that I really missed the Dump command when I was running inside Visual Studio.

Where Are We?

I really love LINQPad. In fact, I find myself wanting the same functionality for other uses, e.g. SQL (real SQL), JavaScript and as a shell. It’s the interactive data access that makes it for me — munge some data, look at it, repeat. It doesn’t quite do everything I want, though — where’s the full-featured, all-data, Swiss army knife for data?

October 27, 2010 tools

LINQ Has Changed Me

In the old days, the post-colonial, pre-LINQ days of yore, I’d have written a one-way MD5 encryption like so:

static string GetMD5String(string s) {
  MD5 md5 = new MD5CryptoServiceProvider();
  byte[] hash = md5.ComputeHash(Encoding.ASCII.GetBytes(s));
  StringBuilder sb = new StringBuilder();
  foreach( byte b in hash ) sb.AppendFormat("{0:x2}", b);
  return sb.ToString();
}

This implementation is fine and has served me well for 10 years (I pulled it out of the first .NET project I ever really did). However, after using LINQ for so long, it’s hard not to see every problem as an operation over sets:

static string GetMD5String(string s) { 
  return (new MD5CryptoServiceProvider()). 
    ComputeHash(Encoding.Unicode.GetBytes(s)). 
    Aggregate(new StringBuilder(), (working, b) => working.AppendFormat("{0:x2}", b)). 
    ToString(); 
} 

I can’t say that the LINQ version is any better, but it felt better. However, you’ll notice that I’m not using any of the LINQ keywords, e.g. select”, where”, etc. I find that I don’t really use them that much. It’s too jarring to mix them, e.g. (from f in foos select f).Take(3)”, since not everything has a LINQ keyword equivalent. I tend to do LINQ-less LINQ more often then not.

P.S. I assume someone will be able to tell me how I can do it better. : )

P.P.S. I’m using the Insert Code for Windows Live Writer add-in. I love WLW!

September 27, 2010 tools

Time to check the donuts

Time to check the donuts

One day when I was supposed to be writing, I needed something to do (as often happens). In this particular case, I built a little tray icon app using the new (at the time) tray icon support in Windows Forms (this was a while ago : ). The data I was checking was my gmail account and whenever there was new mail, I’d pop up a notification. All very simple, so to be funny, instead of saying “You’ve got mail,“� my program said I’s time to check the donuts.”

Over time, I came to rely on this app but lamented the lack of features, like seeing who the email was from or marking an email as read w/o logging in, etc. Over time, I came to wish I had something like Gmail Notifier. I’s free and while it doesn’t contain an ’80s commercial reference, it has way more features than I ever built into mine. Oh, and the noise it makes when you get an email is priceless. Recommended.

March 27, 2010 tools

Updated the CsvFileTester for Jet 4.0

I was playing around building a tool to let me edit a database table in Excel, so I updated my CvsFileTester project to work in a modern world, including the 32-bit only Jet 4.0 driver you’ve probably go lying around on your HD.

Enjoy.

February 9, 2010 tools

Entity Designer Database Generation Power Pack

If you like Model-First design in Entity Framework, you’re going to love the Entity Designer Database Generation Power Pack. The original Database Generation feature in the Entity Designer in VS 2010 is extensible via Windows Workflows and T4 Templates. This Power Pack builds on these extensibility mechanisms and introduces the following:
  • Basic Table-per-Hierarchy support. This is represented by the Generate T-SQL via T4 (TPH)” workflow.
  • The SSDL and MSL generation pieces can now be tweaked through T4 templates, both in TPH and TPT strategies through the Generate T-SQL via T4 (TPT)” and Generate T-SQL via T4 (TPH)” workflows.
  • Direct deployment and data/schema migration are available through the Generate Migration T-SQL and Deploy” workflow. This workflow will use the Team System Data APIs to diff our default T-SQL script against the target database and create a new script which will perform non-invasive ALTERs and data migration where necessary.
  • A new user interface will now display when Generate Database from Model” is selected — this acts as a workflow manager” which will present to you our default workflows and allow you to create your own, customizable workflows based on your own strategy, script generation, and deployment requirements.

Highly recommended. Enjoy!

December 15, 2009 tools

LINQPad updated to support Data Services!

Joe Albahari, the author of LINQPad, has added support for WCF Data Services to the 1.37.1 version beta of LINQPad. This means that you can point LINQPad at any Open Data (OData) endpoint and do queries interactively just like any other LINQ data source. He even supports HTTP security, in case the endpoint in question requires it. Further, if you have your own custom LINQ to Whatever and you’d like to plug a connection to it into LINQPad, Joe has already added the ability to create a custom data context provider. It is, as they say, a thing of beauty. Enjoy!

September 3, 2009 tools

Add “Search the Internet” Back to the Win7 Start Menu

Add “Search the Internet” Back to the Win7 Start Menu

Windows 7 took away a feature I use all the time, as shown on the right: Search the Internet.

Here’s what I did all day, every day in Windows Vista: Ctrl+Esc to bring up the Start menu, then I start typing. If I’m searching on my HD, I immediately get matches and I can choose one with just the arrows and the Enter key. If I’m typing in the name of a program in the Start menu, I get those matches and choose one. If I want calc” or notepad” I can just type those and those work.

However, 80% of the time, I want to search the internet, so enter my search term, optionally including attributes like site:”, I press, down-arrow once, highlight Search the Internet” and press Enter. This brings up my default browser with my search results in my default search engine without me having to move the mouse or open the browser and wait for the home page or even decide where I want the search results to come from until after I’ve entered my search phrase.

And we took it out of Windows 7. : (

But, Shawn VanNess has shown me how to put it back! : )

Download this zip file, execute the .reg file, press Yes and OK a bunch, kill and restart the explorer.exe process and the next time you do the Ctrl+Esc+type+something dance, you’ll see your old friend Search the Internet” right back on the Start menu where Bill intended it to be. Thanks, Shawn!

Update: This post has been translated to Danish.

October 24, 2008 tools

Tired of writing unit tests yourself? Try Pex!

From the Pex site:

Pex (Program EXploration) produces a traditional unit test suite with high code coverage. … To do so, Pex performs a systematic white box program analysis. Pex learns the program behavior by monitoring execution traces, and uses a constraint solver to produce new test cases with different behavior. At Microsoft, this technique has proven highly effective in testing even an extremely well-tested component.” [ed: emphasis mine]

So, Pex will produce a parameterized set of unit tests for your classes and does all of this integrated with Visual Studio and the unit testing built into VS. I’ve seen the demo and it blew me away. Nikolai Tillmann, a developer at MSR (Microsoft Research), has a nice write-up that discusses his work and when you’re done with that, go download Pex!

September 8, 2008 tools

Custom Window Chrome in WPF

Joe Castro, a developer on the WPF product team, has written a very cool article about how to do custom chrome in your WPF applications. But, what makes it even cooler is that he dissects the various ways that shipping apps do custom chrome on various versions of Windows. It’s amazing the number of techniques there are. Very nicely done, Joe.
March 8, 2008 tools

On Beyond Unit Testing

Quetzal Bradley is a software development engineer (SDE) on my team with *tons* of experience in all manner of infrastructure stuff including the requirements of real-world software testing from the trenches at Microsoft.

Q gave a talk about what comes after unit testing to my team and I was blown away, so I sent him to tell Scott about it so that you could hear it, too.

Enjoy.

January 18, 2008 tools

Configuring VS08 to Debug .NET Framework Source

Shawn Burke has released the details to set up VS08 to debug into the .NET Framework source code, including the following assemblies:

  • mscorlib.DLL
  • System.DLL
  • System.Data.DLL
  • System.Drawing.DLL
  • System.Web.DLL
  • System.Web.Extensions.DLL
  • System.Windows.Forms.DLL
  • System.XML.DLL
  • WPF (UIAutomation*.dll, System.Windows.DLL, System.Printing.DLL, System.Speech.DLL, WindowsBase.DLL, WindowsFormsIntegration.DLL, Presentation*.dll, some others)
  • Microsoft.VisualBasic.DLL

Others are coming. Thanks, Shawn!

November 19, 2007 tools

Visual Studio 2008 Has Been Released!

October 3, 2007 tools

Releasing the Source Code for the .NET Framework Libraries!

After programming with MFC (a lot!) and writing the ATL book, it was *very* difficult for me to live in a world without the source code to figure out how something was working. All of us have since moved over to Lutz’s most excellent Reflector, but that’s still no substitute for actually stepping in and now ScottGu has announced that we’ll have the ability to browse and debug with the .NET library source code, integrated into VS2008:

Wahoo!

August 24, 2007 tools

Shawn has prepared Genghis v0.8

Shawn Wildermuth has prepared a v0.8 release of Genghis that includes a bunch of stuff that the folks that put the v0.6 release together dropped. The v0.8 release has all the good stuff from the v0.5 release and all the new stuff from the v0.6 release in a .NET 2.0 package.

Shawn’s really done all the work for Genghis since I came to Microsoft. Thanks, Shawn.

June 17, 2007 tools

Genghis moved to CodePlex

Shawn Wildermuth has moved Genghis to CodePlex because GotDotNet Workspaces is going away. I actually really like CodePlex, but not the state those pesky contractors left the Genghis bits in, so we’ll be following up with another release in early July to bring sanity back. Thanks, Shawn!
April 11, 2007 tools

Show Me The Templates!

Show Me The Templates!

Show Me The Template is a tool for exploring the templates, be their data, control or items panel, that comes with the controls built into WPF for all 6 themes.

Show Me The Template screenshot

Enjoy.

March 1, 2007 tools

Visual Studio Orcas March 2007 CTP

And the hits they keep on comin’:

Enjoy!

February 19, 2007 tools

Lutz Roeder’s Reflector 5.0

February 14, 2007 tools

Detailed Time Zone Data

A long time ago (2000), I was fascinated with turning a phone number into a time zone so I could tell what time it would be somewhere before I called and woke anyone up (this happened too often : ).

As part of that work, I quickly realized that info in Windows for time zones wasn’t detailed enough, so I began looking elsewhere. I found the Time Zone Map Group, which maintains time zone data for all over the world backward through time. This is an amazing accomplishment, since they have to account for every law change as each tin pot dictator comes to power, e.g. George W.

At the time, they had a custom format for the data (and they probably still do, as far as I know), so I wrote a utility to translate the tz format into XML for easy parsing. I literally haven’t touched the tool since, but with the recent time zone law changes in the US, I thought folks might be interested. Enjoy.

February 4, 2007 tools

.NET: Decompressing zip file entries into memory

I knew that the J# libraries in .NET had zip file support, but I couldn’t find any samples that showed how to decompress the files into memory. The hard part, of course, is that the J# stream objects aren’t the same as the .NET stream objects. If you’re a Java programmer looking for a familiar library, that’s great, but I’m not, so I had to do a little finagling.

The first thing you need to do is to add a reference to the vjslib assembly, which brings in .NET classes in Java namespaces, e.g. java.io. The one we care most about is java.uti.zip, which includes ZipFile and ZipEntry. We also need java.util for the Enumeration class and java.io for the InputStream class. With these in place, we can enumerate a zip file:

using java.util; // all from vjslib assembly
using java.util.zip;
using java.io;

static void Main(string[] args) {
  if( args.Length != 1 ) {
    Console.WriteLine(“Usage: dumpzipfileoftextfiles );
    return;
  }

  // we’re assuming a zip file full of ASCII text files here
  string filename = args[0];
  ZipFile zip = new ZipFile(filename);

  try {
    // enumerate entries in the zip file
    // NOTE: can’t enum via foreach — Java objects don’t support it
    Enumeration entries = zip.entries();
    while( entries.hasMoreElements() ) {
      ZipEntry entry = (ZipEntry)entries.nextElement();

      // read text bytes into an ASCII string
      byte[] bytes = ReadZipBytes(zip, entry);
      string s = ASCIIEncoding.ASCII.GetString(bytes);

      // do something w/ the text
      string entryname = entry.getName();
      Console.WriteLine(“{0}:\r\n{1}\r\n”, entryname, s);
    }
  }
  finally {
    if( zip != null ) { zip.close(); }
  }
}

Notice the use of the Enumeration object so we can enumerate in the Java style and the use of the ZipFile and ZipEntry types. This is all stuff you could find in readily available online samples (I did). The interesting bit is the ReadZipBytes method:

static byte[] ReadZipBytes(ZipFile zip, ZipEntry entry) {
  // read contents of text stream into bytes
  InputStream instream = zip.getInputStream(entry);
  int size = (int)entry.getSize();
  sbyte[] sbytes = new sbyte[size];

  // read all the bytes into memory
  int offset = 0;
  while( true ) {
    int read = instream.read(sbytes, offset, size - offset);
    if( read == -1 ) { break; }
    offset += read;
  }
  instream.close();

  // this is the magic method for converting signed bytes
  // in unsigned bytes for use with the rest of .NET, e.g.
  // Encoding.GetString(byte[]) or new MemoryStream(byte[])
  return (byte[])(object)sbytes;
}

For those of you familiar with Java, I’m just reading the zip file entry data into an array of signed bytes. However, most .NET APIs like unsigned bytes, e.g. Encoding.GetString(byte[])” or new MemoryStream(byte[])”, which means you’ve got to convert a signed array of bytes in .NET to an unsigned array of bytes. Unfortunately, just casting doesn’t work (the compiler complains). Even more unfortunately, I could find nothing in the Convert or BitConverter classes to perform this feat of magic and the code I wrote was dog slow, so I asked around internally.

Luckily, James Manning, an MS SDE, had the answer: cast the signed byte array to an object first and then to a unsigned byte array. Thank goodness James knew that, because I didn’t find anything on this topic. Hopefully future generations will find this missive.

You can download the sample if you like. Enjoy.

February 2, 2007 tools

Windows Servers for the rest of us

Charlie Kindel of COM fame (he’s wrote the foreword to Don’s seminal work Essential COM) is the Product Unit Manager (softie-speak for butt on the line”) for the new Windows Home Server team. If you haven’t heard about it, Home Server is a Windows server box for the rest of us. I don’t know about you, but I’ve got file, print and media servers all over the house in a confusing mess and I look forward to being able to consolidate it. According to the enthusiastic beta tester I talked to, Windows Home Server is the way to do that.

Yesterday, Charlie announced the Windows Home Server Blog. Enjoy.

January 29, 2007 tools

Window Clippings 1.5

Capturing screenshots for a book used to be a piece of cake. Alt+PrintScreent and you were golden. However, sometimes I wanted to get the cursor, too, and neither Alt+PrintScreen nor PrintScreen does that, so I got myself a copy of SnagIt. Unfortunately, if I wanted to capture multiple screens, I was putting a maximized copy of Notepad in the backgrand, using PrintScreen and PBrush to do the cropping (although SnagIt has slightly more seamless multi-window selection).

Still, this all worked til Vista came along and Alt+PrintScreen left the shadows out! I was fine with that, but Ian correctly pointed out that the screenshots with the shadows looks *so* much better that I could hardly say no.” And I discovered the Snipping Tool in Vista, which let me do a selection on any part of the screen I wanted to, except that now instead of just doing Alt+PrintScreen, even for a single window, now everything is a selection, which means that somebody (hopefully not me!) has to trim the extra whitespace to make sure the pictures layout OK in the book.

I told you all of that so you could know that I envy folks that don’t have to do screenshots! It’s hard to make it look right, although, for visual technologies, I really can’t imagine not having them. Anyway, I was definately open to another screen capturing technology and that’s when someone turned me on to Windows Clippings.

When I found Kenny Kerr’s most excellent screen capture tool, it was so close to what I wanted (it did Vista shadows with no guesswork!), that I sent Kenny an email with my feature request (easy child+parent capturing support), fully expecting not to hear back (it’s clear from his web site that he’s a busy guy!). Not only did he reply, but he’d implemented my feature!

And it was such a time-saver, that I forwarded it along to Ian, who had his own feature request (keeping the transparency in the captured image w/o grabbing the stuff underneath), which Kenny promptly implemented (with some example code from Ian). Of course, that broke my feature (the constant animation of WPF apps + capturing transparency caused problems), so Kenny fixed that, too. By this point, Kenny’s app itself was notifying me of updates faster than he could send the emails.

All of this is merely to say, I’m really loving my Windows Clippings experience. Thanks, Kenny!

January 19, 2007 tools

CodeFetch: Search Book Source Code

CodeFetch allows you to search in the source code associated with books (like the code I publish for my books). Plus, it lets you choose the language to search on and shows the book the results come from so you can read your favorites. Very cool.
December 15, 2006 tools

Point: Local Live Maps

When it comes to Web 2.0 apps, online maps are easily the thing I use the most. I don’t go anywhere these days w/o first pulling up the map on MapQuest, Google maps or, for a coupla years now, local.live.com (starting back when it used to be called MapPoint). I generally use Google for my search engine, so don’t think it’s just the MS employee thing pushing me — I genuinely like local.live.com better.

Google and MS have been in an arms race for years on the maps stuff, doing fancy stuff like 3D globes and other goo that looks good in demos, but that I don’t need. However, in this war of the world (so to speak : ), today MS fired a decisive shot across the bow, I think — the Send” menu. This is huge for me, because I can send the directions to my phone, either via SMS or via email, and I get a great display clearly optimized for my smartphone. Not only does it have a great mini-map, but the directions are easy to read (saving me from printing the directions for just a single trip) and it has a link to reverse the directions (the one thing I never remember to do).

Oh sure, I can do the same thing with the Google maps Email” menu, but when I follow the link on my phone, there’s no map (although there is a handy link to reverse the directions). Also, the directions don’t read as well and I swear it’s faster to surf to the local.live.com directions (although this might just be the MS bias talkin’ : ).

On the other hand, I just noticed that Google maps has a new Add destination” link for multi-destination trips, which is the only thing I use AAA online TripTiks for and you have to be a member to access the feature (I am, but still it’s kinda clunky…). Hey, local.live.com guys — can I have that, too?!?

P.S. I think I’ve scared the most reactionary, close-minded folks away, so I think I’ll cool it on the postscripts for a while (’til I feel like it again : ). BTW, my definition of close-minded” is those who don’t think I have the right to express my opinion,” not those who disagree w/ me.” Hopefully I managed to shake the former off my RSS feed while keeping the latter.

December 15, 2006 tools

VS2005 SP1

Through further advancement and feedback, Service Pack 1 … provides over 70 improvements for common development scenarios including:

  • New processor support (e.g., Core Duo) for code generation and profiling
  • Performance and scale improvements in Team Foundation Server
  • Team Foundation Server integration with Excel 2007 and Project 2007
  • Tool support for occasionally connected devices and SQL Server Compact Edition
  • Additional support for project file based Web applications
  • Windows Embedded 6.0 platform and tools support

For more information, see the Microsoft Download Center:

At the time of this posting, VS05SP1 update for Vista download wasn’t available, but it should be directly.

P.S. I hope everyone is enjoying the holiday season with peace, love and understanding.

December 11, 2006 tools

XNA Game Studio Express Has Been Released!

Oh, man, I *so* want to write a game that runs on my Xbox 360! Now I can (and so can you). Enjoy!

P.S. Impeach!

August 30, 2006 tools

If it can be installed, Scott’s installed it

and if it’s any good, we hear about it. Really, I’m just posting this link to Scott Hanselman’s 2006 Ultimate Developer and Power Users Tool List for Windows here so I can find it later, but feel free to browse the list yourself, broken up into several interesting categories:

  • Top 10 (+ 5) Life/Working-Changing Utilities
  • A Developer’s Life
  • COM is Dead [ed: if only]
  • XML/HTML Stuff
  • Regular Expressions
  • Launchers
  • Stuff Scott Digs
  • Low-Level Utilities
  • Websites/Bookmarklets
  • Tools for Bloggers
  • Smart People’s Utility Pages
  • Alt.Lang
  • Browser Add-Ins
  • Things Windows Forgot
  • Outlook Add-Ins and Life Organizers
  • Ultimate Registry Tweaks
  • Windows Explorer Integration (and other integratey things)
  • Continuous Integration
  • TablePC Indispensables
  • ASP.NET Must Haves
  • Visual Studio Add-Ins

Notice how just his list of categories is longer than most people’s lists? Scott’s a gem. Guaranteed you’ll find something that makes your life better.

July 30, 2006 tools

Number to String Converter

Number to String Converter

To capture the work that Doug and I did to make Indigo (WCF) and Avalon (WPF) work together, I tore up our PDC sample application into a set of simpler technology samples. To make it fun for myself, as part of these samples, I built a little library for converting numbers into strings of English words, e.g.

Enjoy.

July 30, 2006 tools

RegistrySettingsProvider2

I updated the SDK RegistrySettingsProvider to implement IApplicationSettings and built a sample to demonstrate how to integrate it (or any .NET 2.0 custom settings provider) with the settings designer-generated code. Enjoy.

Discuss

July 30, 2006 tools

Number To String Converter

Number To String Converter

To capture the work that Doug and I did to make Indigo (WCF) and Avalon (WPF) work together, I tore up our PDC sample application into a set of simpler technology samples. To make it fun for myself, as part of these samples, I built a little library for converting numbers into strings of English words, e.g. 4 is four:”

To drive home the point (of which there wasn’t any because the sample had nothing whatever to do with number to English phrase conversions), I spent some time polishing the algorithm so that it handled decimal points:

and when that didn’t satisfy me, I added large numbers and negative numbers:

Before writing this code, I searched the net and didn’t find any algorithms that handled both negative numbers and decimal points, let alone for .NET or in the number of lines of code to which I cut it down (93, including comments). I know it’s not useful, but it was fun. If you want the code, you can get it by downloading the .NET 3.0 Cross Technology samples and checking out the WinSDK_Samples\CrossTechnology\WpfDataBindingToWcfResults\service\NumberUtility.cs file. I built the file to be dropped into any .NET 2.0+ project (and even .NET 1.x projects, if you remove the using System.Collections.Generic” statement at the top of the file — I don’t actually use generics), regardless of whether you’re using Avalon or Indigo or not.

Enjoy.

Discuss

July 29, 2006 tools

MS Live Labs PhotoSynth: building the photo web

Imagine your vacation photos displayed in 3D and linked together, both around a space and zooming in and out. Now imagine everyone’s photos linked together in this way. What you get is PhotoSynth:

Worth checking out.

July 11, 2006 tools

Functional Language Summary

I’ve been hearing a lot about functional programming lately (and the circle of life continues); I found Functional Programming For The Rest of Us to be a nice summary. Here’s what I got from it:

Atoms of FP:

  • All variables” are immutable, often called symbols”
  • Program state is kept in functions (specifically, arguments passed on the stack to functions), not variables
  • Functions are first class citizens, i.e. functions can be passed as arguments
  • currying” is a convenience syntax for adapting a function to an alternate function signature
  • closures” are functions that are allowed mutable state and access to state outside their lexical scope to bridge functional and non-functional languages

Implications:

  • Functions cannot cause side effects (“variables” are immutable)
  • FP is great for unit testing (only have to test outputs against inputs — don’t have to test side effects)
  • FP is great for debugging (no need to worry about external state affecting function results — results are only based on the input)
  • No need for multi-threaded locks, as state is immutable
    • This makes functional programs automatically parallelizeable
  • Can hot swap new function definitions w/o effecting existing instances
  • Don’t need to evaluate a function til the results are needed

FP sounds great! Why do we mess around w/ anything else?!?

July 5, 2006 tools

A Shared Source Site: CodePlex

CodePlex functionality, built on Microsoft Visual Studio® 2005 Team Foundation Server, provides source control, issue tracking, discussion forums and RSS feeds in and out of each project so that members can stay up to date on the development issues most important to them. Microsoft Visual Studio Team Foundation Server enables developers to collaboratively develop, share, discuss and consume source code and build software.”

Enjoy.

June 12, 2006 tools

“man” for MSDN

If you like man, you’ll love MSDN man. Enjoy.
June 9, 2006 tools

Annotate the MSDN Wiki

For a long time, my favorite place to put up code snippets that I could get back to later has been pinvoke.net (like GetTempFileName). However, that was only good for managed/native interop, whereas the MSDN Wiki is for anything in the docs. I don’t know what their commitment is to keeping content over time or between versions, but I’ve got my fingers crossed. Enjoy!
June 9, 2006 tools

Advanced MSDN Search

MSDN has a new search UI which includes And, Or, Exclude, Group, Exact Phrase and Preference in the query and then narrowing by source or category in the results, e.g. MSDN or MFC Reference. The ability to exclude CE in the search results is worth the price of admission. Check it out!
June 5, 2006 tools

Web Application Project: “The type ‘foo’ exists in both ‘some dll’ and ‘another dll’”

In using the most excellent Web Application Project support for ASP.NET 2.0 in VS05 from Mr. Guthrie and co, I ran into what was first an intermittent and then a constant problem that actually made it’s way onto my live site (it worked on my machine!). The error looked like this against several classes in my app, i.e. when I’d comment out one, I’d get another class that showed the same problem:

Compilation Error

Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.

Compiler Error Message: CS0433: The type ASP.clientredirector_ascx’ exists in both c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\sb2\4d76034e\bec2c8d0\App_Web_clientredirector.ascx.cdcab7d2.zmdrab5k.dll’ and c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\sb2\4d76034e\bec2c8d0\App_Web_axhgbqrn.dll’

Source Error:

Line 11: 
Line 12: <!-- client redirector -->
Line 13: <sb:ClientRedirector runat="server" id="ClientRedirector" />
Line 14:
Line 15: <!-- fragment monitor -->

Source File: d:\project\mine\sb2\pageLayout.ascx    Line: 13

I chased this with my ISP a few days ago, but futzing with it made it go away mysteriously. When it came back, it came back with a vengeance and I pulled in every ASP.NET 2.0 resource I could think of to fix it, including sending ScottGu the FTP user name and password to sellsbrothers.com (my site hasn’t fit into a reasonable .zip file for a while now : ).

The thing I did that fixed the problem (seemingly consistently), came from Scott himself; I added the batch=“false” attribute to my compilation element in my web.config file:

<configuration …>
  <system.web>
   
<compilation  batch=false/>
      …

Apparently this ends up generating a lot more assemblies than batch=“true”’, but I don’t know why that would fix the problem or even what’s causing the problem. This never happens in WinForms or Avalon (and, of course, neither of those technologies have issues of their own… : ).

Thanks Scott, Ting-Hao, Simon and David!

Update: Microsoft has updated the Knowledge Base with this issue

April 20, 2006 tools

Visual Studio Express Editions Free4Ever

March 29, 2006 tools

Tell me about your troubles and woes configuring, deploying and maintaining distributed .NET apps

Believe it or not, Microsoft is always trying to improve its products and to do so, I find we do our best work when we actually ask our potential customers what they think.

In this case, I’d like to know what pain points” you experience when configuring, deploying and maintaining distributed .NET applications. That can be any kind of app, whether it’s a client-side app that phones home for code or data updates or whether it’s a fully distributed grid or anything in between. Please be as specific as possible and, if you’d like one of our courteous technical people to follow-up, make sure to include contact info.

Use this as an opportunity to vent — don’t hold back. Remember: the life you save may be your own…

March 29, 2006 tools

Gengis for .NET 2.0

Genghis has been updated for .NET 2.0 and is available from the Genghis workspace. Enjoy.

Update: The following controls have been added to Genghis in the .NET 2.0 version:

  • Dynamic Custom Button Control
  • Data Interchange List Boxes
  • File List Control
  • Folder List Control
  • Multi-Direction Progress bar
  • Help Popup Control
  • IP Address Control
  • PictureBox Button Control
  • TimeOut MessageBox Control
  • Calendar Combo

March 26, 2006 tools

I’m with Scott — I Love Monad

I fell in love w/ the potential of monad a while ago w/ Jeffrey Snover’s original Channel9 video, but I was too lazy to download it onto all of my machines. However, after seeing Jeffrey’s talk at TechDays 2006 in Switzerland (and remembering that monad is installed by default w/ the WinFX SDK, so it was already on all my machines), I took the dive (starting with kiping Jeffrey’s personal copy of Monad,” from ORA, Andy Oakley’s most excellent monad intro) and I’ve been doing it pretty much non-stop on the train and on the plane all the way home. Like Scott, I’m loving it.

I’ve built several scripts, including start-process (to act like cmd.exe’s start” command — invoke-item doesn’t work on URLs), find-file, find-filebytext, find-dir and format-notepad. So far, no luck on format-clipboard, i.e. dropping the results of an operation into the clipboard, but I’m having a blast trying.

Monad is the command line I’ve missed so much from my ex-life under Unix. Give it a try! You’ll love it.

March 7, 2006 tools

ClickOnce + FireFox

If you’re having trouble with ClickOnce while using FireFox as your default browser, then this post is for you. Thanks, Saurabh!

February 26, 2006 tools

Hello from ASP.NET 2.0

I ported sellsbrothers.com to ASP.NET 2.0 a while ago, but I wasn’t happy with the experience, so I didn’t pull the trigger on moving it to a production environment. I’m glad I waited. I ported the site again last night using the VS05 Web Application Project preview and it worked a treat. Recommended.
February 8, 2006 tools

Network bandwidth usage monitor?

Sometimes, for no reason I can discern, the network bandwidth on various computers in my house goes south. What I’d love is a tool that shows me how much traffic is going across my network, where it’s going and where it’s from, i.e. from the internet, from a machine in my house, etc. Ideally, it’d also show me the ports and even the processes on each machine that are producing/consuming the data. Does such a tool exist?
January 26, 2006 tools

Calling a Remote Index Server from .NET

I was building some code to access Index Server’s results via .NET and I got this:

// Catalog specified in connection string
string query = select Path from Scope() where FREETEXT(‘foo’)”;
using( OleDbConnection conn = new OleDbConnection(“Provider=MSIDXS.1;Data Source=MyCatalog”) ) {
  conn.Open();
  OleDbDataAdapter cmd = new OleDbDataAdapter(query, conn);
  DataSet ds = new DataSet();
  cmd.Fill(ds, SearchResults”);
  DataTable table = ds.Tables[0];
  ds.Tables.Remove(table);
  return table;
}

This came from a combo of stuff I found on the net and my own experimenting. However, I had to get an MS employee who know IS (thanks Chad Ray!) to figure out how to access IS remotely, which I was finally able to get working thusly:

// Server and catalog specified in query string, not connection string
string query = select Path from MyServer.MyCatalog..Scope() where FREETEXT(‘foo’)”;
using( OleDbConnection conn = new OleDbConnection(“Provider=MSIDXS.1”) ) {
  conn.Open();
  OleDbDataAdapter cmd = new OleDbDataAdapter(query, conn);
  DataSet ds = new DataSet();
  cmd.Fill(ds, SearchResults”);
  DataTable table = ds.Tables[0];
  ds.Tables.Remove(table);
  return table;
}

Also, if the server or catalog name has anything weird” in it, e.g. those wacky dashes, you’re supposed to wrap it in double quotes. My experimenting showed that wrapping any server or catalog name in double quotes worked just fine, e.g.

string query = select Path from "MyServer".\“MyCatalog\”..Scope() where FREETEXT(‘foo’)”;

However, if the server name is localhost” or 127.0.0.1″, IS doesn’t like it, which meant that I had to check for those server names and drop the ones that used the loopback adapter (although using the machine name of the local machine worked just fine), e.g.

static bool IsLocalHost(string server) {
  return string.IsNullOrEmpty(server) || (string.Compare(server, localhost”, true) == 0) || (string.Compare(server, 127.0.0.1″) == 0);
}

string GetPlainTextQueryString(string text, string columns) {
  // IS doesn’t like localhost”
  if( IsLocalHost(_server) ) {
    return string.Format(“select {0} from "{1}"..Scope() where FREETEXT(‘{2}‘)”, columns, _catalog, text); 
  }
  else {
    return string.Format(“select {0} from "{1}".\“{2}\”..Scope() where FREETEXT(‘{3}’)”, columns, _server, _catalog, text); 
}}

I’m only posting this cuz I couldn’t find it on the net and I want to be able to find it again later. : )

January 11, 2006 tools

.NET 2.0 Breaks NTD

Charles Sterling, Developer Evangelist, points out a problem with .NET 2.0 and No-Touch Deployment applications over the internet (where problem” = breaks completely”).
January 5, 2006 tools

Bindows: Windows Implemented in AJAX

Holy User32 in a browser window, Batman!

I don’t know what it’s like to use an app built this way, but looking at the samples blows me away…

December 20, 2005 tools

New Workspace Link for RegexDesigner

Here.

The nice folks at GotDotNet have decided in their infinite wisdom to move all of the workspaces to a new hierarchy w/o forwarding the URLs and then leaving a message behind indicating that such a thing is temporary to keep users on their toes:

Operational Troubleshooting in Progress
The Gotdotnet team is aware of the current site operational issues and is working on a solution. Thanks for your patience.”

Anyway, due to popular demand, I’ve updated the GotDotNet workspaces link to the RegexDesigner and other tools. Enjoy.

December 9, 2005 tools

Windows Template Library (WTL) 7.5

It looks like my old friend Nenad Stefanovic is up to his old tricks with a new version of my favorite native framework, the Windows Template Library. This will go nicely with ATL Internals, 2e, which Chris Tavares is finishing up for Brent and me.

[via Shawn Wildermuth]

November 16, 2005 tools

Lots of WinForms 2.0 Chewy Goodness

Here. The WinForms team has put up all kinds of WinForms 2.0 resources, including a bunch of FAQs and samples. Enjoy.
November 10, 2005 tools

Windows Forms 2.0 UI Clones

Here.

The Windows Forms team has posted .NET 2.0 versions of their UI clone apps, including:

If you want a Windows Forms app in one of those styles, those samples are where I’d start.

November 8, 2005 tools

Using VS05 to build .NET 1.x apps

November 4, 2005 tools

Generics Q: Best way to convert a string to a T?

What’s the best way to implement the following semantic (feel free to change the signature)?

bool ConvertFromStringToT(string in, ref T out) {…}

I’d like to be able to call it like so:

int x = 452;
double y = 77.7;

ConvertFromStringToT(“123”, ref x); // x is now 123
ConvertFromStringToT(“abc”, ref y); // y remains 77.7

I came up with a solution that relies more than I’d like on run-time behavior rather than compile-time behavior, which is why I’m asking.

October 27, 2005 tools

Scraping old versions of VS05 off your system

If you read the ReadMe.htm from the Visual Studio 2005 setup, you’ll see a detailed list of up to 23 things to uninstall in the right order (plus 2 notes if you have trouble).

To solve this problem, Dan Fernandez posts about a VS05 uninstall tool that worked wonderfully for me.

October 27, 2005 tools

VS05 Has Shipped! Wahoo!

September 26, 2005 tools

MS Dogfooding Avalon

As MS releases new frameworks, folks always ask Does MS use this?” Of course, MS has tons of existing apps that would be silly to rewrite, but when we build new stuff, we generally use the latest frameworks that make sense.

Towards that end, John Gosman continues his history of Expression Interactive Designer aka Sparkle, mentioning the percentage of managed code in  (100%) and the number of P/Invoke calls (1 — HtmlHelp) to get what is probably the most amazing app I’ve seen in years, whether managed or not.

September 18, 2005 tools

Tracking exceptions thrown by your apps worldwide

This is an interesting, and free, service that you hook your app up to and when it throws an exception, it’ll log it w/ the service so that you can track it from afar.

These kinds of services are exactly what web services are wonderful for. Does anyone know of any other such services? I’m embarrassed to say that I don’t actually know, but does MS provide one in this space or other developer-oriented web services for other than development?

September 10, 2005 tools

Remove the slow “Compress Old Files” option!

I love CleanMgr.exe’s ability to clean out my temp folder, my internet cache and my recycle bin in one swell foop, but that damn Compress Old Files” option drives me crazy! Luckily, Scott Hanselman got a .reg file from Shawn Van Ness and now I don’t have to put up with that option. Wahoo!
August 29, 2005 tools

Early WinFS beta posted for MSDN subscribers

Not too far behind Indigo and Avalon’s beta 1, WinFS posts their own beta 1 (although Tom Rizzo, Director in SQL marketing says it may be a tad early). Since their endgame” is that WinFS will be in beta when Windows Vista ships,” so long as they don’t move past beta to RC or RTM (or back to alpha), they’ve hit it. Congrats! : )
August 12, 2005 tools

Very Cool Nullable Fix

.NET 2.0 has the idea of a nullable” type built right in, e.g.

Nullable x = null; // legal

This adds nullability to value types as well as reference types. Further, C# adds direct support with this syntax:

int? x = null; // legal

However, while the C# language was updated to support nullability, the CLR was not, which lead to problems with boxing:

int? x = null;
object y = x;
// a boxed Nullable was never null
if( y != null ) Console.WriteLine(“Doh!“);

This problem was fixed this late in the .NET 2.0 game by getting a bunch of folks together to rejigger things so that the following works the way you expect:

int? x = null;
object y = x;
// a boxed Nullable can now be null
if( y == null ) Console.WriteLine(“Wahoo!“);

Somasgar has the full scoop.

August 11, 2005 tools

What should I do w/ the metadata?

Imagine I’ve got some metadata” that describes some functionality of my system, e.g. the command line parameters to a tool:


 
 

Once I have this metadata” in place, should I a) use it to generate a class at compile-time that implements the command line parsing, or should I b) use it to drive a command-line parsing framework at run-time?

If I do a), generate the code, the result might look like this:

class Args {
  public void Parse(string[] args) {…}
  public string Usage { get {…} }
  public int Lefts { get {…} set {…} }
  public string Attitude { get {…} set {…} }
}

I’ve got better perf, but I have to generate the code in some way and .NET doesn’t come with any built-in tools to do that (no, I don’t count ASP.NET or XSLT as good codegen tools). Plus, the command-line args are now baked in and require a re-compile to change and who cares about perf to parse the command line? Finally, I’m much more likely to have most of the work done in a base class, e.g.

class Args : ArgsBase {
  public void Parse(string[] args) { return base.Parse(args, …); }
  public string Usage { get {…} }
  public int Lefts { get {…} set {…} }
  public string Attitude { get {…} set {…} }
}

In my experience, most of the work of code-gen is generating the smallest possible bit of code to provide a nice wrapper around a base class that does most of the work in a very interpretive manner.

If I do b), have a run-time interpretter of the metadata,” I’ve got to build a command-line argument interpreter, but, as I’ve said, you almost always have that anyway. However, I also give up a develop-time wrapper aka Intellicrack” which will be pried from my cold, dead fingers.

What do you guys do?

August 3, 2005 tools

WinFX Beta 1 Online SDK Docs

July 22, 2005 tools

Cool Avalon Default Style Trick

Karsten shows a cool trick for pulling out the default style of an Avalon lookless control. This is super useful if you want to replace an existing control’s look, but you don’t want to have to start from scratch.
July 16, 2005 tools

My First MsBuild Task

Here. The one where I built my first custom msbuild task.
July 12, 2005 tools

Eric Sink: The Game is Afoot

I don’t know if Eric understands the ISV industry or not, but certainly seems to. Luckily, I’m on a real product team now, so I get to try to channel Eric into my work.

Eric’s latest writing is The Game is Afoot, in which he describes various games and then draws lessons from them for ISVs. It’s fabulous. He concludes by apologizing for the length and then teasing us with the analogies he left off. It wasn’t too long, Eric! I wanted more! (I also want your blog to have comments, but that’s another thing entirely…)

I think now I understand the public outcry when I suggested that I might cut down on the material in the Windows Forms 2.0 book

July 12, 2005 tools

Looking forward to the Portland Code Camp, 7/23-24

The session list for the Portland Code Camp, July 23-24, has just been posted. I’m especially looking forward to the following:

  • .NET Windows Forms Tips & Tricks
  • Forensic Development
  • Implementing Creature AI
  • Introduction to Inform
  • Introduction to Python
  • Introduction to Ruby
  • Ruby on Rails
  • MonoRail - ASP.NET on Rails
  • Web Unit Testing with Ruby and Watir

That’s only if my wife doesn’t have my working on the house (we’re prepping it for sale). Of course, I don’t know if she’ll understand that I’ve volunteered to give my own session: Some Cool Avalon Stuff

July 5, 2005 tools

Register for COM Interop and VS05b2

I was helping a colleague work through a .NET COM interop issue. He’d found my article on the topic (“Hosting Windows Forms Controls in COM Control Containers), but couldn’t get it to work. He’d set the Register for COM Interop setting and adding the Guid attribute to his .NET type, but nothing was registered at build-time.

The problem was that, unlike VS03, the wizard-generated AssemblyInfo.cs has the assembly-wide ComVisible attribute set to false” which causes regasm (the command-line version of what VS is doing to register your .NET assembly with COM at build-time) to skip the registration of all of the .NET types in your assembly, defeating the purpose of the Register for COM Interop option pretty thoroughly.

The trick, of course, is to set ComVisible to true”.

July 5, 2005 tools

Grid: The King of Avalon Layout

The Grid is by far the most useful, powerful and general purpose layout tool in Avalon. As a demonstration of that, Amir Khella, a Microsoft PM on an Avalon-related team, plays with the Grid to build a fish eye effect, duplicating the behavior of the scaling OSX toolbar with 8 lines of C# code. He then goes on to implement the trick in 2D to scale images as you mouse around. Cool stuff.
June 28, 2005 tools

Avalon and ASP.NET, Together At Last

Scott Guthrie says:

What we’ve set out to do is to make it dramatically easier for anyone to build AJAX-style web applications that deliver rich, interactive, and personalized experiences. Developers should be able to build these applications without great expertise in client scripting; they should be able to integrate their browser UI seamlessly with the rest of their applications; and they should be able to develop and debug these applications with ease.

For this work, we’ve been working on a new project on our team, codenamed Atlas.’ Our goal is to produce a developer preview release on top of ASP.NET 2.0 for the PDC this September, and then have a website where we can keep updating the core bits, publishing samples, and building an active community around it.

Then Scott says:

We see Atlas as the best way to write a whole new generation of richer, more interactive, more personalized experiences in browser applications.  Avalon is the next generation presentation model for Microsoft, and will let you build the richest user experiences on the Windows platform. Avalon will deliver phenomenal graphical experiences that use the latest in media integration and hardware acceleration. And Avalon will also let you provide persistent, immersive experiences that go beyond the browser.

Of course, when you’re building Avalon applications, you can reuse the programming model investments you make today with ASP.NET and Atlas. For example, the ASP.Net Building Block Services and Client Building Block Services will also be accessible from any Avalon client. This model gives you a smooth path to the next generation of applications.”

And then I say:

Cool!”

June 27, 2005 tools

New Monad Build Available

You have to stand on one foot, wait for 48 hours and wave a dead chicken over your monitor, but assuming you have the foot and the dead chicken, it don’t cost nothin’ to download the latest beta of Monad. Enjoy.
June 11, 2005 tools

Ajax.NET

If I were doing AJAX work in ASP.NET, Ajax.NET is the kind of thing I’d want to use.
June 9, 2005 tools

Col. Jessup on the .NET Performance Team

This is fabulous! Let me give you a taste:

We use words like L2, swaps, and working set. We use these words as the backbone of a life spent defending something. You use them as a punchline.”

June 6, 2005 tools

@this freaked me out

I saw code that looked like this today:

class Class1 {
 
static void Foo(object @this) {
    Console.WriteLine(@this);
  }

  static void Main(string[] args) {
    Foo(“hi”);
  }
}

It freaked me out, but it’s completely legal and kinda cool…

May 25, 2005 tools

C++ is dead, long live C++!

Congrats to the VC++ 2005 team for a write-up like this!

The truth is that this new development in C++ seriously undermines the justification for C# as a language. C++ programmers yet to learn C# simply don’t need to now. What’s the point? They will find the full productivity of Visual Studio 2005 right there at their fingertips supporting the language they know and love. Why should they move to something that is slower and less feature rich?”

He goes on with choice words about those of us that use C# as either poor folk who have already invested time in it,” Java types moving to .NET and smart enough to avoid J#” or dev-celebs and style gurus will realize that it’s in their interest to keep pushing the C# fashion wagon.” I don’t know which camp I fall into, but I love the phrase dev-celeb!” : )

I remember being in a conference room many years ago with about 10 members of the VC++ team on one side of the table and me on the other with them drilling me for about an hour on what would it take for me to love C++ and give up C#. I asked for the power and performance of C++ and the simplicity of C#. According to The Grumpy Programmer, they’ve not only delivered on this promise, but

the painful, balls-on-the-table truth is that C# has lost its point.”

Luckily, no one asked me to put any of my body parts on the conference table that day, but you gotta love a guy that can turn a phrase like that. : )

May 13, 2005 tools

“dumpbin” is now “link -dump”

Apparently in Whidbey, dumpbin” (and some other tools that were merely wrappers around link) has been dumped. To get to it now, do link -dump -dumpbin_options” e.g. link -dump -exports” does what dumpbin -exports” used to do. In fact, if you just do link -dump” the usage you get is labeled as the dumpbin usage. : )

BTW, it looks like lib,” while still there, is also link -lib” and editbin” becomes link -edit.”

[via Brent Rector]

May 13, 2005 tools

When did the cmd shell start doing this?!?

Imagine the following C program:

// cmdio.c
#include <stdio.h>
void main() {
char s[256] = "";
printf(">");
scanf("%s", s);
printf("%s\n", s);
}

If I run this from a command shell and I enter hi” [Enter], it looks like this:

C:\>cmdio.exe
>hi
hi

If I run it again using lo” [Enter] this time, it would look like this:

C:\>cmdio.exe
>lo
lo

Here’s the thing that blew me away. Anytime I run it after the 1st from the same cmd shell, I get history! For example, running it a 3rd time and pressing [Up Arrow][Enter] gives me this!

C:\>cmdio.exe
>lo
lo

The up and down arrows work, F7 works, F8 works, they all work! When the heck did the shell start keeping track of per sub-command histories and why haven’t I noticed it til now?!?

April 28, 2005 tools

Another VB.NET feature that makes me jealous

April 26, 2005 tools

I Like VC# Express

I was paving a box this weekend with the March Avalon/Indigo CTP and I needed the matching Feb CTP of VS05, so I installed the Feb CTP of VC# Express. I have to say, I’m impressed. Avalon integrated w/ no trouble. I have all the Intellisense, key bindings, options, code formatting and generics support that I went looking for (although I did have to find the Show all settings option in the Options dialog).

Only two things bug me about Express. The first is minor: I’m used to starting VS with Start->Run: devenv [Enter] and now I have to start VC# Express with Start->Run: vcexpress [Enter]. Given that I can install a bunch of Express products, it makes sense to me to need to learn a new EXE name for each of them (especially if I slip Asynch COM out of long-term storage… [dumping]… there, plenty of room!).

The second thing that bugs me is that I’m not allowed to specific a spot on my hard drive when I create a new project. As a guy with a background thread running Alt->F->S every time I typing idles, having everything in a well-known place is important to me. I’m a developer. Things crash!

Overall, though, I’m loving VC# Express. Recommended.

April 4, 2005 tools

RegexDesigner Updated

RegexDesigner has been updated to v1.1 with support for replacement patterns, national and special symbol support, Ctrl+Tab hotkey support, updated highlighting support for color blind users, Ctrl+A support and the use of a bullet instead of @ for matched whitespace. Thanks to Victor Serbin for putting this update together from source contributed to the GDN workspace.
March 29, 2005 tools

Translate C# To And From VB.NET As You Type!

Carlos Aguilar Mares, an SDE on the MS Web Platform & Tools team, has created a fabulous C# to/from VB.NET code translation tool. You can hand it a file and translate in batch mode or you can just type in one language and see it translated in real-time into the other. Now all Carlos needs is a project-wide batch mode and he’d have the problem licked!
March 22, 2005 tools

Duncan Shows How To Host MSDN Content On Your Site

Are you unhappy with how MSDN arranges content on our site? Would you like to host the content you’ve written on your own site in your own chrome? You can’t do it with everything, but for the content with which it works, Duncan Mackenzie has posted code that pulls content out of MSDNs current content management system* and hosts in in your own chrome. For those of you that don’t like how MSDN arranges its content, you now have the technical means to arrange it to suit your own tastes.

* DISCLAIMER: Microsoft’s copyright still applies. The internal details of our content management system are going to change without notice. Use at your risk. No warranties extended. Void where prohibited. Some assembly required. blah, blah, blah…

March 13, 2005 tools

When the student is ready, the teacher will come

I’ve been digging into .NET application extensibility lately, discovering the various pieces discussed here. And then, just when I’d despaired of finding a resource that covered the issues in depth, a copy of Customizing the Microsoft .NET Framework Common Language Runtime,” by Steven Pratscher, showed up at my door (that happens sometimes, but I’ve never quite figured out how…).

Steven’s a PM on the CLR team and his book has wonderful chapter titles like:

  • Loading Assemblies in Extensible Applications
  • Extending the CLR Security System to Protect Your Extensible Application
  • Enforcing Application-Specific Programming Model Constraints

And if you’re thinking, Big deal, .NET 2.0 is coming out soon and will makes this info obsolete,” au contraire, mon frere! This book is based on the .NET 2.0 beta, so the concepts (and hopefully most of the details) are the latest and greatest (and you can download the source that goes along with the book here). I plan on having quite a bit of fun with this book! Thank you book-mailing-to-my-house-god, wherever you are…

February 8, 2005 tools

XSLTO: Mapping XSLT to Objects

Here. When Tim Ewald was still a Microsoft employee, he and the next-gen MSDN content management system team experimented with some fun techniques for XSLT to Object mapping. To illustrate this technique, Kim Wolk has built a little prototype that lets you associate an XPATH statement with a method on an object and that method will be invoked for the nodes that match the XPATH statement. Check it out.

Update: Steve Dunn has ported Kim’s sample from .NET 2.0 beta to .NET 1.1. Thanks, Steve!

January 30, 2005 tools

Awaiting and Dreading Subtext

If you follow the link to the subtext demo that Preston Bannister mentions, you’ll see my idea of hell, i.e. manipulating code primarily with a mouse. Have you ever seen those guys — you know who I mean — those guys that want to copy a chunk of code and reach for the mouse, almost select the text, almost select the text again, finally select the text they want, go to the Edit menu, choose Copy, click on the place near where they want the code to be, click again, finally click in the right place, go to the Edit menu and choose Paste and by that time, you’ve died of old age? It’s all I can do not to tackle these people so I can use the combinations of Ctrl, Shift, Alt and the arrows to select the text and move the cursor to the spot where it belongs, using Ctrl+C and Ctrl+V, never touching the mouse, like BillG intended.

So, watching the subtext demo, which was nearly all copy and paste using the mouse made me want to tackle the guy doing the demo, especially since I couldn’t run it at a higher speed (my very favorite WMP feature).

On the other hand, I loved the idea of the code always being executed with live, example data to show me instant code coverage and I loved the idea of the code always being executable. If I could get a structured editor that let me copy and link using the keyboard (and it used some language I could actually ship, at least in some transformation mode), I’d use it in a heartbeat.

January 5, 2005 tools

Thinstall sounds cool

Jim Hubbard gives Thinstall a ringing endorsement:

This solution will take your executable (.Net, VB or C++) and all of its dependencies and wrap them all into a single executable. The neat thing is that it even includes the portions of the .Net framework needed to run your executable inside the executable it creates. So, there’s no need to distribute the whole .Net framework.”

Has anyone else tried it?

December 1, 2004 tools

GUI Front End to XmlSerializerPreCompiler

Mathew Nolton has posted a GUI front-end to my XmlSerializerPreCompiler that you might find useful. Thanks, Matt!

November 18, 2004 tools

Rich Salz on WSDL 2.0

According to Rich Salz’s reading of the WSDL 2.0 spec (Rich makes a living selling hardware to make XML smoke, so I think he knows), the following is legal WSDL 2.0:

#include "wsdl.h"
extern void hello_world(const char* text);

It’s hisjudgmentt that this is not a step forward and I’m having a hard time finding fault with his argument. : )

November 13, 2004 tools

Tons of Fun with Windows Media Encoder

I’ve been wanting an easy way to capture screen demos and audio for a while and after stumbling across Jon Udell’s post on Movies of Software, I thought I’d give Windows Media Encoder a try. Here’s what I learned:

  • I really like giving short little vignettes imagining an audience; I didn’t think I would
  • The preparation for recording a screen demo is the same as a real demo, i.e. I want to make sure I know what I’m going to demo before I do it
  • The preparation does not include lighting or another person to run a camera or a microphone, which means that I can do it on a whim at 5am on a Saturday morning
  • My built-in mic at normal speaking volume works great
  • Capturing a particular screen doesn’t work very well because I’m likely to move between windows without knowing that I will ahead of time. Instead, I should capture a region of the screen, ideally something not too large so that it fits well in a video window
  • Medium quality may not be good enough. I did 13 minutes at medium quality, which resulted in a 3MB file and good audio, but the screen itself was nearly unreadable. Maybe the screen itself was too big?
  • Stop other apps before capturing a screen, otherwise you’re bound to get slowdowns in the capture, particularly in the audio
  • Talking in my kitchen at normal volume for 13 minutes will waken my wife (sorry, sweetie)

So, while I wasn’t happy with the results, I’m very jazzed about the medium. Expect to see more.

November 4, 2004 tools

Distributed Shared Always On Message Queue Service

Here. Jeff Barr of Amazon has just informed me that Amazon now provides a distributed, shared, always on message queuing service which allows you to create and delete queues, enqueue, read and dequeue messages that can stay put for as long as 30 days. It’s free right now and I don’t quite know how it will be used for porn and spam, but I have every confidence that you guys will figure it out. : )
November 4, 2004 tools

Jon Udell Knocks My Socks Off With Dragon Naturally Speaking 8.0

I’ve never really seen anyone use speech recognition for real and after watching Jon Udell use Dragon Naturally Speaking 8.0, I’m flabbergasted. I had no idea working with it could be so natural. Wow.
November 1, 2004 tools

MaxiVista: Changing My Mind About Tablets

When I first read about MaxiVista, the thing that really got me interested was that it gave me two things that I really want from my Tablet PC. The 1st is to be able to use a slate-only Tablet as a 2nd monitor for my laptop so that I can continue my addiction to keeping my whole life on a laptop, but still be cool like the other kids (I’ve so far avoided multi-monitor setups because I love my laptop too much and I was afraid of the conflicting addictions).

The 2nd thing I get is a result of the first, i.e. if I’m going to use the Tablet as an adjunct to my laptop, then I shouldn’t worry about a generation sometime in the future where Tablet convertibles can replace my laptop, but just get the best slate I can find and enjoy it as a remote viewer/editor of info via file sharing and terminal services.

If you have a device you’d like to turn into a 2nd monitor and you don’t yet have MaxiVista, Scott Hanselman’s posted a 30% off MaxiVista coupon.

October 17, 2004 tools

I’m With Jim: X1 Rocks

Like everyone else in the blogespher, I installed Google Desktop Search last week. And, after using it a few times, I’ve uninstalled it. Jim’s right; X1 kicks its butt.
October 15, 2004 tools

Channel9: More Monad

I haven’t even seen this yet and I want to recommend it. I’m just a big monad and Jeff Snover fan.
October 14, 2004 tools

re: Business Object Design tools question

Today Ralph Loizzo asked me what tool I use to outline my objects, to which I replied:

The tool I use most often to design my systems is a text editor. I write my client code first against the objects I wish I had to obtain the first order of functionality I’m after, then implement those classes and refactor til I’ve reached a state of happiness between the clients and the object model.

In this age of development methodology du jour, I assume my methodology already has a name, but today I dubbed it CDD (Client-Driven Development). Also, I don’t distinguish between client UI code and lower-level code, i.e. just as often as I write lower-level code against an imaginary OM, I design my UIs first, then implement an OM to enable the UI.

Over the years, I’ve become less and less of a fan of the idea of componentizing the functionality you think the higher levels are going to need, as it often results in over-engineering. Instead, I prefer just-in-time engineering, refactoring my design as I need new or different functionality, whether in the client during the initial development stage or during the maintenance stage.

Test Driven Development is very similar to Client-Driven Development:

  • TDD: writing the tests first and writing your code til the test pass
  • CDD: writing the client first and writing your code til the client has the functionality it needs

It may even be that CDD is a degenerate case of TDD where the test” is the client seems to work.”

October 2, 2004 tools

Mixed Feelings

For the last few months, I’ve been doing some really cool work with a group of folks whose only task is to build apps that exercise the WinFX technologies so that we can make sure stuff works the way we want it to and give feedback to the product teams when it doesn’t. Because we’re still in preview technology land, various features that we want to test are in various builds of each part of WinFX, so we’re constantly fooling around with new combinations of the bits, which we bring together in VPC HD images and that I then have to download. Since I’m downloading the 7+ GB images from my house over VNC and since the internal VNC connection software isn’t quite as robust as the VNC software we ship to the rest of the world, that means that I’m constantly being kicked off of my connection and reconnecting, sometimes 2 or 3 dozen times over the 2 days it takes me to download the image. I just finished downloading another build today.

Unfortunately, when setting the Administrator password, I managed to enter the wrong thing twice, which meant that I had no way to log into my new VPC image after 2 days of hard labor getting it to my house. So, instead of re-downloading it again, I googled for a utility to reset the Administrator password. The first link was a knowledge base article from MS that didn’t help me because I hadn’t yet logged in to make myself a password reset diskette (which, frankly, I never do anyway). The second link was a list of completely unsupported, possibly illegal, tools to reset the Administrator password. The first one on that list worked like a charm in several orders of magnitude less time than downloading a new VPC image.

So, now I have mixed feelings. On the one hand, I’m happy that I didn’t have to go through all that trouble again, but on the other, I doesn’t seem very useful to set my Administrator password to anything useful if I anyone with physical access can just reset it so easily. Of course, Keith Brown and other security experts have been saying that physical security is paramount for any other kind of security to be affective, but it was kind of unsettling to have the point driven home so starkly.

September 23, 2004 tools

Very Much Enjoying .NET Rocks Lately

DNR goes up and down like every other media outlet (it’s not unlike this very web site in that way), but I’ve really been enjoying it muchly lately. Not only did I get to hear someone besides my normal brethren talk about CAS in a way that didn’t make my flinch (Don Kiely on developing with least privilege), but I also got to listen to Mark Miller talk (at break-neck speeds) about my Dad freaking out when the jelly got into the peanut butter at the same time he was enthusing about CodeRush and telling Rory that he didn’t need counseling to deal with his relationship problems, he needed penicillin. Fabulous.

September 21, 2004 tools

Giving a Mapped Drive .NET FullTrust

Lately, I’ve been running Virtual PC a lot to test various versions of WinFX on various platforms. To save me for locking any valuable code into a VPC HD, I use VPC shares, mapping Z to the D HD on my VPC host PC. That’s all well and good til I try to load a project from Z which, according to the OS, is a mapped network drive (in spite of the fact that it’s just the other partition on the very same PC), and Visual Studio complains that since I don’t have FullTrust on that drive, things may not work out the way I’d hoped (and for whoever decided to write the code and put up that message box, thank you!):

The project location is not trusted.
Running the application may result in security exceptions when it
attempts to perform actions which require full trust.

What’s happening is that VS is detecting that the project on the network drive is getting Intranet permissions according to the good and true workings of .NET Code Access Security (CAS). However, since I’m just trying to pretend that Z is on my PC (and, in fact, it is), I want it to have FullTrust permissions. To accomplish this, you need to add a new Code Group with an URL membership permission specifying the folder (in URL form) to which you’d like to grant full trust. You can do with the .NET Framework Configuration tool or you can do it from the command line like so:

c:\>caspol -q -machine -addgroup 1 -url file://z:/* FullTrust -name "Z Drive"

Once this new code group is in place, any new .NET processes you start will give any assemblies on the Z drive full trust (make sure to cycle the devenv.exe process if you want these new permissions and that message box to go away).

Since awarding new permissions, full trust or not, to any chunk of code is something that can cause a security hole, be careful. In this case, I’m awarding full trust so that Z acts just like a normal HD which has full trust by default, so I’m OK. Please make sure that you’re OK before adding permission via code groups willy nilly.

September 20, 2004 tools

Windows Command Shell Partner Drop 3 Available

For Windows Command Shell (aka MSH aka Monad) users, Partner Drop #3 was just posted today on http://beta.microsoft.com. So far, all I know is that it fixes 45 internally and externally reported bugs, but it’s nice to know that things are moving along on the first new shell we’ve had since NT 3.1.
September 10, 2004 tools

Windows Forms 2.0 Rocks The House

Joe Stegman shows off the ability of Windows Forms 2.0 to build very professional looking UIs, including clones of MSN Messenger, MS Money, IE and Outlook, all using out of the box controls. In particular, IE was implemented with 10 lines of non-Designer code. Whoa. I can only assume that the Windows Forms team will ship these code samples on windowsforms.net ASAP. Recommended.
August 16, 2004 tools

Dealing with Programmer’s Block

A friend of mine IM’d me just a few moments ago and asked, When you’re sitting in front of a code editor and you have no motivation, what do you do?”

I hereby dub this programmer’s block” and since I’ve never had it (which I’m just now realizing is pretty weird), I wondering if you can offer my friend some advice. Thanks!

August 16, 2004 tools

Good Idea: Builders in Visual Studio Code View

Good Idea: Builders in Visual Studio Code View

I really love Mitch’s idea for a Builder” in the Visual Studio Code View:

There are tons of hidden strings in code that would benefit from such a thing, e.g. data provider-specific connection and query strings, and I’d gladly rebuild my FormatDesigner as a Builder. I wonder if the VSIP SDK is powerful enough to implement it…

August 16, 2004 tools

MSDN TOC Right From The IA’s Mouth

Have you got opinions about how information is arranged on MSDN? Do you have issues with the Table of Contents? Are you just looking for some way to fight back against the machine? If so, check out Paula Land’s blog.

Paula is MSDNs Chief Information Architect and she’s provided a sneak peak at MSDNs new TOC. If you’ve got comments, now’s the time.

July 23, 2004 tools

Tim and His Angle Brackets

Tim Ewald, one of my closest friends and the guy I think deserves to be much more famous (the first chapter of his criminally under-selling Transactional COM+ is worth the price of a Hawaiian honeymoon and is just as fulfilling) is blogging.

In fact, he’s been blogging for a few weeks now, but he’s teased me before, so I didn’t want to point people his way if he was just going to break my heart again. Still, he seems to be on a roll. My most favorite post is XmlSerializer sans XSD, but his recent post on why he cares about the angle brackets on the wire pushed me over the edge.

Don’t disappoint us by going away again, Tim!

BTW, Roger Searjeant built some tools to support Tim’s ideas.

July 21, 2004 tools

Tim Sneath On The What’s New in WinForms 2.0

Tim Sneath has a nice, concise list of what’s new in Windows Forms 2.0. By far and away, ClickOnce deployment as an order of magnitude improvement over No-Touch Deployment is my favorite advance, but the new controls are cool (you can drop the standard buttons on the menu and toolstrips from the context menu), the BackgroundWorker is very cool (and eliminates about 2/3rds of the code in my threading chapter) and the designer layout assistance for helping with the layout and spacing of controls sounds like it’ll reduce a bunch of monkey work in the designer.
July 13, 2004 tools

Refactoring C# Code Using Visual Studio 2005

Cool piece by Andrew Troelsen on the new refactoring features in Visual Studio 2005 for C#. Now I just have to train myself to think to use the refactoring operations instead of letting my fingers do it as they’ve been forced to for lo these many years…
July 11, 2004 tools

Looking for Genghis Co-Khan

Right now, I’m holding the shared source Genghis library back. I’m acting as sole arbiter of what makes it into Genghis and how and I’m not able to keep up with the flow. I’m looking for someone who’s interested in sharing this duty with me. Only proven contributors to the Windows development community need apply.
June 29, 2004 tools

Lots of Fun Visual Studio 2005 Beta 1 Stuff

MSDN shipped their part of Visual Studio 2005 Beta 1 at about 12:30am on Tuesday morning. Sara has a nice summary of the new MSDN Product Feedback Center that I think folks will find particularly satisfying:

At the MSDN Product Feedback Center, you can submit bugs and suggestions. You can search through other people’s submitted bugs and suggestions. You can vote for your favorites. You can share workarounds. And, you can see feedback and details directly from folks on our product teams. Oh, and you can get notified when the status of an issue you’re interested in changes.”

In other words, developer feedback to the product teams for the supported products is no longer just an email or a post, but an entry in a database that the product team and you can track. I can’t wait to get this for Longhorn.

Also, Kent has announced the new Visual Studio 2005 Developer Center, complete with next-gen personalization features that we’re testing on this content before we push them out site-wide. My favorite part of the site is the bit where the product teams that contribute to .NET 2.0 point out what’s new (and the Windows Forms team even tell you how they’re progressing on the features they’re implementing).

Kent also points out the site for the new Visual Studio 2005 Express Edition, the beta of a slim and trim VS05 for students, hobbyists, etc. that you can download immediately. There’s even a contest for Express users where the prizes include an XBox and a copy of Halo 2.

Duncan also has a post where he addresses our current philosophy on coverage of shipping vs. future content on MSDN and why TechEd is going to throw it out of whack” for a while (except me, of course, who’s going to be out of whack for a good long time : ).

NOTE: Beta 1 of Visual Studio 2005 will not install on Longhorn. Hopefully the next community drop of Longhorn will include a matching drop of VS05, but as of today, they remain incompatible.

June 26, 2004 tools

The Good Bits of STL in .NET 2.0

I look at Krzysztof Cwalina’s post on delegated-based APIs in combination with generics and I think of the best parts of STL-like template-based programming without all the STL or templates causing the blinding pain just behind your eyes.
June 20, 2004 tools

More On The VC# 2005 Key Bindings

Joe Nalewabau has one very important addition point to make about the new key bindings in Visual C# 2005: while the VC# team will be providing a bunch of key bindings based on how things are arranged, e.g. Ctrl+W, S to show the Solution Explorer from the Window menu, 90+% of the old key bindings will continue to work, e.g. Ctrl+Alt+L to show the Solution Explorer. I worry that the 90% coverage won’t be like uptime, where 90% is generally just fine, but more like speech recognition, where anything less than 99.9% just bugs people. I’m keeping my key bound fingers crossed…
June 18, 2004 tools

The VS Keybinding Randomizer Is An Actual Person

Joe Nalewabau, a Lead PM on the Visual C# team, admitted today that he was responsible for the VC# keyboard randomization process for Visual Studio 2005 and describes the thought process that he went through to get there. I admit that Joe makes a good case for changing the key bindings, but I hate the idea of learning a whole new set (especially since, because I’m a keyboard boy, I’ll be crippled until I learn the new bindings). If Joe would swear on a stack of user manuals that the key bindings would never, ever change again, I’d be happier about it. (Rocky: Again? That trick never works!” Bullwinkle: This time fur shure!“)

Of course, what I think doesn’t matter (it stopped mattering when I signed that damned employment contract : ). It’s what you think that matters and you should feel free to let him know what you think about the new VC# 2005 key bindings.

June 5, 2004 tools

Leaked Image of VB.net Context Menu

The great thing about multiple language teams in .NET is that each team can provide tools specific for their audience, like this leaked image of the Visual Basic 2005 context menu.

[via Don Box]

May 30, 2004 tools

Replicator v0.1

I’m not sure what I would make if I had one of these, but that doesn’t stop me from wanting one.
May 28, 2004 tools

On Threat Modeling

Lately, when the subject about how to actually secure a .NET app or component comes up, a magic phrase is uttered: threat modeling.” Apparently, this is the thing that tells you how folks could use your well-intentioned code to do bad things. And on a mailing list with a fairly select membership (although not too select — I’m on it : ), the Swiderski, Snyder book Threat Modeling was recommended. And the free threat modeling tool that goes along with the book is hosted right on microsoft.com, which I take as a sign of quality. Model those threats towards a happier, healthier you!

[via Pierre Nallet]

May 25, 2004 tools

.NET Framework 2.0: BindingList

After spending a bunch of time with various partial IBindingList implementations, I just stumbled onto a brand new one in the Visual Studio 2005 Community Technology Preview: BindingList. It’s not done yet, e.g. sorting doesn’t work, but the model is certainly what you’d want, e.g. you create a BindingList, bind it to something smart, like a DataGrid or a DataGridView, and you’re able to edit instances of your custom type or add or remove instances, as well as search or sort instances, just like you’d need a custom implementation of IBindingList for today. Very nice.

May 24, 2004 tools

A Gathering of VS05 Team System Info

I find that in the process of learning about something, I often dig through a lot of places before I come up with what I’m looking for.

In the case of Visual Studio 2005 Team System (aka Burton”), I wanted to know a lot more about the features that MS was building into VS for teams, including much more flexible source code control integration, web site functionality and stress testing, static code analysis like FxCop and perf. analysis built right into the build system and stats recording as part of the normal workflow for project management reporting.

In the process of gathering these details, here are the places I went:

Here are some things that tickled my fancy:

  • Data binding to drive web site testing. I want the same thing for stand-along client testing
  • The real-time stats and drill-down for ongoing web site stress testing
  • Building static code analysis right into the build process so that I can fix those issues along with my compiler issues
  • The idea of collecting project stats as part of what the developer is doing in VS and using those to roll-up conprehensive stats for the whole team
  • Seeing our own internal tools, like PREfast, made available to our customers and integrated so nicely into VS
May 14, 2004 tools

Chad on the Visual Studio Team Wants To Meet You

Chad says:

You are important to me! You spend your money and time on VS, and you expect VS to help you make more money and time. You will be using Whidbey to make your living, paying for braces and college and retirement, buying coffee and beer and cigarettes, contributing to political and social causes, paying income taxes and mortgage interest, ordering pizza and books and flowers.”

Chad wants you to send him your picture and some info so that he can show his VS team that their customers are real folks. I sent him mine; I may be an MS employee, but I’ve been using Visual Studio non-stop since it was called QuickC and I care what those guys do with my development environment of choice!

May 7, 2004 tools

More Free WIndows Forms Controls:vbAccelerator

After posting a few sets of free Windows Forms controls, now I’m a magnet for the but you forgot my favorite free controls site” emails, which I feel compelled to share with you. This time, it’s the vbAccelerator site, which is a mix of VB6 and .NET controls, code and tools. The .NET stuff is here. Enjoy.

May 6, 2004 tools

Kent Sums Sums Up the P/Invoke Add-In Nicely: Whoa

Adam Nathan has taken the information from his extremely popular P/Invoke Wiki site and built an add-in to pull and drop P/Invoke signatures directly into VS.NET. Whoa, indeed.
May 5, 2004 tools

FileDisassembler Add-In for Reflector 4.0

It turns out that the add-in model for Reflector 4.0 is so powerful that it enabled Denis Bauer to build an add-in that leverages the built-in R4 disassembler to disassembly an entire assembly into source code files. Very handy for curling up on a sunny afternoon with a chunk of source from your favorite assembly, a cigar and a single malt Scotch.
May 2, 2004 tools

More Free WIndows Forms Controls:xpCommon Controls

And the hits, they keep on coming
May 1, 2004 tools

NetXP: More Free Windows Forms Controls

Roy points out some Windows Forms controls that Mike pointed out to him and now I’m pointing out to you: NetXP, which includes all kinds of fun controls and components for use for free for personal and freeware use. It’s amazing the number of high-quality free .NET controls exist. Wahoo!
April 19, 2004 tools

PInvoke.NET: Interop the Wiki Way

Here. Whoever put this site together had the right idea. I was hoping to work my magic to get MS to publish a giant interop DB, but instead of waiting, Adam Nathan (of .NET and COM: The Complete Interoperability Guide fame) put up a wiki to collect all of the P/Invoke signatures that the community already knows about. Yeah, baby! This could finally be a wiki I can get behind! (Sorry, Ward, but I’ve just never found a wiki that makes me want to hang out there…)
April 6, 2004 tools

Son of Strike Debugging Inside Visual Studio .NET

Here.

In his June 03 Bugslayer column, John Robbins made a sideways comment when discussing Son of Strike (SOS), a debugging extension from Microsoft for doing all kinds of low-level, mixed native and managed code debugging.

What Jon said was this: Interestingly, starting with Visual Studio® .NET 2003, you can load SOS when doing mixed-mode debugging.” And then he didn’t say how to load SOS into VS.NET, even after spending the rest of the article telling us how cool SOS was.

Luckily, Mike Stanton, an SDE on the CLR team, has created a set of instructions for loading SOS into VS.NET. Actually, he posted those instructions in December of last year, but it wasn’t til today that they were accurate because it wasn’t til today that I tried them and couldn’t get them to work. Now they are and I can and I have all kinds of low-level goodness to explore with Son of Strike.

April 5, 2004 tools

WiX: Open Source XML-Based MSI Creation

Rob Mensching, an MS SDE, has finally released his WiX tools for building MSI files from XML. I say finally,” because I’ve been using his tools for months to build the MSI files that MSDN puts up on microsoft.com/download. All of our downloads have to be wrapped in an MSI so that you have to agree to the EULA before you get the files. Plus, we need to bundle some descriptive text and author name in there, along with the code that pops open the install folder after the files have been installed. Instead of using VS.NET to create the MSI files for each set of folks, I built a tool and the best programatic interface to creating MSI files that I could find was easily Rob’s. Check it out.

April 2, 2004 tools

FxCop for SQL Server

If you were listening to the .NET Rocks show today, you heard me invent something that Microsoft has already shipped: The Microsoft SQL Server Best Practices Analyzer. One less thing I have to build myself. : )
March 30, 2004 tools

Visual Studio 6 SP6

I used to live and die with Visual Studio Service Packs and the DevDiv Sustaining Engineering team has just released another SP for you Visual C++ 6 and Visual Basic 6 programmers. Millions of folks still use these products and it warms my heart that we’re 2.5 generations past this, but still releasing SPs. I don’t anticipate any more of them, though, so I recommend using this SP for your current projects and moving to Visual Studio .NET 2003 or Visual Studio 2005 on the next one, depending on the timing.
March 25, 2004 tools

Web Site Dedicated to Extending VS.NET

I swear I only stopped reading blogs for a coupla days, but interesting news has just surged! For example, I just found out that MSDN has an entire web site dedicated to extending VS.NET. This includes the legendary VSIP and a set of extensions that lets you build VSIP packages in managed code. Very cool.

[via Visual ActiveKent Sharkey .NET SE 3.11]

March 25, 2004 tools

VS.NET Whidbey Has a Command Shell Window Built It

It’s well hidden, but Jason Olson points out that VS.NET Whidbey finally has a command shell built right in. Now if only it changed folders with my solution and support completion via the tab key, support F7 and F8

March 24, 2004 tools

Very Cool Web Service Testing Tool from Mindreef

I knew Mindreef had cool testing tools, but I just found one today on their web site that I ended up using all afternoon. You feed it a WSDL URL and it generates a form, allowing you to see the SOAP request and response packet in several formats include raw XML, to pseudo-code, pretty-printed XML and tree. It’s much more flexible then the built in one that ASP.NET provides and the price is right.

March 10, 2004 tools

The VS7 Debugger doesn’t work. What can I do?

Mark Parks, a PM on the Visual C# Debugger QA team, has posted ways to fix common VS.NET debugger problems. He’s even got a fix for why I can’t debug the localhost version of my site. Thanks, Mark!

[via Duncan Mackenzie]

March 9, 2004 tools

Genghis v0.5 Released

After much delay (man, this Microsoft gig keeps a person busy), I’m happy to announce Genghis v0.5:

  • New HtmlLinkLabel class from Jeff Key that knows how to launch IE and EXEs directly w/o requiring you to handle the event
  • Much prettier images in SimplePad from Chris Burrows
  • Updated MRU code from Michael Weinhardt to match .NET event signature conventions and to fix a problem when using more than one MRU components on a single menu
  • Updated FileSearchEngine code from Mike Marshall to check for whole words at beginning and end of line correctly
  • Updated validation code from Michael Weinhardt with support for validating controls at a container level, e.g. validating controls on a tab instead of on an entire form
  • New gradient progress bar from Mike Marshall
  • Updated FileDocument from Chris Sells to match text of Windows Forms Programming to include more MFC-like features like a pluggable scheme for serialization handling, registration of document extension with the shell, and adding to recent docs, i.e. Start->Documents
  • Updated HandleCollector from Ethan Brown to work with .NET 1.0 and .NET 1.1
  • Performance enhancements from Ethan Brown in the MappedDrives and SystemShares classes
  • New user-resizable panel from Ethan Brown
  • Updated WebCommandLineHelper from Andrew Duncan to fix System.IO.FileLoadException in ieexec.exe
  • Updated AniForm from Mike Marshall to support stacking ala SharpReader and fix a terminal server-related bug
  • Updated cool menu sample from Chris Burrows with additional support for abstracting commands from click even handlers
  • Enjoy.

    March 5, 2004 tools

    Reimplementing Mike’s cmdline Utility using WMI

    Here.

    In early 2000, Mike Woodring moved Heaven and Earth to write a tool that would inject a DLL into a process’s memory for purposes of finding the command line with which the process was launched. While hanging around Don and Tim this week, Don was all hot on WMI, so we fired it up in .NET and rebuilt Mike’s tool like so:

    using System;
    using System.Management;

    class
    cmdline {
      static void Main(string[] args) {
        if( args.Length != 1 ) {
          Console.WriteLine(“usage: cmdline );
          return;
        }

        ManagementObject obj =
          new ManagementObject(string.Format(“Win32_Process.Handle="{0}\“”, args[0]));
        Console.WriteLine(obj.Properties[“CommandLine”].Value);
      }
    }

    This makes WMI pretty darn cool in my book. I’ll be reading Jon Fancey’s article on WMI + .NET in the latest MSDN Magazine.

    BTW, I have to admit that I’m nowhere near as manly as Mike. I’ll take this sissy code any day. : )

    February 23, 2004 tools

    Genghis v0.5 On the Way, But Baby First

    Here.

    For those folks asking, another drop of Genghis is on the way, which includes an HTML link class that handles links for you, a user-sizeable panel, a gradient progress bar, a completely revamped FileDocument and a host of fixes and enhancements, including stacking support and terminal server support for toast windows. However, before that can come, Mike Marshall, the Genghis build-master, stopped to email me about the impending arriving of his first child. Now *that’s* dedication! I doubt if I’d stop to email any of the folks in charge of the shared source projects I’m involved with on the way to the hospital… : )

    February 17, 2004 tools

    The Facts About The Windows Source Code Posting

    MSs official word on what happened with the illegal source code posting and what we’re doing about it.
    January 9, 2004 tools

    My First .NET Tool Gets An Update

    Here.

    Given Aaron’s wonderful set of .NET XML tools, I don’t know why Tony Malandain found my little xmlValid tool for checking XML well-formedness and schema validness, but he did and then added the ability to take XML input from stdin (he apparently uses it to check compressed SVG files).

    What makes this kind of unusual is that I built this tool almost 2.5 years ago. In fact, it was the first .NET tool I posted on my site. Before that, it was all C++ and COM, although almost none of that has gone up since. It was kind of fun digging into that code again. I spent a bunch of time rearranging it to map more closely to my current .NET coding style not because it added any more functionality but because I couldn’t stand not to. This developer thing is just a sickness, isn’t it? : )

    January 2, 2004 tools

    ImCli Classes Updated for MSNP8

    Here.

    Plenty of folks have asked for updates to my IM client classes to support the new MSNP8 protocol, but only Robert M. Wagner Jr. made the changes and sent them to me. Thanks, Robert!

    December 9, 2003 tools

    Learn the new VC++ from the master

    I used to brag that, unlike most C++ programmers, I learned C++ directly from the CFRONT 2.0 release notes and not from Stanley Lippman (his C++ Primer is a key part of C++ canon law). That boast came to a screeching halt when I had Stan in one of my COM courses and he revealed that he’d written the CFRONT 2.0 release notes.

    And as if teaching the world C++ wasn’t enough, now that he works at Microsoft on the new Visual C++ and it’s new support for the .NET Framework in Whidbey,” he’s started a blog to teach the world now only how VC++’s new tracking handle syntax (aka hat”) but more importantly to point out *why* the VC++ went in this new direction.

    And I can’t imagine someone I’d rather learn it from.

    November 26, 2003 tools

    WinForms SDI and MDI wizards?

    Here. I noticed that Stephane Rodriguez put an SDI and MDI wizard up on CodeProject. I’ve been *dying* for those forever, but I couldn’t get his to work. Anyone come up with a simplified set up for them? Anyone interested in porting them to Genghis?
    November 26, 2003 tools

    WksSync Updated

    Here. Ethan Brown has done a massive update to the wkssync tool, the command line tool for accessing source from GotDotNet workspaces. Thanks, Ethan!
    November 25, 2003 tools

    ADO.NET CSV File Tester

    Here. I wrote CsvFileTester to explore the ADO.NET/ODBC/JET support for CSV files and I was amazed at how comprehensive the support was. And, since I can never remember the syntax and limitations between one use of Jet expression syntax and the next, I put a bunch of samples into the program itself.
    November 25, 2003 tools

    ADO.NET CsvFileTester

    ADO.NET 
	CsvFileTester

    CsvFileTester is a tool inspired by Shawn Wildermuth’s ExcelFileTester, which he wrote cuz I kept asking him how to do queries on .xls files. However, because the Excel query language has no where or order by clauses, I gave that up in favor of comma-separated text files.

    I wrote CsvFileTester (with Shawn’s help) to explore the ADO.NET/ODBC/JET support for CSV files and I was amazed at how comprehensive the support was. And, since I can never remember the syntax and limitations between one use of Jet expression syntax and the next, I put a bunch of samples in the combobox.

    Enjoy.

    November 7, 2003 tools

    The Visual C++ Team Wants You!

    Here. The VC++ team has a bunch of cool work they need doing and they’re looking for candidates. Don’t be shy. Apply today! And if http://microsoft.com/jobs is too slow for you, feel free to send your resume and a bottle of Scotch (OK, that last part is optional : ) to Terry Leeper, a friend of mine on the VS team desperate for help: tleeper@microsoft.com.
    November 3, 2003 tools

    XmlSerializer Workshop

    Here. Simon Steele has posted a most excellent tool for digging through an assembly of .NET types trying to build XML serializers for them. This helps you to figure out which classes are going to succeed at design-time instead of at run-time and shows you what’s wrong. Much cooler than my silly command line app. Thanks, Simon!
    October 25, 2003 tools

    Another .NET Regular Expression Tool

    Here. Regular Expressions seems a popular thing to build a tool around. The Regular looks cool. They all look cool. Why weren’t any of these tools around when I started building RegexD?!?
    September 6, 2003 tools

    Are You Missing Out on Code Generation?

    Here. Oh, sure, I built an entire codegen product a number of years ago. Would it have hurt folks to get excited about it then?!? : )
    August 6, 2003 tools

    .NET FormatDesigner

    .NET FormatDesigner

    FormatDesigner is an application to experiment with the format strings used to format data in String.Format and various type’s ToString functions.

    Click here to launch the application directly (requires the .NET Framework 1.1).

    Click here to download the source code.

    Enjoy.

    July 29, 2003 tools

    *Free* (as in beer) Access to VSIP!

    Here. Register to become a Visual Studio Industry partner and get FREE access to the VSIP SDK. As a VSIP you will have access to the technology, private newsgroups and secured technical content to assist you in seamlessly integrating your tools, components, and languages into the Visual Studio .NET IDE.” Everything you always wanted to do to integrate seamlessly into VS.NET used to cost money. As of todays, it’s free! Wahoo!
    July 7, 2003 tools

    Regular Expression Workbench 2.0

    Here. While I don’t think it’s as pretty, Eric Gunnerson’s RegexW has some cool features I wish RegexD [1] had, like regex->English translation and menus for regex parts. Anyone want to merge the best of both into some uber regex tool? [1] http://sellsbrothers.com/tools/#regexd
    July 7, 2003 tools

    Genghis Moved to GotDotNet Workspaces 1.0

    Here. Now that GotDotNet Workspaces 1.0 has shipped (congrats!) Mike has moved Genghis there. Feel free to apply for membership if you’ve already contributed source to Genghis or if there’s something you’d like to add.
    July 1, 2003 tools

    Spout: Learning to Learn

    Here. The one where I talk about the most important thing I ever learned.
    June 18, 2003 tools

    XmlSerializerPreCompiler

    Here. Tired of the XmlSerializer’s generic File or assembly name ctewkx4b.dll, or one of its dependencies, was not found” exception? The XmlSerializerPreCompiler tools checks to see if a type can be serialized by the XmlSerializer class and if it can’t, shows the compiler errors happening behind the scenes so that the type can be modified. Enjoy.
    June 18, 2003 tools

    XmlSerializerPreCompiler

    Tired of the XmlSerializer’s generic File or assembly name ctewkx4b.dll, or one of its dependencies, was not found” exception? The XmlSerializerPreCompiler tools checks to see if a type can be serialized by the XmlSerializer class and if it can’t, shows the compiler errors happening behind the scenes so that the type can be modified. Enjoy.

    This just in: Mathew Nolton has posted a GUI front-end to my XmlSerializerPreCompiler that you might find useful. Thanks, Matt!

    June 13, 2003 tools

    Filter Files With Unknown Extensions For XP

    The fact that Windows XP Find in Files only searches files with known file extensions drives me crazy because it skips, among other things, .cs  files. Every time I set up a new system, I have to re-figure out how to fix this. To facilitate that, I put together a .reg file that will search all unknown file extensions as text files. Enjoy.

    June 3, 2003 tools

    SQL Buddy

    Here. I got turned onto this tool internally and I love it. It installs simply, works intuitively and allows for easy ad hoc queries and commands. Recommended.
    May 7, 2003 tools

    Genghis v0.4

    Sorry for the long wait. There’s been two whole books written between the last release of Genghis and this one. Here’s the list of new features:

    • Everything works under .NET 1.0 and 1.1 (except HandleCollector)
    • MSN Messanger-style popup window
    • UI Type Editor for use with ImageList index selection
    • AppBar implementation
    • Text file search
    • Themed controls
    • Single instance application support, including passing command line args from other instances
    • Multiple top-level window support
    • Many enhancements and fixes to the command line parser
    • Splash screen class
    • Improved WebCommandLineHelper class which now works with .NET 1.0 and 1.1, includes URL decoding and requires no additional permissions (although it does require a server-side HTTP handler, included as the ConfigFileHandler class that maps requests for foo.exe?bar=quux.config to the foo.exe.config file)
    • WizardSheet updates
    • Status Bar Extender for mapping status messages to Windows Forms controls

    Thanks to my new build master, Mike Marshal, who got all of this together. He’s the greatest!

    April 24, 2003 tools

    NAnt 0.8.2 released

    Here. From Matthew Mastracci: NAnt 0.8.2 was recently released. Note that this release has support for both the Microsoft.NET framework v1.1 and Mono. See the download link above or the NAnt homepage: http://nant.sourceforge.net/
    April 17, 2003 tools

    Hello IDispatch Lovers

    I’m probably jumping into this topic a bit late but it doesn’t seem to end. I admit I haven’t read all article in this thread but I think I have an implementation solution for multiple dual interfaces on one class. And I would like opinions on it from others as well, and as to whether or not it displays proper COM implementation.

    The implementation is very much like one that has been posted earlier, which I’ve seen different variations of many times before. However, I feel the one I am presenting allows all dual interfaces to be on one object and accessible via scripting without explicitly asking for a piece. No new interface definitions will be necessary with this technique. However, there may be one flaw. It will work ideally when none of the dispid’s of any of the dual interfaces collide, and when none of the named functions collide.

    I consider a collision when the dispids,or names are equal, but the parameter list/type are not. Even still, when they do collide, the implementers using this technique can choose which should take priority.

    Using ATL, I defined a templated class which should be derived by the class that exposes multiple dual interfaces.

    template
    class XMultiDualImpl : public IDispatch
    {
    public :
    typedef tihclass _tihclass;
        void Add( UINT uiIndex, LPDISPATCH pDisp, _tihclass & tih)
        {
            ASSERT( t_uiNum > uiIndex-1 && uiIndex>0 );
            m_arrDispImpls[uiIndex-1] = pDisp; //no need to addref, pDisp==this
            m_arrpTih[uiIndex-1] = &tih;
        };

        STDMETHOD(GetTypeInfoCount)(UINT* pctinfo) {*pctinfo = 1; return S_OK;}
        STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo** pptinfo)
        {return m_arrpTih[0]->GetTypeInfo(itinfo, lcid, pptinfo);}
        STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR* rgszNames, UINT cNames,
            LCID lcid, DISPID* rgdispid)
        {
            /*perhaps the loop should check for a succeeded hresult instead*/
            HRESULT hr = DISP_E_UNKNOWNNAME;
            for ( UINT i=0; i < t_uiNum && hr == DISP_E_UNKNOWNNAME; i++ )
            {
                hr = m_arrpTih[i]->GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid);
            }
            return hr;
        };

        STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr)
        {
            HRESULT hr = DISP_E_MEMBERNOTFOUND;
            for ( int i=0; i < t_uiNum && hr == DISP_E_MEMBERNOTFOUND ; i++ )
            {
                hr = m_arrpTih[i]->Invoke( m_arrDispImpls[i], dispidMember, riid, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr);
            }
            return hr;
        } ;

        LPDISPATCH m_arrDispImpls[t_uiNum];
        _tihclass * m_arrpTih[t_uiNum];

    };

    As an example, if we were to implement an object with 3 dual interfaces we would do the following

    typedef XMultiDualImpl<3> XTriDualImpl ;

    class DispTest3 : public XTriDualImpl,
        public IDispatchImpl,
        public IDispatchImpl,
        public IDispatchImpl,
        public CComObjectRoot,
        public CComCoClass
    {
    public:
        DispTest3()
        {
            Add( 1,(IDispTest1*)this, IDispatchImpl::_tih );
            Add( 2,(IDispTest2*)this, IDispatchImpl::_tih );
            Add( 3,(IThirdIntfTest*)this, IDispatchImpl::_tih );
    }

    BEGIN_COM_MAP(DispTest3)
        COM_INTERFACE_ENTRY2(IDispatch, XTriDualImpl)
        COM_INTERFACE_ENTRY(IDispTest1)
        COM_INTERFACE_ENTRY(IDispTest2)
        COM_INTERFACE_ENTRY(IThirdIntfTest)
    END_COM_MAP()

    //IDispTest1 methods [code omitted for brevity]
    //IDispTest2 methods [code omitted for brevity]
    //IThirdIntfTest methods [code omitted for brevity]
    };

    I admit the constructor of the derived class leaves room for elegance.

    Basically, all QueryInterfaces for IDispatch will result in the XMultiDualImpl vtable. The IDispatch implementation for that vtable basically asks each IDispatch vtable (of the dual interface) in it’s array one by one if it can carry out the call. If it fails, it moves on to the next dual interface vtable.

    One might point out the following however :

    pUnk->QueryInterface( IID_IDispatch, (void**)&pIDispatch );
    pUnk->QueryInteface( IID_IDispTest1, (void**)&pIDispTest1 );

    pIDispatch->GetIDsOfNames does not have the same implementation as pIDispTest1->GetIDsOfNames. as well as the implementation differs for ->Invoke. I question whether or not that’s a problem. Since IDispTest1 derives from IDispatch, I could see why it may be.

    -herb

    April 17, 2003 tools

    Exposing Multiple Interfaces to Scripting Clients

    This page represents an attempt to capture the collective consciousness of the COM community. Of course, thoughtful feedback is welcome and encouraged (who the hell am I to voice the collective opinions of the entire COM community?). Once this is all sorted out, I anticipate never implementing IDispatch again (“Get COM+ now, I’ll show you how!“).

    This page attempts to answer the question:

    How do I expose multiple interfaces to scriping clients?”

    Why is this an issue? Because IDispatch is limited? No. It’s a problem because current scripting clients don’t support QI. Based on my observations of this list and my extensive conversations with members of the COM community, I see several solutions to this problem:

    1. Don’t try to expose the functionality of multiple interfaces to a scripting client.

    This is my favorite technique and was originally suggested to me by Keith Brown. He recommends using IDispatch to model the entire functionality of the object at a higher level than the individual interfaces, e.g.

    interface IRect : IUnknown
    {
        HRESULT GetCoords([out] long* pleft, [out] long* ptop,
                          [out] long* pright, [out] long* pbottom);

        HRESULT SetCoords([in] long left, [in] long top,
                          [in] long right, [in] long bottom);
    }

    interface I2DObject : IUnknown
    {
        HRESULT Inflate([in] long cx, [in] long cy);
        HRESULT Translate([in] long cy, [in] long cy);
    }

    // For scripting clients only
    [ hidden, dual ]
    interface _IRectangle : IDispatch
    {
        [propput] HRESULT Left([in] long left);
        [propget] HRESULT Left([out, retval] long* pleft);
        …
        HRESULT Inflate([in] long cx, [in] long cy);
        HRESULT Translate([in] long cy, [in] long cy);
    }

    An implementation would use the dual strictly for IDispatch purposes, i.e. vtbl-binding clients wouldn’t use _IRectangle:

    class CRectangle : …,
        public IRect,
        public I2DObject,
        public IDispatchImpl<_IRectangle, &IID__IRectangle,
                             &LIBID_SHAPESLib>
    {
    public:
    BEGIN_COM_MAP(CRectangle)
        COM_INTERFACE_ENTRY(IRect)
        COM_INTERFACE_ENTRY(I2DObject)
        COM_INTERFACE_ENTRY(IDispatch)
        // No entry for _IRectangle
    END_COM_MAP()

        // IRect methods
        …

        // I2DObject methods
        …

        // _IRectangle methods
        …

    };

    Since we’re no longer using interface-based programming, this technique allows full control when implementing the single interface the scripting client will see w/o having to worry about mapping every method of all of the interfaces. By using the dual strictly as a means of implementing IDispatch and not exposing it, your IDispatch implementation can evolve as your object functionality evolves, i.e. using another dual w/ another IID. While it’s still possible for a savvy developer to get a hold of the dual and try to implement it or derive from it, a slap on the forehead is generally enough to discourage this behavior.

    Unfortunately, nobody ever likes this technique because it forces them to provide client-specific implementation (which, btw, you’ll likely to have to do anyway…).

    2. Use the C++ MI trick.

    If you have n interfaces that are already [oleautomation] compatible, you can define a dual interface in IDL that is a union of all of the methods of all of the interfaces you’d like to expose methods from and let the C++ compiler match up the vtbls for you.

    [ oleautomation ]
    interface IRect : IUnknown
    {
        HRESULT GetCoords([out] long* pleft, [out] long* ptop,
                          [out] long* pright, [out] long* pbottom);

        HRESULT SetCoords([in] long left, [in] long top,
                          [in] long right, [in] long bottom);
    }

    [ oleautomation ]
    interface I2DObject : IUnknown
    {
        HRESULT Inflate([in] long cx, [in] long cy);
        HRESULT Translate([in] long cy, [in] long cy);
    }

    [ hidden, dual ]
    interface _IRectangle
    {

        // Copied from IRect
        HRESULT GetCoords([out] long* pleft, [out] long* ptop,
                          [out] long* pright, [out] long* pbottom);

        HRESULT SetCoords([in] long left, [in] long top,
                          [in] long right, [in] long bottom);

        // Copied from I2DObject
        HRESULT Inflate([in] long cx, [in] long cy);
        HRESULT Translate([in] long cy, [in] long cy);

    }

    The implementation derives from all of the interfaces and implements the union of the methods. The C++ compiler will fill in the vtbl entries for the dual interface using the methods you are already implementing for your non-dual interfaces, e.g.

    class CRectangle :
        …,
        public IRect,
        public I2DObject,
        public IDispatchImpl<_IRectangle, &IID__IRectangle,
                             &LIBID_SHAPESLib>

    {
    public:

    BEGIN_COM_MAP(CRectangle)
        COM_INTERFACE_ENTRY(IRect)
        COM_INTERFACE_ENTRY(I2DObject)
        COM_INTERFACE_ENTRY(IDispatch)
        // No entry for _IRectangle
    END_COM_MAP()

        // IRect methods
        …

        // I2DObject methods
        …

        // _IRectangle methods already implemented!

    };

    This method allows your clients to have access to the union of the methods of all of the interfaces that you have copied and pasted into your dual interface. However, now you’re left with the copy n’ paste dance in IDL and there’s no way to resolve name conflicts, e.g. IRect and I2DObject both have a method Foo() that is each meant to do different things. This method also requires you to define your non-dual interfaces with scripting clients in mind. Finally, this method also exposes the dual in the TypeLib to savvy developers (see the aforementioned forehead-slap solution).

    3. Use a typeinfo-driven implementation of IDispatch that provides a union of the methods of the scriptable interfaces.

    Daniel Sinclair provides another implementation of this technique called MultiDual, described in this online ReadMe.
    Herbert Carroll provides a similar implementation, but not based on typeinfo.
    Kjell Tangen provides another solution for by implementing a extended version of CComTypeInfoHolder.

    Imagine the following IDL:

    [ oleautomation ]
    interface ICowboy : IUnknown
    {
        HRESULT Draw([in] long nSpeed); // Conflicts with IArtist::Draw
        HRESULT Shoot();                 // Conflicts with ICurse::Shoot
    }

    [ oleautomation ]
    interface IArtist : IUnknown
    {
        HRESULT Draw([in] long nStrokes); // Conflicts with ICowboy::Draw
        HRESULT Paint();
    }

    [ oleautomation ]
    interface ICurse : IUnknown
    {
        HRESULT Shoot(); // Conflicts with ICowboy::Shoot
        HRESULT Darn();
    }

    library TURNOFTHECENTURYLib
    {
        coclass AcePowell
        {
            interface ICowboy;
            [default] interface IArtist;
            interface ICurse;
        }
    }

    The client would like to write code like this:

        ace.paint    ′ unambiguously IArtist::Paint
        ace.draw 100 ′ resolved to IArtist::Draw because
                     IArtist is [default]

        ace.darn    ′ unambiguously ICurse::Darn
        ace.shoot   ′ resolved to ICowboy::Shoot because ICowboy
                    ′ comes before ICurse in the coclass statement

        ace.icurse_shoot    ′ resolved to ICurse::Shoot because of prefix
        ace.icurse_darn     ′ prefix unnecessary but still works

    The typelib-based table-driven implementation would use the coclass statement to map calls to GetIDsOfNames and Invoke to the appropriate interface definition, doing a little pre-processing along the way to provide non-colliding DISPIDs for non-default interface methods and handling the prefixes to perform fully-scoped name resolution.

    Because the implementation is completely table-deriven based on the coclass statement, an aggregatable implementation of IDispatch that provided this amalgam behaviour could be implemented that only depended on the object to expose IProvideClassInfo. In fact, some members of this list have provided implementations of similiar techniques w/o, unless I’m mistaken, the name resolution scheme I’ve proposed above. Assuming such an implementation of IDispatch, the object implementation could look like this:

    class CAcePowell :
        …,
        public IProvideClassInfo
    {

    BEGIN_COM_MAP(CAcePowell)
        // Appropriate entries for nested composition of
        // ICowboy, IArtist and ICurse

        COM_INTERFACE_ENTRY_AUTOAGGREGATE(IID_IDispatch, m_spunkDisp.p,
                                          CLSID_StdAmalgamDispatch)

        COM_INTERACE_ENTRY(IProvideClassInfo)
    END_COM_MAP()

        …

    private:
        CComPtr m_spunkDisp;
    };

    Note: Assuming the implementation exposed the same DISPIDs for the methods and properties of the default interface as the default interface, early bound clients would be just as happy as late bound ones. And, because no dual interface is defined to implement IDispatch, there’s no worry of a developer getting a hold of the interface definition for the dual interface directly (although a slap is still warranted for those that try).

    4. Use a typeinfo-driven implementation of IDispatch that provides a collection of nested objects that implement the scriptable interfaces.

    Don and I implemented this technique at Tim’s house. It’s available here. Also, this has been updated by Serge Sandler for VC6 and for Win9x compatibility.

    Assuming the AcePowell IDL shown above, the client would like to write the following code (which performs the same as the previous client code):

        ace.paint    ′ top level object has all methods of
                     ′ [default] interface

        dim artist
        set artist = ace.iartist ′ Can QI for specific interface
        artist.draw 100

        dim curse
        set curse = artist.icurse ′ Simulated QI
        curse.darn

        dim cowboy
        set cowboy = curse.icowboy ′ Simulated QI
        cowboy.shoot

        curse.shoot
        curse.darn

    As you can see, we’re exposing a collection of objects where the top level object has all of the methods and properties of the [default] interface as well a property to obtain an interface pointer on a sub-object for each of the oleautomation interfaces. The sub-objects are separate COM identities whose implementation of IDispatch simply forwards to the main identity via the specific interface in question. Each of the sub-objects also have one property per interface to get to the other interfaces, thus simulated the rules of COM identity as exposed via QI. This allows us to build an invocation model very similar to VBs where QI is an assignment and references of type class mean references to the [default] interface.

    Parts of the implementation for this scheme have also been posted w/o, unless I’m mistaken, the full simulated QI as I propose above. The nested implementation of IDispatch could also be fully typelib-drived based on an object’s implementation of IProvideClassInfo and aggregated, e.g. using a clsid like CLSID_StdNestedDispatch.

    One alternative syntax that might be a bit more flexible is the following:

        ace.paint    ′ top level object has all methods of
                     ′ [default] interface

        dim artist
        set artist = ace.interface(“iartist”)

        if not artist is nothing then artist.draw 100

        dim curse
        set curse = artist.interface(“icurse”)
        if not curse is nothing then curse.darn

        dim cowboy
        set cowboy = curse.interface(“icowboy”)
        if not cowboy is nothing then cowboy.shoot

       if not curse is nothing then
            curse.shoot
            curse.darn

        end if

    This syntax makes it even more clear that we’re doing COM, it only requires one additional property (interface) and it’s easier to handle the QI failure case.

    5. Use a separate object to perform QI.

    This method is made real in an implementation by Dave Rogers, available at http://www.combatcom.com/adminstore/component-warehouse/thedispadapter.htm and Valery Pryamikov, available at http://home.sol.no/~valery Instead of building the pseudo-QI into the object itself, Valery uses another another object to perform the QI. This allows the client code to look like this:

        ′ Requires object to implement IProvideClassInfo or IPersist
        set dispenum.ObjectClass = ace

        ′ Doesn’t require IProvideClassInfo or IPersist
        ′ Note: Could use CLSID instead of ProgID
        dispenum.SetCLSIDObjectClass(ace, Ace.AcePowell.1”)

        Dim artist
        Set artist = dispenum(“iartist”) ′ Use disenum to perform QI
        If not artist is nothing then artist.draw 100

        Dim curse
        Set curse = dispenum(“icurse”)
        If not curse is nothing then curse.darn

        Dim cowboy
        Set cowboy = dispenum(“icowboy”)
        If not cowboy is nothing then cowboy.shoot

       If not curse is nothing then
            Curse.shoot
            Curse.darn
        End if

    This technique requires another object to perform the QI, so it seems a little weird, but the good news is that it works with existing objects. No recompile necessary!

    Now What?

    Given those techniques of implementing IDispatch to expose the functionality of multiple interfaces, the first two require no additional tool support. You can use them today. The last two, amalgam dispatch and nested dispatch, represent two models of exposing the functionality of multiple interfaces to a scripting client. Either model may be appropriate, but each is conceptually separate, i.e. the object implementor would pick one or the other.

    After writing the client code, I find I really like technique 4 best. It looks like COM to me. However, I can see that some folks would prefer technique 3 or 5.

    So, what do we do now? Do we wait for MS to ship COM+? We won’t see meta-information driven scripting until the turn of the millennia. Do we wait for MS to implement CLSID_StdAmalgamDispatch and CLSID_StdNestedDispatch? Those guys are pretty busy with COM+, so I won’t hold my breath. Are we sure of the ramifications and usage of amalgam dispatch and nested dispatch? I’m pretty sure, but not completely so. If you think I’m all wrong (or even just a litte), let me know.

    On the other hand, if there are enough folks that are excited about a typelib-driven implementation of IDispatch, we can get it done. I’ve dedicated this web page to collecting and distributing the pieces. If folks have some source to contribute, I’ll use it to build the two implementations. If folks have full implementations, I’m happy to post those as well. Please, let’s stop implementing IDispatch so I can stop thinking about the worthlessness of duals. Thanks.

    BTW, want to know the real reason we have duals? It saves a vptr. Doh!

    This article is translated to Serbo-Croatian by Anja Skrba from Webhostinggeeks.com.

    January 22, 2003 tools

    NUnitASP

    Here. From Colin: NUnitAsp is a tool for automatically testing ASP.NET web pages. It’s an extension to NUnit, a tool for test-driven development in .NET.
    January 10, 2003 tools

    .NET ResourceExplorer

    .NET ResourceExplorer

    In writing the resources chapter of my WinForms book, I found that there was no single utility for displaying the resource contents of assemblies, .resx files and .resource files (even embedded .resources files) in a way that made sense to me. So, I built one and called it ResourceExplorer.

    ResourceExplorer is very simple and could stand some extension to show specific resources at images, text, data, etc, but it certainly served my needs, especially when it came to understanding the usage and limitations of the ResourceReader (for reading .resources files) and the ResXResourceReader (for reading .resx files). Enjoy.

    December 15, 2002 tools

    New Genghis Release Coming

    Here. There has been all kinds of activity on Genghis since the v0.3 release. I’ve been gathering these bits together to make a coherent v0.4 release in the new year (right after I finish my darn book!). Those of you with final bits and pieces that need to get in before that release, please get them to me ASAP. Thanks.
    December 12, 2002 tools

    ADO.NET — Offline and On Tap

    Here. In the .NET* Framework, rich clients can bring database servers to their knees, just like Web-based applications. But with the disconnected nature of ADO.NET, your rich clients can manipulate and analyze database data without impacting the database server. Once you have the data in the rich client, you can do high-performance analysis of the data—including sorting, filtering, and querying—without expensive server calls. In this article we will show you how to use DataSet, DataView, and XmlDataDocument to make your rich clients work with database data in a disconnected way.”
    December 7, 2002 tools

    WinForms Control Inspector — Spy++ for .NET

    Here. ControlInspector hooks on to all events on a given control, user-control or form and shows when they are fired, along with any eventargs. It even handles custom events and custom event args using dynamically generated assemblies.” This looks *very* cool and was inspired by DevelopMentor’s Guerrilla .NET course. Wahoo!
    November 14, 2002 tools

    VBTV Episode 2: DO NOT WATCH THIS SHOW!

    Here. Actually, I think you probably should watch it. I find VBTV very amusing. : )
    November 7, 2002 tools

    Regular Expressions in .NET

    Here. Michael Weinhardt and Chris Sells plumb the depths of .NETs regular expression engine.
    October 13, 2002 tools

    Scancode Mapper

    Scancode Mapper

    Scancode Mapper is a GUI tool for setting the Scan Code Mapper for Windows Registry settings for Win2K+:

    As an example of what this tool does to the Registry, this .reg file turns off the CapsLock key. Of course, changing scancode mappings is a risky business, so be sure of what you’re doing before committing the changes and restarting Windows. No warranties extended. Use at your own risk. Enjoy. : )

    October 3, 2002 tools

    NUnit 2.0 Released

    Here. From Bernard Vander Beken: From the readme: “This is the second major release of the xUnit based unit testing tool for Microsoft .NET. It is written entirely in C# and has been completely redesigned to take advantage of many .NET language features, for example custom attributes and other reflection related capabilities.” “In the next few weeks we will be formulating the next release trying to incorporate as many requests as possible.”
    September 20, 2002 tools

    NUnit 2.0 RC3 available

    Here. From Bernard Vander Beken: From the release notes of this unit testing framework: “This barring any unforeseen new critical bugs will be the last V2.0 release candidate. We will not be adding any additional features until V2.0 is released which we expect now to be sometime around 26 September, 2002.”
    September 10, 2002 tools

    TAPI Explorer

    TAPI Explorer

    I built the TAPI Explorer (tExplorer) to allow me to understand the various capabilities of the telephony devices installed on my system when I was developing TAPI applications and writing my TAPI book. It grew into a utility for showing all line, address and phone capabilities as well as other TAPI settings, e.g. country codes, telephony locations, service providers, etc. If you’re running into TAPI errors that you don’t understand, TAPI Explorer will help you work through them.

    This version has been run and tested on Windows 98, Windows ME, Windows NT 4.0, Windows 2000 and Windows XP and supports TAPI versions 1.4 through 3.1.

    VS.NET Source | VC6 Source (previous version)

    September 4, 2002 tools

    Microsoft XML Diff and Patch 1.0

    Here. Microsoft XML Diff and Patch is a set of tools for comparison of two XML documents and application of the changes (patching). XML Diff detect addition, deletion and other changes between two XML documents. It also detects structural changes like a move of a XML subtree. It produces Xml Diff Language Diffgram (XDL diffgram or just diffgram) that describes the differences between the two XML documents. The diffgram can be then used to display these differences or to perform a patch operation using the XML Patch tool.” I know that this tool has been sorely needed in the XML community for a while and now MS has released one.
    August 29, 2002 tools

    VC++ Jacket for the Best Managed C++ Entry

    Here. Things are still heating up in the prize category. Not only has O’Reilly just donated a year subscription of Safari, along with a bunch of .NET book packs, but Nick Hodapp, a PM on the VC++ team at Microsoft, has just donated a VC++ Jacket to the best Spend A Day With .NET coding contest entry that’s written in Managed C++. The anticipation is killing me!
    August 18, 2002 tools

    Genghis v0.3 Release

    What’s new in Genghis v0.3:

    • Screen shots for everything.
    • Source available via CVS repository.
    • MRU support, including both in-menu and sub-menu support.
    • A much more robust set of validation components modeled along the lines of the ASP.NET validation components, including required, regex, range and comparison validators.
    • FileDocument component for document/dirty bit handling.
    • Wizard support, including changing page groups on the fly!
    • Custom state treeview so that you can set and show all three checkbox states.
    • A class to expose the WinForms HandleCollector so that you can put your own custom resources into it.
    • A Screen Saver class.
    • A bunch of file utility classes, including retrieving mapped drives, retrieving shares and path resolution.
    • A cursor changer class that works with the using block.
    • A WebCommandLineHelper class to parse command line arguments from the URL used to launch href-exes.
    • Update to the FileNameDialog to include newish flags.
    August 16, 2002 tools

    NUnit 2.0 RC1 available

    Here. From Bernard Vander Beken: Highlights of the updated unit testing framework for .NET: - Attribute based mechanism for identifying test fixtures and test methods. - Automatic creation of test suites. - Improved GUI runner allowing dynamic reloading of test assemblies. - The Console runner supports XML output. - Mostly backward compatible with NUnit 1.0.
    August 9, 2002 tools

    VBTV

    Here. From Jesse Ezell: If the .NET show wasn’t enough for you, Microsoft is producing another show. Supposed to be slightly irreverant and not for the faint of heart.
    July 25, 2002 tools

    Beta-2 of Nunit 2.0 is available

    Here. Some of the highlights of the new release include the following: “- Attribute based mechanism for specifying test and test fixtures. “- New Forms Interface that displays Tests and TestSuites in an Explorer like fashion. The interface allows you to run individual tests and/or suites from the forms interface. “- Automatic construction of suites based on namespaces. Just provide an assembly and the test runner constructs a suite of all TestFixtures in the assembly. “- Minimal amount of effort to upgrade due to inclusion of a backwards compatibility class called TestCase and the framework also looks for methods that begin with test” regardless of case as it did in the past. “- XML output from the console program.” [DOTNET-PRODUCTS]
    July 25, 2002 tools

    Microsoft XML Diff and Patch 1.0 Beta

    Here. The primary purpose of the tool is to be able to quickly detect node-level changes between versions of an XML document, and with enough granularity to support efficient patch and merge scenarios. The patch format can be used for fairly terse delta-encoding to transfer incremental changes across the wire as well. The tool is officially called XmlDiff and Patch” and is implemented in managed code (sorry, no MSXML version). Currently you can only perform XML Diff through the web page, but the assembly should be available on that site very soon. I think it is considerably better than anything else available today, in terms of both performance and accuracy, and the API is a good fit with the System.Xml libraries, so it should be really easy for any VB/J#/C#/F# programmers to use.” [netcrucible.com/blog]
    June 20, 2002 tools

    treecc — Free Compiler Construction Tool for C#

    Here. The approach that we take with treecc is similar to that used by yacc. A simple rule-based language is devised that is used to describe the intended behaviour declaratively. Embedded code is used to provide the specific implementation details. A translator then converts the input into source code that can be compiled in the usual fashion.”
    June 10, 2002 tools

    Genghis — 0.2 Release

    Thanks to all of the *very* active contributors, Genghis has doubled in size! This update includes:

    • an automated nant build
    • a framework for nunit tests
    • an almost complete .NET implementation of SimplePad
    • an imagelist combo box
    • a preferences and window position serializer
    • an MRU sample
    • a custom state treeview class for doing tri-state checkboxes
    • an update to ListViewSorter to make it declarative
    • an expanded trace class for common tracing operations
    • various other bug fixes

    There’s plenty more to see and do, so check out Genghis if you’re building WinForms applications.

    June 9, 2002 tools

    ADOGuy’s Typed DataSet Generator

    The Typed DataSet that Microsoft generates from Visual Studio.NET (or from the XSD.exe tool), does not support derivation directly. In order to allow us to derive from Typed DataSets, Chris Sells and I created this tool that fixes the couple of issues with inheriting from Typed DataSets.”

    June 8, 2002 tools

    Brent Rector: The Truth about Code Obfuscators

    An obfuscator only delays the inevitable. With unlimited resources (time and money) and physical access to code, all code can be reverse engineered. This was true for native x86 binaries and it’s true for .NET Framework applications. What an obfuscator does is increase the cost of the effort required to reverse engineer obfuscated code. Hopefully, it increases the cost enough to make reverse engineering your code unpractical.”

    June 6, 2002 tools

    Visual Build Pro

    It’s easy to put Visual Build Pro to work doing all that manual labor for you so you can focus on more important things. Visual Build Pro is a powerful but affordable build management solution that will automate the build process without a huge commitment of time, and it works with the tools you’re using today.”

    June 4, 2002 tools

    Updated XsdClassesGen

    Eric Eric Friedman has submitted code to support namespaces and uninstall. The former fills the biggest hole in XsdClassesGen (thanks Eric), but why would anyone need the latter?!? : )

    May 17, 2002 tools

    .NET XsdClassesGen

    XsdClassesGen is a Custom Tool Add-In to VS.NET 2002 & 2003 to generate type-safe wrapper classes for serializing to and from XML documents. It takes as input an XSD and produces the C# or VB.NET code to do the serialization using the XmlSerializer. This is really just the output of running xsd.exe /classes, but integrated directly into VS.NET.

    If you’d like to know more about what a custom tool is and how to build your own, check out CollectionGen.

    Also, Atif Aziz used some of my custom tool code and built a generic VS.NET code generator shim that allows you to build a code generator that plugs into VS.NET by implementing a single method.

    And, as if that weren’t enough, Stephane Tombeur has posted the code to VS2005. Thanks, Stephane!

    May 13, 2002 tools

    Modern C++ Design

    From Razvan Caciula: I like Chris Sells’s books, but also i like romanians too :> I’m preparing for a technical interview and i founded this book very useful.
    May 10, 2002 tools

    Genghis — .01 release

    We’ve released the v0.1 version of Genghis. Enjoy!
    May 10, 2002 tools

    Announcing Genghis

    Genghis is a set of extensions built on top of .NET and integrated with WinForms to provide application-level services in the same flavor as the Microsoft Foundation Classes. Genghis gets its name as the functional heir to Attila, a similar set of functionality built on top of ATL.
    May 10, 2002 tools

    SafeFormatter for .NET

    Are you building and deploying .NET applications in a secure environment, e.g. over the intranet or the internet? If so, they you’ve probably mourned the loss of the binary and SOAP formatters that can automatically serialize a graph of objects that are marked as [Serializable] and that may also implement ISerializable and IDeserializationCallback. Both of these formatters are dependent on reflection, which will not be available in a more restrictive security environment. Likewise, even ISerialization.GetObjectData is verboten if you wanted to do this kind of thing yourself. As far as that goes, [Serializable] and ISerialization should be forbidden in a secure environment, as it allows a client to get and set the private variables of an object, potentially causing harm.

    Still, security is the enemy of usability, to paraphrase Keith Brown. So, in the spirit of a balancing the design need for objects that can serialize themselves with the goal of complete disclosure in a secure world, I’ve built my own safe” formatter. It only uses facilities of the runtime that work in the most secure environment of the default settings for the internet zone. So that objects can guard themselves against malicious data, I define a new interface called ISafelySerializeable that they need to implement to support this serialization facility. The protocol is exactly the same as ISerializable, so if that interface is already being implemented, the implementation of GetObjectData can be shared between both interfaces.

    Currently, the code is in alpha and is riddled with TODO statements, but its functional enough today for actual usage. My SafeFormatter and test harness are available for your feedback. Enjoy.

    April 12, 2002 tools

    Giving VS.NET That XP Look

    USE THIS FILE WITH CARE. It causes problems with image lists for .NET EXEs that don’t also use the same manifest file.

    Just drop this devenv.exe.manifest file next to devenv.exe in your VS.NET install directory and the next time you start VS.NET under XP, it’ll look mostly the same! (well, maybe a little different : )

    April 10, 2002 tools

    .NET CollectionGen

    .NET CollectionGen

    [Note: As of 5/5/03, the functionality of CollectionGen has been sucked into Eric Smith’s CodeSmith. I asked Eric to take on these features because CodeSmith does all of what CollectionGen does and more. All new feature requests/bug reports should go his way.]

    CollectionGen is a Custom Tool Add-In to VS.NET 2002 & 2003 to generate type-safe collections. As it turns out, I did almost none of the work. Jon Flanders figured out how to add a custom tool. Shawn Van Ness implemented the template for type-safe collections. I just put it together.

    CollectionGen is an add-on to generate code for type-safe collections until we have templates in C# (likely) and VB (unlikely). The benefit of a type-safe collection, of course, is that you can use it without having to cast items to and from objects. Also, Shawn has been very careful to implement a collection class that is very efficient for both reference types and value types.

    Once you’ve setup it up and defined your collections in a collection definition file in your project, you’ll have type-safe collection classes generated as part of your design-process, as shown here:

    Figure 1: collections.xml collection definition file

     

    Figure 2: collections.xml and generated collection.cs implementation file

     

    Figure 3: CollectionGen custom tool add-in associated with the collections.xml file

     

    Figure 4: Generate type-safe collection code

    Enjoy!

    Also, Atif Aziz used some of my custom tool code and built a generic VS.NET code generator shim that allows you to build a code generator that plugs into VS.NET by implementing a single method.

    April 6, 2002 tools

    RegexDesigner.NET

    RegexDesigner.NET

    RegexDesigner.NET is a powerful visual tool for helping you construct and test .NET Regular Expressions. When you are happy with your regular expression, RegexDesigner.NET lets you integrate it into your application through native C# or VB.NET code generation and compiled assemblies (usable from any .NET language).

    Features:

    • Full source
    • Interactive matching of .NET regular expressions.
    • Syntax highlighted match results, including zero-length matches and hidden characters.
    • Tooltips to display matched groups.
    • Regular expression matching, replacing and splitting.
    • Regular expression projects to save expressions, text to match and all regex options.
    • Full code generation for C# and VB.NET for all regex operations.
    • Compiled assembly generation.
    • Full online help.

    March 8, 2002 tools

    .NET IM Client Classes

    Inspired by my need to know who was calling without hauling my butt off the couch to look at the caller ID on the phone across the room (my father always said that laziness is the mother of invention”), I built a couple of C# classes for managing an IM connection and an IM session. The test client is a console application that just sends messages and dumps whatever it gets from the IM server to the console, but I think it would serve as the code is the beginnings of a real IM client. It does the MD5 stuff properly and handles being redirected to another IM server, so the hard part of the protocol is already implemented. The sample itself is a handy little program that logs in as an IM user, sends a message to another IM user and logs back off again. Perfect for annoying your office mates. Enjoy.

    BTW, Harry Pierson has made a number of updates to this core code to support his full-blown  .NET IM client application. Check it out!

    February 16, 2002 tools

    Welcome to Genghis!

    Welcome to Genghis!

    Welcome to Genghis

    Genghis is a set of extensions built on top of .NET and integrated with WinForms to provide application-level services in the same flavor as the Microsoft Foundation Classes. Genghis gets its name as the functional heir to Attila, a similar set of functionality built on top of ATL.

    Disclaimer

    Most of the Genghis classes were built by different folks and while every effort was made to keep things consistent by choosing .NET and WinForms design techniques, everyone does things their own way.

    This work is the work of the individuals involved and does not represent any contribution of their respective employers. You are under no obligation to use any of Genghis at any time, but if you do, you are required to abide by the License.

    Installation

    You can download the latest Genghis source code from here. The Genghis archive includes this page, the source code to the Genghis class library, a series of samples showing off the various classes and a pre-built, signed version of genghis.dll in the redist folder. Notice that some of the samples use the Genghis files directly instead of using the compiled Genghis assembly. Either usage is supported by Genghis (except where it drives the WinForms Designer nuts).

    Source Code Control

    Genghis source code control has been moved to the Genghis CodePlex workspace. Thanks to GotDotNet and Rob MacFadyen for hosting the previous versions.

    Building Genghis

    Genghis is written in C#. Building Genghis requires Visual C# or Visual Studio.NET. Visual Studio.NET solution and project files (*.sln and *.csproj) are provided to build Genghis and all the samples. You should be able to load any solution file into Visual C#/Visual Studio.NET and build the project for yourself.

    A NAnt build script (Genghis.build) is also provided. It is used to make the snapshot for Genghis, and is not designed for general use. You may wish to use this file to simulate the snapshot build process; please be aware that you will not be able to properly sign the release mode Genghis DLL (the private key is not provided in this distribution).

    For Visual Studio.NET related build issues, please contact the Off Topic Windows mailing list. This is where the Genghis contributors have their discussions, and most of them will be familiar with Visual Studio.NET builds of Genghis. If you have NAnt related build issues, you should contact Mike Marshall (the Genghis build master) directly.

    Thanks to Brad Wilson for the NAnt build scripts for folks without VS.NET.

    Bug Reports

    Bugs will now be kept in the Bug Tracker section of the GDN Workspace.

    Please do not send Chris Sells or any of the other contributors personal email complaining about Genghis. Also please do not post Genghis bug reports to any mailing list. A much better way to contribute to the life of Genghis is to submit the fix along with the bug report.

    Submission Guidelines

    • Submissions should be in the Genghis namespace (I don’t think we’ll have to worry about collisions… : ).
    • Submissions should be single-file and stand-alone as much as possible. The goal is that Genghis can be built as a DLL and used as a whole or that bits of its source can be pulled into individual projects as needed ala atl.dll vs. atlwin.h.
    • All code should be commenting using C# doc comments so that docs can be generated via Tools->Generate Source Comments.
    • All source code files should include the copyright and license notice.
    • All code shall be set to use spaces, not tabs, and a vanilla coding style.
    • When hacking on existing code, thou shall conform to the existing coding standard of the file. Many coding standards are readable, but not when mixed.

    The Genghis Group

    This group is made up of official Genghis contributors:

    Who Does What

    If you’d got something you’d like to see contribute to Genghis, please let me know (multiple people are free to collaborate on a single feature).

    Feature

    Owner(s)

    Progress

    Screen Shot(s)

    Command line parser

    Chris Sells

    included

    screenshot

    Completion combo

    Chris Sells

    included

    screenshot

    Control hosting status bar

    Ethan Smith

    included

    screenshot

    Cursor changer

    Shawn Wildermuth

    included

    screenshot

    Custom check state treeview

    Chris Sells

    included

    screenshot

    Custom XP theming controls

    Matthew W. Adams et. al.

    included

    screenshot

    File Search Engine

    Mike Marshall

    included

    screenshot

    FileDocument class (doc/dirty bit management)

    Chris Sells

    included

    screenshot

    FindReplaceDialog

    Ramakrishna Vavilala

    included

    screenshot

    FolderNameDialog

    Chris Sells

    included

    screenshot

    HandleCollector for the world

    Ethan Brown

    included

    screenshot

    Header group box control

    Matthew Adams

    included

    screenshot

    Image combo

    Horst Veith

    included

    screenshot

    More robust validation ala WebForms

    Michael Weinhardt

    included

    screenshot

    Most-Recently-Used (MRU) files support

    Michael Weinhardt

    included

    screenshot

    MSN Messenger-style popup window

    Mike Marshall

    included

    screenshot

    Multiple Top-Level Windows

    Chris Sells

    included

    screenshot

    Multiple-instance detection

    Chris Sells

    included

    Path resolution b/w UNC, local (including SUBST, etc)

    Ethan Brown

    included

    screenshot

    Retrieving mapped drives

    Ethan Brown

    included

    screenshot

    Retrieving shares

    Ethan Brown

    included

    screenshot

    Screen Saver class

    Shawn Van Ness

    included

    screenshot (sorta : )

    Scrollable Picture Box

    Husein Choroomi

    included

    screenshot

    Sorting listview (including the little triangle thingy)

    Horst Veith

    included

    screenshot

    Splash Screen class

    Peter Foreman

    included

    screenshot

    Status Bar Extender

    Chris Sells

    included

    screenshot

    WebCommandLineHelper

    Chris Sells

    included

    screenshot

    Window serializer

    Paul Bartrum

    included

    screenshot

    Wizard framework

    Shawn Wildermuth

    included

    screenshot

    HtmlLinkLabel class Jeff Key included screenshot
    User-resizable panel Ethan Brown included screenshot

    Gradient Progress Bar

    Mike Marshall

    included

    screenshot

    Command updating

    Paul Bartrum

    sample

    screenshot

    Cool bars/Cool menus

    Chris Burrows

    sample

    screenshot

    Docking App Bar

    Dean Cleaver

    sample

    screenshot

    A real image list control

    Matt Wilson (of Attila fame!)

    pending

    Advanced layout managers, e.g. grid/table

    Matthew Adams

    pending

    Command routing

    Paul Bartrum

    pending

    Dynamically docking/undocking windows

    TBD

    pending

    href exe-safe serialization framework

    Chris Sells

    pending

    Managed HTML display ala a C# port of Mozilla?

    TBD

    pending

    Menu/toolbar editing ala Office or VS.NET

    Paul Bartrum, Chris Burrows

    pending

    Outlook-style Bar

    Richard Birkby

    pending

    SDI, MDI and Explorer-style application wizard

    TBD

    pending

    Tab-based MDI implementation (ala VS.NET)

    TBD

    pending

    Tear-off menus

    Matt Wilson

    pending

    Note: Anything marked with sample means that there’s a sample included with Genghis that shows the current implementation of a feature but that it’s not done enough to be part of the official Genghis component. Mostly the hold-up is integration with the WinForms Designer.

    Documentation

    The Genghis documentation is composed of the C# documentation comments as part of the automated build. Check redist\Genghis.chm for the latest.

    SimplePad

    SimplePad is an MFC application that should serve as a simple baseline for what Genghis should enable to be built easily. We currently need a raw WinForms implementation to help guide the Genghis development efforts. After building it, use Help->Help Topics to see the list of features that the MFC SimplePad application provides straight out of the wizard (also duplicated here):

    • MDI application
    • Multiple documents
    • Multiple views per document that are updated as the document changes
    • Dirty” bit handling
    • Title bar that shows the document with the current focus along with a dirty indicator, i.e. the asterix.
    • File New, Open, Save, Save As, Exit and MRU
    • MDI Window menu
    • Separate icons for the application and the documents
    • Association of the icons with the documents in the shell
    • Dockable, floating toolbar
    • Print, Print Preview, Print Setup
    • Edit Undo, Cut, Copy and Paste.
    • View Toolbar and Status bar
    • Help Topics and About
    • Context-sensitive help
    • Status bar that updates when menu items or toolbar items are in focus”, as well as showing NUM, SCROLL and CAPS as these keys change. Since Microsoft has shown that no one looks at the status bar much, the auto-update as items come into focus is not a feature that needs to be duplicated in WinForms/Genghis.
    • Command line launching of the application based on the application’s file extension
    • Drag-n-drop from the file explorer
    • Double-click support from the file explorer (including routing open requests to a currently open application)

    The current .NET implementation of SimplePad is now available as one of the Genghis samples. Thanks to Paul Bartrum and Chris Burrows for all their hard work on this!

    History

    • 03/09/04: Release v0.5:
      • New HtmlLinkLabel class from Jeff Key that knows how to launch IE and EXEs directly w/o requiring you to handle the event
      • Much prettier images in SimplePad from Chris Burrows
      • Updated MRU code from Michael Weinhardt to match .NET event signature conventions and to fix a problem when using more than one MRU components on a single menu
      • Updated FileSearchEngine code from Mike Marshall to check for whole words at beginning and end of line correctly
      • Updated validation code from Michael Weinhardt with support for validating controls at a container level, e.g. validating controls on a tab instead of on an entire form
      • New gradient progress bar from Mike Marshall
      • Updated FileDocument from Chris Sells to match text of Windows Forms Programming to include more MFC-like features like a pluggable scheme for serialization handling, registration of document extension with the shell, and adding to recent docs, i.e. Start->Documents
      • Updated HandleCollector from Ethan Brown to work with .NET 1.0 and .NET 1.1
      • Performance enhancements from Ethan Brown in the MappedDrives and SystemShares classes
      • New user-resizable panel from Ethan Brown
      • Updated WebCommandLineHelper from Andrew Duncan to fix System.IO.FileLoadException in ieexec.exe
      • Updated AniForm from Mike Marshall to support stacking ala SharpReader and fix a terminal server-related bug
      • Updated cool menu sample from Chris Burrows with additional support for abstracting commands from click even handlers
    • 4/25/03: Release v0.4:
      • Everything tested under VS.NET 2002 & 2003 (except HandleCollector, which doesn’t work under VS.NET 2003)
      • Mike Marshall’s AniForm -an MSN Messanger-style popup window
      • Chris Burrows’ Image Index Editor - a UI Type Editor for use with ImageList index selection
      • Dean Cleaver’s .NET AppBar implementation (a C# port of original code from Jeffrey Richter)
      • Mike Marshall’s File Search Engine: a text file search implementation with behavior similar to dev studio’s Find In Files”
      • Matthew W. Adams’ et. al. Themed controls
      • Chris Sells’s InitialInstanceActivator. The InitialInstanceActivator makes sure that only one instance of an application is started and when another instance is started, the first instance is passed the command line arguments passed to the initial instance
      • Chris Sells’s MultiSdiApplicationContext class for allowing multiple top-level Windows Forms
      • Peter Stephens’ changes to the CommandlineParser that fix some bugs as well as add the ability to skip the first argument
      • Matt Berther’s additions to the CompletionComboBox to fire an event when the text typed does not match any items in the dropdown
      • Peter Foreman’s splash screen implementation
      • Chris Sells’s newly improved WebCommandLineHelper class which now works with .NET 1.0 and 1.1, includes URL decoding and requires no additional permissions (although it does require a server-side HTTP handler, included as the ConfigFileHandler class that maps requests for foo.exe?bar=quux.config to the foo.exe.config file).
      • Shawn Wildermuth’s WizardSheet updates
      • Chris Sells’s Status Bar Extender for mapping status messages to Windows Forms controls
      • Andre Van Der Merwe’s CommandLineParser changes as described below:
        • Added ValueDelimiters: enum for ValueUsageAttribute which lets the user specify which (combination) of delimiters (space, : or =) will be allowed
        • Added AllowOnOff: bool in FlagUsageAttribute to specify if a +/- suffixes can be used on the flag
        • Added EnvironmentDefaults: string in ParserUsageAttribute, allows the user to specify defaults in an environment variable (ala DIRCMD).
        • Modified the Long&Short help generation functions to
          • Format/pad flag/param names correctly regardless of length
          • Show [+|-] prefix (if applicable) for flags
          • Show [sp|:|=] delimiters (as applicable) for values
    • 08/18/02: Release v0.3:
      • Screen shots for everything.
      • CVS repository available, as provided by our rmTrack sponsor, along with extensive CVS docs from Brad Wilson.
      • MRU support from Michael Weinhardt, including both in-menu and sub-menu support.
      • A much more robust set of validation components from Michael Weinhardt (Michael’s been busy : ) modeled along the lines of the ASP.NET validation components, including required, regex, range and comparison validators.
      • FileDocument component from Chris Sells for document/dirty bit handling.
      • Wizard support from Shawn Wildermuth, including changing page groups on the fly!
      • Custom state treeview from Chris Sells so that you can set and show all three checkbox states.
      • A class to expose the WinForms HandleCollector from Ethan Brown so that you can put your own custom resources into it.
      • A Screen Saver class from Shawn Van Ness.
      • A bunch of file utility classes from Ethan Brown, including retrieving mapped drives, retrieving shares and path resolution b/w UNC, local (including SUBST, etc).
      • A cursor changer class that works with the using block by Shawn Wildermuth.
      • A WebCommandLineHelper class from Chris Sells to parse command line arguments from the URL used to launch href-exes.
      • Update to the FileNameDialog from Deepak Shenoy to include newish flags.
    • 6/10/02: Release v0.2:
      • Updated ListViewSorter to be declarative. Look for Designer support ASAP.
      • Generated new genghis.key and removed it from the distribution.
      • Brad Wilson, our new Build Master, contributed a Nant build.
      • Paul Bartrum and Chris Burrows contributed a mostly-complete .NET implementation of SimplePad, along with some sample command updating and cool menus implementations.
      • Paul Bartrum also provided a window serializer and a preference class.
      • Michael Weinhardt contributed an MRU sample.
      • I contributed a custom state treeview useful for things like tri-state checkboxes.
      • Minor bug fixes.
    • 4/3/02: Released v0.1.
    • 2/28/02: Set the license.
    • 2/16/02: Posted this page.

    Sponsors

    rmTrack provided the initial hosting space and administration support for Genghis bug tracking and source code control.

    License

    Copyright © 2002-2004 The Genghis Group

    Th is software is provided as-is’, without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.

    Permission is granted to anyone to use this software for any purpose, including commercial applications, subject to the following restrictions:

    1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required, as shown here:

      Portions copyright © 2002-2004 The Genghis Group (http://www.genghisgroup.com/).
       
    2. No substantial portion of the source code of this library may be redistributed without the express written permission of the copyright holders, where substantial” is defined as enough code to be recognizably from this library.

    License Note

    This license based on the open source zlib/libpng license. The idea was to keep the license as simple as possible to encourage use of Genghis in free and commercial applications and libraries, but to keep the source code together and to give credit to the Genghis contributors for their efforts. While this license allows shipping Genghis in binary form, if shipping a Genghis variant is the sole purpose of your product, please contact The Genghis Group for a new license.

    January 6, 2002 tools

    VS.NET Fun Facts

    If you haven’t seen it yet, check out the VS.NET Fun Facts piece that started as praise and bitching about VS.NET, but turned into something pretty useful if you’d like to get the most out of VS.NET.

    September 13, 2001 tools

    CorPub

    Oct 10, 2001

    I’ve updated CorPub to show *all* managed AppDomains by initializing the COR debugging sub-system prior to enumerating them. Thanks to Atif Aziz for the tip.

    September 13, 2001

    I built the CorPub utility when my friend Jason pointed me at the .NET corpub.idl interfaces (his exact words were ICorPublishProcess rocks!“). CorPub lists the managed processes on the current machine and the AppDomains in each process, as follows:

    Managed process 0xa54: D:\project\mine\RegexPlorer\bin\Debug\RegexPlorer.exe
    	AppDomain 0x1: RegexPlorer.exe
    
    Managed process 0xdc8: C:\vs.net\Common7\IDE\devenv.exe
    	AppDomain 0x1: DefaultDomain
    
    Managed process 0x1ec: C:\PROGRA~1\MICROS~2.NET\FRAMEW~1\Bin\ildasm.exe
    	AppDomain 0x1: DefaultDomain

    It’s fun for spelunking. Enjoy.

    NOTE: .NET beta 2 is required to run this utility.

    August 8, 2001 tools

    .NET XML Checker and Validator

    Aug 8, 2001

    xmlValid is simple command line utility that will check an xml file for well-formedness and, optionally, will validate it against a supplied XML schema file (xsd). I built it to check that my site’s HTML files were well-formed (and therefore XHTML-compliance), but it’s got all kinds of other uses, including checking .NET .config files. Source is included. Enjoy.

    Usage: xmlValid.exe xmlFile [xsdFile]

    Note that this utility requires .NET beta 2 to be installed.

    August 7, 2001 tools

    Setting the Completion Character

    Aug 7, 2001

    Whenever I set up a new machine (which happens a lot as WinXP and .NET go through their beta & RC cycles), I always need to manually set up the completion character (to TAB, of course) in the Registry. Shawn VanNess posted a .rgs file that would set this up without the lengthy search through the Registry. Inspired by Shawn, here’s my own completionChar.reg that doesn’t require a program to parse .rgs files (which doesn’t come with Windows).

    BTW, if you don’t know about the command shell’s Completion Character, stop right now, run the completionChar.reg file, start up a WinNT/Win2K/WinXP command shell, type cd c:\p[TAB]” and watch while the shell expands it to cd C:\Program Files" for you. If you have other directories that start with c:\p”, continue to hit [TAB] to cycle through them. This works for any directory or file name and it boosts my productivity by about 100% on the command line. I can’t live without it!

    August 6, 2001 tools

    NullScript Used to Reverse Engineer Gen

    Wow. I’m impressed as all get out. Hugh Brown has reverse-engineered Gen as one of the tests of his NullScript implementation. I wish I would have had this when I started Gen a couple of years ago. It would’ve saved me figuring out how ASP did it.

    My thinking along these lines years ago led me to go the opposite way, i.e. I built a front-end ASP parser that generated script for VBS. I called it TextBox (which, as a Win32 programmer, I should’ve realized was a terrible name…).

    August 5, 2001 tools

    Moniker Wizard

    Here’s my moniker wizard that includes the framework used by the Basic Monikers.

    August 4, 2001 tools

    Tim’s COM+ Utilities

    Aug 4, 2001

    The great and powerful Tim Ewald (author of Transactional COM+: Building Scalable Applications and personal friend of mine) put together a handy little set of COM+ classes and utility functions in a concise header file that he has graciously allowed me to host. Among my favorites are IsInActivity, IsInTransaction, IsSecurityEnabled, GetCallersName,  IsCallerInRole, and parameterized versions of CoGetObjectContext and GetAspObject (which is even cooler than my CAspPtr). Download the code! Buy the book! Feed your brain!

    August 3, 2001 tools

    Command Line Parsing

    Aug 3, 2001

    I got tired of not having getopt under Win32 and the best version to port doesn’t handle slashes (as per the Windows standard) or @files for arguments and it requires you to give away the source for every app that uses it, so, inspired by my friend Josh Gray,  I built my own. It supports typed flags and params, @file support and building full usages on the fly.

    Plus, the latest version has support for parsing ANSI or Unicode argfiles, as provided by Johan Nilsson. Thanks, Johan! Also, I’ve added a contribution by Paul Westcott to support arguments with restricted values. Thanks, Paul! And, as if that weren’t enough, Adis Delalic contributed a UML diagram to describe how the CLP is built. Wow.

    And as if that weren’t enough, Keith Brown ported the command line parser to VS.NET. Thanks, Keith!

    August 2, 2001 tools

    Expando Objects

    Aug 2, 2001

    I’ve seen lots of interest lately in expando objects, e.g. objects that can add methods and properties on the fly. Joe Graf wrote a piece on IDispatchEx in MIND that was pretty interesting. My own implementation of IDispatchEx is available here. It supports expando objects that have no static properties or methods as well as those that do. Check out the DispExTest.js for a demonstration, dispeximpl.h, dynamemlist.h and dynamemlist.cpp for the implementation and MyExpando.h for the usage.

    August 1, 2001 tools

    Windows Template Library

    Aug 1, 2001
    July 31, 2001 tools

    VARIANT_BOOL Wrapper

    July 31, 2001

    CComBool is a class to prevent the misuse of the VARIANT_BOOL type. VARIANT_BOOL is a problem because its legal values are -1 and 0 instead of 1 and 0, making converting back and forth between bool, BOOL and VARIANT_BOOL problematic. CComBool supports the constructors and operators needed to convert between the three C++ Windows Boolean types. It also supports operator& and CopyTo for common COM client and server usage. CComBool is available here.

    July 30, 2001 tools

    ATL CRT Numbers

    July 30, 2001

    The following table lists the various prices you pay for using the CRT and the default Win98 support in VC6. The builds were done with VC6, SP3, ATL COM in-proc server, no classes, no MFC, no merged p/s:

    Target CRT Win98 Size
    RelMinSize _ATL_MIN_CRT yes 24KB
    RelMinDepend _ATL_MIN_CRT yes 24KB
    RelMinSize _ATL_MIN_CRT /opt:nowin98* 7KB
    RelMinDepend _ATL_MIN_CRT /opt:nowin98 10KB
    RelMinSize MSVCRT /opt:nowin98 20KB
    RelMinDepend MSVCRT /opt:nowin98 22KB

    *Note: /opt:nowin98 is a VC6 linker switch that says not to align binaries on a Win98-friendly boundary. /opt:nowin98 builds will still load and run under Win98 without a problem, but the loading time could be longer. Also, when images get above 24KB, the /opt:nowin98 seems not to much of an affect on the size of the image.

    July 29, 2001 tools

    VBLite

    July 29, 2001

    Dharma Shukla and I wrote Extending ATL3.0 Containment to Help You Write Real-World Containers” in the 12/99 issue of MSJ detailing how to add much-needed features to ATLs support for control containment. Dharma wrote the sample code that accompanies the piece and has already made improvements to the code based on feedback. He’s maintaining the history and bits here.

    July 28, 2001 tools

    Attila

    Attila stands for ATL for Applications.” Attila is a set of extensions built on top of ATL to provide application-level services in the same flavor as MFC. Towards that end, Attila uses a lot of the same notions as ATL, e.g. heavy use of templates, static binding and reliance on the compiler and the linker doing their job.  Also, in the flavor of ATL, Attila is under-documented and requires a lot of user investment to make use of it. However, once you do, we think you’ll find the flexibility and efficiency worth it. If you don’t, you haven’t lost much, cuz Attila is free. Enjoy.

    July 27, 2001 tools

    Simple Object II ATL ObjectWizard Extension

    July 27, 2001

    The Simple Object II ATL ObjectWizard Extension (whew — I’ve got to come up with a shorter name…) provides the following features:

    • Support for [oleautomation] interfaces.
    • Support for the Neutral-threaded apartment.
    • Support for IDispatch-based interfaces other than duals.
    • Better support for disabling features that do not make sense together, e.g. FTM + ThreadingModel=Apartment.
    • Updated pop-up help.

    Originally, SimpleObject2 was built to do away with the one benefit of IDispatchImpl over IDelegatingDispImpl — wizard support. As do most things developed under the greedy eye of my colleagues, it grew to support a few more features than that. It’s available for download here. Enjoy. 

    July 26, 2001 tools

    CComVector: A SAFEARRAY Wrapper

    July 26, 2001

    I got tired of not having a smart type for SAFEARRAYs, so I built one. It’s limited to one dimension (does anyone use multi-dimentional SAFEARRAYs?) and provides one class for the SAFEARRAY and another for the data itself (the lock is a resource, too), but the usage is pretty nifty. See comvector.h for the what and the how.

    Also, Ron Jacobs sent me an ATL port of COleSafeArray called CComSafeArray that I’ve made available here.

    July 25, 2001 tools

    CComDate

    July 25, 2001

    This zip provides two classes for use with dates and times under Windows:

    • CComDATE: Wraps the COM DATE type, providing conversions from VARIANT, DATE, ANSI string, UNICODE string, time_t, SYSTEMTIME, FILETIME, DOS time and DBTIMESTAMP data types.
    • CComSpan: Represents the result of subtracting one CComDATE from another. Useful for time/date math.
    July 24, 2001 tools

    Exposing Multiple IDispatch Interfaces

    If you’d like to know about how to expose multiple IDispatch implementations from a single COM object, check out this extensive treatment of that very topic.

    July 23, 2001 tools

    MDI Applications in ATL

    July 23, 2001

    At atlmdi.zip, please find Charles Petzold’s famous raw Win32 MDI application, MDIDemo, ported to ATL. See atlmdi.h for a set of base classes for building MDI applications in ATL and mdidemo.cpp for an example of their use.

    July 22, 2001 tools

    Fixing the External Dispatch in ATL + IE5

    July 22, 2001

    Are you getting this: Error: object doesn’t support this property or method” when you try to call a method on your ATL HTML Control exposed external dispatch (accessed via window.external in the HTML of the control)? Did it used to work with IE4 and now it doesn’t with IE5? That’s because the ATL boys played fast and loose with the identity laws of COM and, while it took the COM police a while to catch up with them, catch up with them they did.

    Download WrapperDispatch.h for an explanation of the problem and my solution to it.

    July 21, 2001 tools

    TraceHook

    July 21, 2001

    TraceHook is a member function call tracing delegator hook based on Keith Brown’s most excellent universal delegator. It allows you to write:

        // Get a COM object to wrap
        CComPtr<ICalc>  spCalc;
        spCalc.CoCreateInstance(CLSID_Calc);
    
        // Wrap it (when _DEBUG is defined only)
        TRACEHOOK(OLESTR("MyCalc"), &spCalc.p);
    
        // Use it
        spCalc->put_Sum(0);
        spCalc->Add(2);
        spCalc->Add(2);
        long nSum;
        spCalc->get_Sum(&nSum);
    

    and see the following in the debug output (with no changes to the object’s source) :

        MyCalc, ICalc::put_Sum(0)
        MyCalc, ICalc::Add(2)
        MyCalc, ICalc::Add(2)
        MyCalc, ICalc::get_Sum()
    

    Notice that the call stack is now dumped (for duals, either directly or via IDispatch, or any method with automation-compliant data types, thanks to features added by the most excellent Simon Fell! He also added the ability to hook objects created in scripting environments (or VB or Java, too), e.g.

        ' WSH Test script for CalcSvr / TraceHook
    
        ' Create the implementation of ITraceHookFactory
        set th = CreateObject("UDTraceHookSvr.TraceHook")
    
        ' Create an object (an <object> tag in HTML would be fine, too)
        set calc = CreateObject("CalcSvr.Calc")
    
        ' Trace all further calls on calc
        th.ComTrace "MyCalc", calc
    
        calc.sum = 0
        calc.add 2
        calc.add 2
        msgbox "2+2= " & calc.sum
    

    would yield the following debug output:

        MyCalc, IDispatch::(Invoke) sum(0)
        MyCalc, IDispatch::(Invoke) add(2)
        MyCalc, IDispatch::(Invoke) add(2)
        MyCalc, IDispatch::(Invoke) sum() returned 4
    

    The source, pre-built binaries and client-side headers are available here. The pre-built binaries include Keith’s delegator as well.

    July 20, 2001 tools

    CAspPtr

    If you’ve ever had to write the code to pull the ASP intrinsic objects from the MTS context, you might appreciate CAspPtr, which allows the following:

    STDMETHODIMP CJon::DoIt() {
      CAspPtr<IResponse> spResponse;
      if( spResponse ) {
        spResponse->Write(CComVariant(OLESTR("Baby got <b><i>Response</i></b>.")));
      }  
      return S_OK;
    }
    

    CAspPtr is available here and was inspired by Jon Flanders. Thanks, Jon!

    July 19, 2001 tools

    Smart IEnumVARIANT

    Visual Basic and its variants (sic) use IEnumVARIANT to implement the For-Each statement. Unfortunately, they only ask for 1 element at a time, leading to terrible performance across apartments. I propose two solutions. One allows you to wrap any collection in a CollectionBuffer object and set the buffering yourself, e.g.

    Dim collBuffer As Object
    Set collBuffer = CreateObject("SmartEnumSvr.CollectionBuffer")
    collBuffer.Collection = coll ' coll is an interface on any collection
    collBuffer.BufferSize = 1024 ' How many items would you like buffered?
    
    c = 0
    For Each v In collBuffer ' Uses SmartEnumVARIANT to buffer items
        c = c + 1
    Next v
    MsgBox "Counted " & c
    	

    The second solution allows you to leverage SmartEnumVARIANT on the server-side, seamlessly to the client. A detailed explanation and code is available here.

    July 19, 2001 tools

    SmartEnumVARIANT

    The Problem

    VB/VBScript provides the implementation of For-Each using an implementation of IEnumVARIANT exposed from a collection via the _NewEnum method. Unfortunately, VB uses 1 for the argument to Next, making round-trip time terrible.

    A Solution:
    If you don’t own the collection implementation code…

    If you don’t own the collection implementation code, you can still wrap the collection in a custom object called the CollectionBuffer, which implements the following interface:
    [
    	object,
    	uuid(B6175081-83D4-11D2-987D-00600823CFFB),
    	dual,
    	helpstring("ICollectionBuffer Interface"),
    	pointer_default(unique)
    ]
    interface ICollectionBuffer : IDispatch
    {
        [propget, helpstring("property Collection")] HRESULT Collection([out, retval] IDispatch** pVal);
        [propput, helpstring("property Collection")] HRESULT Collection([in] IDispatch* newVal);
        [propget, helpstring("property BufferSize")] HRESULT BufferSize([out, retval] long *pVal);
        [propput, helpstring("property BufferSize")] HRESULT BufferSize([in] long newVal);
        [propget, id(DISPID_NEWENUM)] HRESULT _NewEnum([out, retval] IUnknown** ppunkEnum);
    };
    
    The Collection property is used to pass in the collection object to which you’d like buffered access. The BufferSize property is used to control how many VARIANTs you’d like to have returned on each call to Next. The implementation of _NewEnum gets the IEnumVARIANT interface from the collection and wraps it in a buffered implementation of IEnumVARIANT called SmartEnumVARIANT.

    The SmartEnumVARIANT object manages buffered access to the underlying IEnumVARIANT. VB can still ask for one item at a time, but the items will come out of the buffer. Depending on the buffer size, this can improve performance by many order of magnitude.

    Usage

    The following VB code uses an unbuffered collection and is slow:
    Dim coll As Object
    Set coll = CreateObject("DumbEnumSvr.CollectionOfNumbers")
    coll.CountOfNumbers = 10000
    
    Dim v As Variant
    Dim c As Long
    For Each v In coll
        c = c + 1
    Next v
    MsgBox "Counted " & c
    
    This VB code wraps the unbuffered collection in the CollectionBuffer object:
    Dim collBuffer As Object
    Set collBuffer = CreateObject("SmartEnumSvr.CollectionBuffer")
    collBuffer.Collection = coll
    collBuffer.BufferSize = 1024
    
    c = 0
    For Each v In collBuffer
        c = c + 1
    Next v
    MsgBox "Counted " & c
    

    Another Solution:
    If you do own the collection implementation code…

    If you do have the source to the collection, there’s no reason that VB clients have to do anything. Instead, your implementation of IEnumVARIANT can use a manual form of handler marshaling (invented, as far as I know, by Don Box —  the manual form, MS invented handler marshaling…).

    The handler marshaling works like this:

    1. The server-side implementation of IEnumVARIANT implements IMarshal.
    2. Server-side enumerator returns CLSID_SmartEnumVARIANT when GetUnmarshalClass is called.
    3. Server-side enumerator marshals the interface of it’s own stub (obtained by calling CoGetStandardMarshal) into the stream provided during the call to GetMarshalSizeMax and MarshalInterface.
    4. On the client-side, the Proxy Manager used the CLSID provided by the server-side enumerator to create an instance of SmartEnumVARIANT.
    5. The SmartEnumVARIANT object also implements IMarshal and it will pull the marshaled stub to the real implementation of IEnumVARIANT out of the marshal packet.
    6. The SmartEnumVARIANT becomes a smart proxy,” forwarding calls to the server-side implementation of IEnumVARIANT. However, instead of forwarding _Next calls directly, the calls are buffered for efficiency.
    This solution is nice because the VB client doesn’t have to do anything special. When the server-side implementation of IEnumVARIANT is marshaled to the client, the SmartEnumVARIANT automatically becomes the smart proxy, making buffered calls on the server.

    For the handler marshaling to work, the server-side enumerator must implement IMarshal appropriately. In UseSmartEnum.h, I’ve provided an implementation of IMarshal for this purpose:

    template <typename Deriving, ULONG celtBuffer = 1024>
    class IMarshalForSmartEnumImpl : public IMarshal {...};
    
    For example, the CollectionOfNumbers2 example class uses IMarshalForSmartEnumImpl to add IMarshal to CComEnum like so:
    typedef CComEnum< IEnumVARIANT, &IID_IEnumVARIANT, VARIANT, _Copy<VARIANT> > CComEnumVariant;
    
    class CSmartProxiedEnumVARIANT :
        public CComEnumVariant,
        public IMarshalForSmartEnumImpl<CSmartProxiedEnumVARIANT, 1024>
    {
    public:
    BEGIN_COM_MAP(CSmartProxiedEnumVARIANT)
        COM_INTERFACE_ENTRY(IMarshal)
        COM_INTERFACE_ENTRY_CHAIN(CComEnumVariant)
    END_COM_MAP()
    };
    

    The Source

    CollectionBuffer, SmartEnumVARIANT, IMarshalForSmartEnumVARIANT and two samples, CollectionOfNumbers (which doesn’t use handler marshaling) and CollectionOfNumbers2 (which does use handler marshaling) are available here.

    Copyright

    This source is copyright (c) 1998, Chris Sells.
    All rights reserved. No warrenties extended. Use at your own risk.
    Comments to csells@sellsbrothers.com
    July 18, 2001 tools

    Implementing Marshal-by-Value using ATL

    July 18, 2001

    Not too long ago, Jonathan Borden, jborden@MEDIAONE.NET, posted a nifty class called IMarshalByValueImpl that implemented IMarshal for objects interested in being marshaled by value . It was built in the ATL style, i.e. it used fun template tricks, and depended on the COM class also implementing either IPersistStream or IPersistStreamImpl. And, in fact, ATL provides an implementation of IPersistStreamInit called IPersistStreamInitImpl. However, IPersistStreamInitImpl has one fatal flaw: it implements GetSizeMax by returning E_NOTIMPL. This breaks Jonathan’s IMarshalByValueImpl, which depends on a sane implementation of GetSizeMax from the class.

    IPersistStreamInitImpl2 leverages the property map of ATLs IPersistStreamInitImpl to build GetSizeMax. The code is not pretty. It’s just pieced together from ATLs implementation of IPersistStreamInit::Save and CComVariant::WriteToStream, but it seems to work (thanks to Dharma Shukla, v-dharsh@microsoft.com, for testing it!).

    Here’s the usage for giving a class MBV:

    class PassByValue :
      public CComObjectRootEx<CComMultiThreadModel>,
      public CComCoClass<PassByValue, &CLSID_PassByValue>,
      public IDispatchImpl<IPassByValue, &IID_IPassByValue>,
      public IMarshalByValueImpl<PassByValue>,
      public IPersistStreamInitImpl2<PassByValue>
    {
    public:
    BEGIN_COM_MAP(PassByValue)
      COM_INTERFACE_ENTRY(IDispatch)
      COM_INTERFACE_ENTRY(IPassByValue)
      COM_INTERFACE_ENTRY(IMarshal)
      // Don't need to expose these to the world
      //COM_INTERFACE_ENTRY(IPersist)
      //COM_INTERFACE_ENTRY  
      (IPersistStreamInit)
    END_COM_MAP()
    
    BEGIN_PROP_MAP(PassByValue)
      // List of properties to marshal-by-value
      ...
    END_PROP_MAP()
    
      // IPassByValue methods
      ...
    
    private:
      // Whatever data members you wish to marshal
      ...
    
    public:
      BOOL m_bRequiresSave; // Required by IPersistStreamInitImpl2
    };
    July 17, 2001 tools

    Implementing dispatch-based interfaces in ATL

    July 17, 2001

    There are three kinds of ways to declare a dispatch-based interface in IDL, but ATL (as of version 3.0), only supports the implementation of 1.5 of them (duals and a raw dispinterfaces for handling events).  The ATL Dispatch Sampledemonstrations the use of three ATL-based classes, one for implementing each type of dispatch-based interface. The header file that defines these classes, dispimpl2.h, is provided for use in your own projects.

    BTW, thanks to Ehab Kashkash for making this code work under VS.NET as well as VC6.

    July 16, 2001 tools

    MeowMoniker

    If you’re into COM Monikers, here’s one that I like.

    July 15, 2001 tools

    Basic Monikers

    Wish there was a moniker that did CoCreateInstance just like the Class Moniker calls CoGetClassObject? Wish you were able to compose the Class Moniker with a host name? Then you’ll want the BasicMonikers project, which bundles together the New moniker and the Host moniker. Sample syntax follows:

    dm.newmk.1:Excel.Application
    dm.newmk.1:00024500-0000-0000-C000-000000000046:
    dm.hostmk.1:frodo:!dm.newmk.1:00024500-0000-0000-C000-000000000046:
    dm.hostmk.1:frodo:!clsid:00024500-0000-0000-C000-000000000046:
    July 14, 2001 tools

    regsvr.reg

    July 14, 2001

    regsvr.reg is a regedit script file that adds Register COM Server and Unregister COM Server to the context menu for DLLs, OCXs and EXEs under Win95+ and NT4+. In addition, it’s also been updated to add Register TypeLib and Unregister TypeLib commands to .tlb, .odl, .dll, .ocx and .exe files, using VC6′s new regtlib tool.

    July 13, 2001 tools

    ATL Composition

    July 13, 2001

    I’ve developed a set of macros to support implementing interfaces using nested composition in ATL (the one common way of implementing interfaces they neglected). The benefit of composition is that it is easy to implement multiple interfaces with methods with the same name but that require different behavior, e.g.

    interface IArtist : IUnknown {
         HRESULT Draw();
    }
    
    interface ICowboy : IUnknown {
         HRESULT Draw();
    }

    The benefit of this particular implementation is that it has no object size overhead. Interfaces implemented using nested composition have no greater overhead than using multiple-inheritance. Feel free to download atlcompose.h for your own use.

    July 12, 2001 tools

    Client-Side Enumeration Iterator

    July 12, 2001

    Have you ever been jealous of the VB programmer who could write this:

    sub EnumVariants(col as Collection)
        dim v as variant for each v in col
            ' Do something with v
        next v
    end sub

    If so, you may be interested in the STL-style IEnumXxx iterator I’ve built. You’ll also need a supporting file, atlcopies.h.

    July 12, 2001 tools

    STL Enumerator Iterator

    Have you ever been jealous of the VB programmer who could write this:

    sub EnumVariants(col as Collection)
        dim v as variant for each v in col
            ' Do something with v
        next v
    end sub

    when we poor C++ programmers have to write this:

    void EnumVariants(IEnumVARIANT* pevar)
    {
        HRESULT hr;
        enum { CHUNKSIZE = 100 };
        VARIANT rgvar[CHUNKSIZE] = { 0 };
        do {
            ULONG cFetched;
    
            hr = pevar->Next(CHUNKSIZE, rgvar, &cFetched)
            if( SUCCEEDED(hr) ) {
                if( hr == S_OK ) cFetched = CHUNKSIZE;
                for( ULONG i = 0; i < cFetched; i++ )
                {
                    // Do something with rgvar[i]
                    VariantClear(&rgvar[i]);
                }
            }
        }
        while (hr == S_OK);
    }

    Well no more! I’ve built an enumeration iterator class that holds IEnumXxx and exposes an STL-compatible iterator:

    template <typename EnumItf, const IID* pIIDEnumItf,
              typename EnumType, typename CopyClass = _Copy<EnumType> >
    class enum_iterator;

    It uses the same copy policy classes as ATL for convenience. Now you can write:

    void EnumVariants(IEnumVARIANT* pevar)
    {
        typedef enum_iterator<IEnumVARIANT, &IID_IEnumVARIANT, VARIANT> EVI;
        for( EVI i = EVI(pevar); i != EVI(); ++i )
        {
            VARIANT&    v = *i;
            // Do something with v
        }
    }

    or you can use the typedefs for the standard enumerators:

    void EnumVariants(IEnumVARIANT* pevar)
    {
        for( variant_iterator i = variant_iterator(pevar);
             i != variant_iterator();
             ++i )
        {
            VARIANT&    v = *i;
            // Do something with v
        }
    }

    or you can use STL algorithms (this is my personal favorite):

    struct DoSomethingWithVariant
    {
        void operator()(const VARIANT& v)
        {
            // Do something with v
        }
    };
    
    void EnumVariants(IEnumVARIANT* pevar)
    {
        for_each(enum_variant(pevar),
                 enum_variant(),
                 DoSomethingWithVariant());    
    }

    Feel free to download the enum_iterator class for your own use. You’ll also need a supporting file, atlcopies.h.

    July 11, 2001 tools

    GitHelp

    July 11, 2001

    githelp.hdefines a set of wrappers for implementing inter-thread marshaling using the GIT instead of streams. githelp.cpp provides the non-inline implementation. For another spin on GIT usage, check out Don Box’s GitLip.

    June 30, 2001 tools

    Codename TextBox

    The Need for Code Generation

    Have you ever wanted to generate code like the wizards do, i.e. start with a template, mix in some symbols and boom, out comes the code? If you’re building a custom AppWizard, you define code like so:

        int WINAPI WinMain(HINSTANCE hinst, HINSTANCE, LPSTR, int nShow) {
        $$IF(coinit)
            // Initialize COM
            CoInitialize(0);
    
        $$ENDIF
            // Initialize the ATL module
            _Module.Init(0, hinst);
        $$IF(axhost)
    
            // Initialize support for control containment
            AtlAxWinInit();
        $$ENDIF
    
            // Create and show the main window
            HMENU   hMenu = LoadMenu(_Module.GetResourceInstance(),
                           MAKEINTRESOURCE(IDR_$$ROOT$$));
        ...
        

    This is fine if you’ve got the MFC-based interpreter building your code and you’re willing to live within the boundaries of a very small set of features. The ATL Object Wizard-style of generation is similar, i.e.

        class [!ClassName] : 
         public CAxDialogImpl<[!ClassName]>
        {
        public:
         [!ClassName]()
         {
         }
        [!crlf]
        ...
        

    Again, only good if you’re running under the ObjectWizard and again, somewhat limited. What you really want is to be able to do things ASP-style, e.g.

        <%@ language=vbscript %>
        <% ' test.cpp.asp %>
        <%
            greeting = Request.QueryString("greeting")
            if len(greeting) = 0 then greeting = "Hello, World."
        %>
        // test.cpp
    
        <% if Request.QueryString("iostream") <> "" then %>
        #include <iostream>
        using namespace std;
        <% else %>
        #include <stdio.h>
        <% end if %>
    
        int main()
        {
        <% if Request.QueryString("iostream") <> "" then %>
            cout << "<%= greeting %>" << endl;
        <% else %>
            printf("<%= greeting %>\n");
        <% end if %>
            return 0;
        }

    In this case, you get the same effect as the other two, but you’ve got the full power of a scripting language. However, for this to work, you had to run under ASP… until now…

    TextBox

    TextBox is a ASP-like script host that will process any file you give it looking for:

    • text blocks
    • script blocks (<% script %>)
    • output blocks (<%= output %>)
    • An optional language block as the first line in the file only (<%@ language= language %>)
      (TextBox defaults to vbscript and currently only works with vbscript and jscript).

    TextBox pre-processes the text to turn the whole thing into into script and hands it to the scripting engine for execution, outputting the result to standard out. Whatever features of the scripting language you want to use, feel free.

    Usage

    To provide for I/O, TextBox emulates ASP somewhat. It provides two intrinsics, the request object and the response object. The Request object has a single property, QueryString, that works just like ASP. The Response object has a single property, Write, just like ASP. In fact, if you only use Request.QueryString and Response.Write, you should be able to test your script files using ASP.

    To set name/value pairs for use by the script via the Request object, the usage of TextBox is like so:

        usage: textbox <file> [name=value]

    For example, to interpret the file above, any of the following command lines would work:

        textbox test.cpp.asp
        textbox test.cpp.asp greeting="Double Wahoo!"
        textbox test.cpp.asp iostream=true greeting="Double Wahoo!"
        

    The first would yield the following output:

        // test.cpp
    
        #include <stdio.h>
    
        int main()
        {
            printf("Hello, World.\n");
            return 0;
        }
        

    while the last would yield the following:

        // test.cpp
    
        #include <iostream>
        using namespace std;
    
        int main()
        {
            cout << "Double Wahoo!" << endl;
            return 0;
        }
        

    Errors and Debugging

    If the scripting engine finds an error, it will notify TextBox, who will notify you. However, if you’ve got script debugging enabled on your machine, the scripting engine will ask you if you’d like to fire up the debugger, showing you exactly the offending code.

    Not Just Code

    Of course, TextBox is good for the generation of any text, not just code.

    Download

    TextBox is available for download. It’s just a prototype, so please adjust your expectations accordingly. If you have any comments, please send them to csells@sellsbrothers.com.

    Copyright

    Copyright (c) 1998-2001, Chris Sells All rights reserved. NO WARRANTIES EXTENDED. Use at your own risk.

    February 22, 2001 tools

    TZ Data to XML Project

    These are the outputs of my attempts to translate the native tz data into XML for easier parsing for applications other than implementations of the standard C routines related to time.

    This is the first step in a project to merge time zone and map data by the Time Zone Map Group, lead by Chuck Ellis.

    Done

    • tz2xml.zip: A VC++ program to translate native tz data files into XML. Warning: This requires a certain directory structure and a few modified files from the tz code to export shared functions. I’m working to fix that.
    • /tools/tz/tzxml.zip: Native tz data files translated to XML, including comments. Suitable for replacement as the native format. Generated by running tz2xml on the tz data files.

    Yet To Do

    • Namespace support.
    • XSD support.
    • An XSLT to translate back to native tz data format.
    • An XSLT to output popular data needs, e.g. all the zones, all the rules, etc.
    • An updated zic to use the new XML format instead of the existing format.
    • Unix port of tz2data (I’ll need help on that one).

    Help!

    Unfortunately, I’m but one man. If you’d like to help on any of these projects, let me know.

    License

    Copyright © 2001 by Chris Sells. All rights reserved. No warrantees extended. Use at your own risk. You may not distribute any portion of the tz2xml source code without express written consent. You may, however, use the source with no fee or redistribute the sample XML data at will.
    February 16, 2001 tools

    Genghis

    June 26, 2000 tools

    UrlRun

    Mon, 26 Jun 2000

    To deal w/ the number of wrapped URLs I get in my email box, I built UrlRun. It checks the clipboard for an URL, no matter how broken, strips spaces, newlines and greater thans out of it and runs IE. To handle an URL as show above, select it, copy it to the clipboard and launch UrlRun.exe. I keep it on my QuickStart toolbar.

    If you happen to be using Outlook 2000 or Outlook XP, Tim Tabor has built an UrlRun add-in that does the magic by simply right-clicking on a mangled URL that’s you’ve selected. It’s pure sex.

    November 1, 1999 tools

    Welcome to Attila!

    Welcome to Attila!

    Attila GDI sample
    (Jim Murphy likes Attila and GDI a little too much…)

    Welcome to Attila

    Attila stands for ATL for Applications.” Attila is a set of extensions built on top of ATL to provide application-level services in the same flavor as MFC. Towards that end, Attila uses a lot of the same notions as ATL, e.g. heavy use of templates, static binding and reliance on the compiler and the linker doing their job.  Also, in the flavor of ATL, Attila is under-documented and requires a lot of user investment to make use of it. However, once you do, we think you’ll find the flexibility and efficiency worth it. If you don’t, you haven’t lost much, cuz Attila is free. Enjoy.

    Disclaimer

    Attila isn’t a class library. Some of the headers depend on some of the others. Some are stand-alone. You are free to pull in the pieces of Attila that you need and leave the rest alone. Most of the headers were built by different folks and while every effort was made to keep things consistent by choosing ATL design techniques, everyone does things there own way.

    This work is the work of the individuals involved and does not represent any contribution of their respective employers. You are under no obligation to use any of Attila at any time, but if you do, please abide by the License.

    License

    Attila is copyright (c) 1999-2000 by its contributors.
    All rights reserved.
    No warrantees extended.
    Use at your own risk.

    You may use Attila in your product in compiled form without royalty.
    You may not distribute Attila in source code form without the express written consent of the contributors.

    The official home of Attila is http://www.sellsbrothers.com.

    Installation

    The current Attila bits are located at attila.zip. Download and unzip them into the folder of your choice (making sure to preserve path names). Make sure to add the Attila include directory to your compilers include path. For example, if you unzipped Attila into the c:\attila directory, add c:\attila\include to your compiler’s include path. You can check to make sure you did this right by building any of the samples in the samples folder.

    Support

    Please do not send Chris Sells or any of the other contributors personal email complaining about Attila. Also please do not post Attila bug reports to any other mailing list, e.g. DCOM or ATL. If you like, you can submit bugs to the Attila Hit Squad mailing list (but only if you’re a member). Nobody there is under any responsibility to fix anything in Attila, but you might shame someone into it. A much better way to contribute to the life of Attila is to submit the fix along with the bug report. Or even better, join the Attila Hit Squad mailing list and fix bugs submitted by others.

    Official Attila Contributors

    Who Did What

    • Chris did a lot of the initial framework.
    • Justin did CMsgTranslator.
    • Ed did CRegPreferences and CRegWindowSerializer.
    • Curt did the common dialogs and restructured and added AX support to property pages.
    • Matt and Shawn did work on the coolmenus and coolbars.
    • Simon did the multi-SDI stuff.
    • Joe did the command UI routing support.
    • Anthony did the command routing.
    • Rodrigo and Jim did the GDI wrappers.
    • Jorge did the Doc/View stuff.
    • Brad did the DDX/DDV support.
    • Shawn did CSimpleList.

    Documentation

    You might find some implementation notes for Attila in the docs folder, but you probably won’t. If you have any documentation you’d like to submit, we’d love to have it.

    Samples

    Check the samples.htm file in the samples folder of the Attila distribution. You can build all of the samples from the command line using the buildall.cmd batch file in the samples folder.

    CComSingleInstanceModule

    • Uses Single_Instance_App as the DDE application name, preventing more than one single instance ATL application from running at a time. DDE application name should be based on something unique to the application, e.g. the module name.

    SdiDocView

    • No MRU.

    MdiDocView

    • None of the MDI accelerators work, e.g. ctrl-tab.
    • There seems to be a lot of glue code in CMainWindow that could be hoisted to a base class.
    • No MRU.

    LookOut

    • Left pane needs work.

    History

    • 8/14/00, Various property sheet enhancements.
    • 1/28/00, Simulated PSN_APPLY for Wizards and PSN_APPLY for modeless propsheets bug fix.
    • 12/8/99, CSimpleList and bug fixes.
    • 11/29/99, Bug fixes.
    • 11/25/99, Bug fixes.
    • 11/10/99, DDX/DDV and bug fixes.
    • 11/1/99, Bug fixes.
    • 11/1/99, Beta release.
    June 27, 1997 tools

    Welcome to MeowMoniker!

    Overview

    MeowMoniker and Feline are COM objects designed and built by Chris Sells, with a great deal of input from Don Box and Tim Ewald. The MeowMoniker is a custom moniker derived from the CComMoniker class implemented by Don Box, Tim Ewald and Chris Sells.

    To contact the authors with suggestions or comments, use csells@sellsbrothers.com, tewald@obelisk-llc.com and dbox@microsoft.com.

    MeowMoniker Usage

    Microsoft tags every marshalled interface reference packet with the signature MEOW (which they claim stands for Microsoft Extended Object Wire-representation). This binary packet is a serialized interface reference used for inter-apartment activation. Turning this binary packet into a string (via some encoding technique, i.e. Base64) allows a serialized interface pointer to be passed more easily than binary data, e.g. as a command-line argument or in an HTML page.

    Monikers, on the other hand, provide a general-purpose way for a client to separate itself from the object binding policy. These object binding polices can be composed and stored in strings. These strings contain a string description of the binding policy and policy parameters. By building a custom moniker that takes a string-ized interface reference as a parameter, a client can use the standard moniker-based binding algorithm and bind to a running object via an interface reference. The MeowMoniker is an implementation of a moniker that can compose display names out of interface pointers and bind to objects via its display names.

    To create a MeowMoniker from an interface pointer, MeowMoniker.dll exposes the CreateMeowMoniker() function:

    STDAPI CreateMeowMoniker(
       IUnknown* punk,      // Pointer to the interface to be marshaled
       REFIID riid,     // Reference to the identifier of the interface
       DWORD dwDestContext, // Destination context
       DWORD mshlflags,     // Reason for marshaling
       IMoniker** ppmk);    // Indirect pointer to the moniker

    e.g.

    IMoniker* pmk;
    hr = CreateMeowMoniker(punkObject,
                   IID_IUnknown,
                   MSHCTX_DIFFERENTMACHINE,
                   MSHLFLAGS_NORMAL,
                   &pmk);

    To obtain the MeowMoniker’s display name, use the GetDisplayName() member function of the IMoniker interface:

    HRESULT GetDisplayName(
       IBindCtx *pbc,   // Pointer to bind context to be used
       IMoniker *pmkToLeft,   // Pointer to moniker to the left in the composite
       LPOLESTR *ppszDisplayName);   //Indirect pointer to the display name

    e.g.

    IBindCtx* pbc;
    hr = CreateBindCtx(0, &pbc);
    wchar_t* pwszDisplayName;
    hr = pmk->GetDisplayName(pbc, 0, &pwszDisplayName);

    To parse a display name composed by the MeowMoniker, OLE32.dll exposes the MkParseDisplayName() function:

    WINOLEAPI MkParseDisplayName(
       LPBC pbc,   // Pointer to the bind context object
       LPCOLESTR szUserName,   // Pointer to display name
       ULONG FAR *pchEaten,   // Pointer to the number of characters consumed
       LPMONIKER FAR *ppmk);   // Indirect pointer to the moniker

    e.g.

    IBindCtx* pbc;
    hr = CreateBindCtx(0, &pbc);
    IMoniker* pmk;
    ULONG cchEaten;
    hr = MkParseDisplayName(pbc,
         pwszDisplayName,
         &pmk);

    To bind to a object, use the BindToObject() member function of the IMoniker interface:

    HRESULT BindToObject(
       IBindCtx *pbc,   // Pointer to bind context object to be used
       IMoniker *pmkToLeft,   // Pointer to moniker that precedes this one in the composite
       REFIID riidResult,   // IID of interface pointer requested
       void **ppvResult);   // Indirect pointer to the specified interface on the object

    e.g.

    IUnknown* punk;
    hr = pmk->BindToObject(pbc, 0, IID_IUnknown, (void**)&punk);

    Note: The MeowMoniker does not current support composition or the IMoniker interface member function BindToStorage().

    Feline Usage

    Since neither VB nor VBScript supports calling CreateMeowMoniker() and since VBScript has no equivalent of the VB function GetObject(), the Feline object provides a dual-interface for making display names out of interface pointers and parsing moniker display names:

    [
       object,
       uuid(CB18CB8E-C7CC-11D0-9A44-00008600A105),
       dual,
       helpstring("DIFeline Interface"),
       pointer_default(unique)
    ]
    interface DIFeline : IDispatch
    {
       [id(1), helpstring("Returns the Meow Moniker name of an interface pointer")]
       HRESULT GetDisplayName([in] IDispatch* pdisp, [out, retval] BSTR* pbstrName);

       [id(2), helpstring("Returns an interface pointer given any moniker display name")]
       HRESULT ParseDisplayName([in] BSTR bstrName, [out, retval] IDispatch** ppdisp);
    };


    The following is an example Active Server Page that creates an object on the server, creates a display name using the object’s interface pointer and uses the display name to create a client-side script. The client-side script uses its own instance of a feline object to parse the display name and bind to the object created on the server-side.

    <HEAD>
    <TITLE>feline.asp</TITLE>
    </HEAD>
    <BODY>

    <object classid="clsid:CB18CB8F-C7CC-11D0-9A44-00008600A105"
       runat=server
       id=feline>
    </object>

    <object classid="clsid:7CF322E0-29A9-11D0-B367-0080C7BC7884"
       runat=server
       id=pt>
    </object>

    <object classid="clsid:CB18CB8F-C7CC-11D0-9A44-00008600A105"
       id=feline>
    </object>

    <script language=vbscript>
       dim pt
       set pt = feline.ParseDisplayName("<%= feline.GetDisplayName(pt) %>")
       pt.x = 100
       pt.y = 200
       document.write pt.x & ", " & pt.y
    </script>

    </BODY>
    </HTML>

    CComMoniker Implementation

    The MeowMoniker derives most of its functionality from CComMoniker, provided in mkbase.h and mkbase.cpp. This base class implements IMoniker, IParseDisplayName, IROTData and IMarshal (for marshal-by-value). This implementation uses the moniker’s display name as the persistent state. The custom moniker implementor deriving from CComMoniker must provide the CSLID of the moniker as the single template parameter (used in the implementation of the GetClassID() member function of IPersist and the GetUnmarshalClass() member function of IMarshal). The implementor may override any of the base class’s member functions but must implement these three IMoniker members:

    STDMETHODIMP BindToObject(
       IBindCtx* pbc,
       IMoniker* pmkToLeft,
       REFIID riidResult,
       void** ppvResult);

    STDMETHODIMP GetDisplayName(
       IBindCtx* pbc,
       IMoniker* pmkToLeft,
       LPOLESTR* ppszDisplayName);

    STDMETHODIMP ParseDisplayName(
       IBindCtx* pbc,
       IMoniker* pmkToLeft,
       LPOLESTR pszDisplayName,
       ULONG* pchEaten,
       IMoniker** ppmkOut);

    As a aid in parsing display names, the CComMoniker class provides the following helper function:

    bool MatchesProgID(
       const wchar_t* pwszDisplayName,  // Display name being parsed
       const wchar_t** ppwszDisplayParam);  // Pointer to character past :

    This function checks the display name for a leading ProgID or VersionIndependentProgID followed by a colon and returns a pointer to the first character of the display name parameter(s), i.e. one character past the colon. The implementation of this function requires the derived class to implement the following member functions:

    virtual const wchar_t* ProgID() =0;
    virtual const wchar_t* VersionIndependentProgID() =0;

    e.g.

    const wchar_t* ProgID() { return L"dm.meow.1"; }
    const wchar_t* VersionIndependentProgID() { return L:dm.meow"; }

    CoMeowMoniker Implementation

    The MeowMoniker is an ATL object named CoMeowMoniker. It derives from CComMoniker and provides an implementation of the required members only. The bulk of the implementation is contained in the two member functions, MarshalInterface() and UnmarshalInterface(). These two member functions manage the Base64 encoding and decoding of the interface pointer. The actual Base64 implementation is kept in Base64.cpp.

    CoFeline Implementation

    The Feline is an ATL object named CoFeline. Its implementation of GetDisplayName() uses a MeowMoniker. Its implementation of ParseDisplayName() uses MkParseDisplayName() so that any moniker’s display name can be used.

    Download

    Here.

    YACL

    The implementation of the MeowMoniker is based on utilities provided in the YACL (Yet Another COM Library), developed and maintained by Don Box and available at Don’s YACL web site. The pieces of YACL
    that I have used, I’ve included in the appropriate directories.

    Revisions

    6/15/98

    • Updated MeowMoniker to perform GetSizeMax properly.
    • Updated MeowMoniker and CComMonikerBase to use CComPtr and CComQIPtr instead of SmartInterface.
    • Removed use of HRESULTEX and therefore the use of C++ exception handling.
    • Moved some includes around.
    • Reduced RelMinDepend build from 89KB to 80KB. Could probably reduce it more if I could find Matt Pietrek’s tinycrt and stop using the real CRT.

    Copyright

    MeowMoniker, copyright (c) 1997, Chris Sells.
    Feline, copyright (c) 1997, Chris Sells.
    CComMoniker, copyright (c) 1997, Don Box, Tim Ewald and Chris Sells.
    YACL, copyright (c) 1997, Don Box.
    Extensions to YACL, copyright (c) 1997, Tim Ewald and Chris Sells.
    All rights reserved. NO WARRANTIES ARE EXTENDED. USE AT YOUR OWN RISK.