MindManager 7 "ToDo List" Add-in development Part 3: Initial Working Code

Successful running of the add-in!  Once I added the required Registry settings, the add-in finally made itself known (through the MessageBox’es).  I learned that the HKCR settings are also necessary for other calls to succeed, but the essential behaviour of being recognized and loaded by MindManager was entirely dependent on having those Registry settings populated in the \Addins key.

At first I just used a .REG file to populate the Registry settings, following the model of the MM7 Sample Addin.  I had to do this as a side-effect of the work the helpful folks on the Mindjet “Dev Support” team did to rip out a bunch of “custom actions” stuff from my MM7 add-in solution, and this appears to have included all the Registry settings as well.  [Note: the Mindjet dev support folks are really helpful, and I’m not blaming them for this — the MM7 VS project template was (a) developed under Visual Studio 2005 not 2008 (which I’m using), and (b) was last updated last summer (and is no currently under active development I’d guess because the person who originally created it has since left the company — at least, that’s the usual way these things occur).

However, it’s not quite perfectly operating yet — just before the OnStartupComplete dialog box comes up, the following error is thrown by MM7:

image

According to this thread, this means that Addin ID must match the first parameter to applicationObject.Commands.Add().  In my code that parameter is “ParanoidMike.ToDoListBuilder.AddIn”, and my first guess is that the key under HKLM\Software\Mindjet\MindManager\7\AddIns needs to have the same name (which it currently doesn’t).  Upon changing it to match, I finally saw the Add-Ins Ribbon tab that I hadn’t been able to expose until now.

On to a little code…

First stage: Ribbon Button That Counts Tasks in Current Map

I wanted to use as much of the code from the MindManager7 Sample Add-in as possible… however somehow I ended up not using much or any of that.  This was my original plan:

  1. Create variable for MM application
    • Sample\MmxUtility\Helper.cs: MmxUtility.Helper.GetMmxMap()
  2. Beg/borrow/steal ribbon button code from existing add-in
    • Sample\MmxUtility\RibbonTabBase.cs (base class for creating a new Ribbon tab)
    • Sample\MmxUtility\ControlStripBase.cs
  3. Attach function to Ribbon button
  4. Create variable for Current Map
    • Application.ActiveDocument
  5. Find the Base Topic and enumerate
    • Sample\MmxUtility\Helper.cs: Helper.BaseTopicFinder()
  6. Create variable for Count
  7. Create For Each loop of Task objects, and count ’em
    • Sample\MmxUtility\Helper.cs (Topic attributes)

Instead, though, I ended up trying to separate out the UI from the data manipulation code, and leveraging the code I’d written from the MindManager DevZone article “How to Create a MindManager 7 Add-in Using C#“. 

This is what resulted:

        private void mmCommand_Click()
        {
            // Process the MindManager command and say hello
            MessageBox.Show("Hello world! (C#)", addInDisplayName);

            // Get the current Map
            Mindjet.MindManager.Interop.Document currentMap;
            currentMap = applicationObject.ActiveDocument;

            // Count the current Map's Tasks and display for the user:
            int count;
            ToDoListBuilder taskCounter = new ToDoListBuilder();
            count = taskCounter.countTasks(currentMap);
            MessageBox.Show("There are " + count.ToString() + " Tasks in this Map");
        }
    class ToDoListBuilder
    {
        public int countTasks(MMInterop.Document mindMap)
        {
            int tasksCount; // count of the number of Topics that are Tasks
            MMInterop.Range range; // just a collection of whatever we can find in the Document 🙂
            range = mindMap.Range(MMInterop.MmRange.mmRangeAllTopics, true);
            tasksCount = 0; // initialize to avoid error CS1065
            foreach (MMInterop.Topic topic in range)
            {
                if (topic.Task.Complete >= 0)  // this is intended to test whether the "topic" has Task attributes attached to it, and is how ResultsManager characterizes a Task
                {
                    tasksCount++; // increment this counter variable
                }
            }
            return tasksCount;
        }
    } 

The key magic in this code was the test for whether a Topic is a Task or not:

if (topic.Task.Complete >= 0) 

I’d spotted this approach in a macro that was published on ActivityOwner, but it seemed more complicated and indirect than should be necessary.  I wondered whether something like topic.Task.IsValid() would identify whether a topic had “valid” Task characteristics.  I looked into what documentation for this method was available, but the available info is pretty sparse.  If not for the generous help from the MindManager development community like Nick Duffill, I would’ve been forced to work through this by trial & error.

Which Security Event Log audit categories are most useful on a Windows client?

Let’s say you’re looking to maximize the value of the data logged to the Security Event Log on a huge number of Windows clients (say, Windows XP SP2).

Further, let’s assume that you’re not inspecting such logs on a regular basis, but instead you just want to keep the most critical events in case you have to track down some “suspicious activity” later.  [Suspicious activity would probably include such things as successful intrusions into the PC (whether by attackers or malware), which is going to be a losing battle but worth trying.]

You have two different sets of knobs to twiddle: which categories of security events will be logged, and how the security Event Log will be configured.  The categories are the more involved thinking, so let’s start with the Event Log configuration first, shall we?

Security Event Log configuration

The default Security Event Log size on Windows XP is a paltry 512 KB.  [It got boosted on Windows Vista, so don’t go yelling at Microsoft — they heard ya already.]  The question isn’t if you should increase its size, but by how much?

When it comes down to a “best practice”, I’ve always found it to be an arbitrary choice.  This choice should be informed by the level of activity you expect (or tend) to see — many customers who turn on all logging options can fill up a 10 MB log in the space of a week, but those who make more judicious choices can survive on 2048 KB for sometimes a month.

The upper limit is somewhere in the neighbourhood of 300 MB, but that limit includes all Event Logs (even custom event logs created by other applications, I believe) — this is documented in Chapter 6 of Threats and Countermeasures.  So for example, if you’ve already set the System and Application logs to 50 MB apiece, I would strongly advise a Maximum log size of somewhere around 150-200 MB for the Security event log.  [Note: there is a bug that causes problems with Security event logs over 50 MB, which hopefully has not only been fixed in Windows Server 2003 but also Windows XP SP2.]

Aside: I’m sure there are others you might find, but on my own Windows XP box I’ve got four additional custom Event Logs:

  • Microsoft Office Diagnostics
  • Microsoft Office Sessions
  • Virtual Server
  • Windows PowerShell

The next setting to consider is how the logs will respond when they (inevitably) fill up.  There’s a setting innocuously labelled When maximum log size is reached, and there’s no perfect selection for everyone.  I’ve generally advised people to choose Overwrite events as needed, since most times, my customers would be interested in having a record of the most recent activity on the PC (e.g. tracking down details of a recent virus outbreak or suspected break-in attempt).

Finally, if you’re really anal about your Security Event logs (and what security geek doesn’t ideally want to keep them around forever?), you can enable one or two other specialized settings created just for you — but should you?

  • WarningLevel: recent versions of Windows can warn the Administrator when the Security Event log is nearly full (the usual recommendation is 80 or 90% threshold).  Windows will record a single System event with EventID = 523.  However, this is really only useful in cases where the Administrator wants to archive all Security Event Log records for later analysis or compliance checking, and they don’t already have an infrastructure for collecting and centralizing this logging info.  Warning someone of imminent failure, when they have no way to avert disaster, is really just a tease.  Thus, the more useful setting is…
  • AutoBackupLogFiles: Rather than let the log files overwrite themselves, some would prefer to archive all log entries.  This registry setting enables Windows to automatically backup and empty the specified Event Log, so that all the entries are stored in a local file on disk.  This isn’t perfect (a malicious attacker could wipe them out, for instance) but in cases where you just can’t imagine copying the security Event log between the time the 90% alarm goes off and you get the time to deal with it, this can be an effective alternative.  The most significant consequence of this is, over time, you may end up filling the OS volume with these archived files.  However, shunting such saved data to a separate, non-OS volume — or monitoring for disk space — are the kinds of problems that aren’t difficult to solve.

Security Event Log Category choices

Now the tough part: deciding which Success & Failure event categories to enable.  Leaning on Eric Fitzgerald and Randy Franklin Smith, here’s the current thinking I’m advising my customer for keeping the noise down (and which you’re welcome to leverage, if our thinking seems to fit):

Account Logon

  • This’ll identify the local (i.e. SAM-based) usernames that users have attempted to logon at this PC
  • If you’re interested in tracking actual user activity and successful break-ins, then enable Success auditing.
  • If you’re interested in (and plan to actually investigate) attempted but failed break-ins, and if your users don’t use local accounts (and thus won’t be the overwhelming cause of failed account logon attempts due to fat-fingering their password), then enable Failure auditing.  Under such circumstances, this shouldn’t be a significant contributor to the security logs.
  • Recommendation: enable Success and Failure auditing.

Account Management

  • This’ll identify such things as account creation, password reset and group membership changes.
  • Under normal circumstances these should be highly useful records (both the successful changes and the attempts) — especially if you don’t often manipulate local accounts on your XP clients.
  • Recommendation: enable Success and Failure auditing.

Directory Service Access

  • pointless — this only applies to Domain Controllers
  • Recommendation: No Auditing

Logon events

  • In a non-domain context, this doesn’t add much value over and above Account Logon auditing
  • Recommendation: No Auditing

Object Access auditing

  • This is a tricky one.  It logs little or nothing by default, even when Success and Failure auditing are enabled for this.
  • Used correctly, you can collect information with a fairly high signal-to-noise ratio.
  • Used incorrectly, however (and I was as guilty of this as anyone in my early career, and am still guilty today), and you’ll wipe out any useful information that the security log might’ve otherwise kept for you.
  • For example, I’m currently recording “Handle Closed” and “Object Access Attempted” events dozens or hundreds of times an hour.  What is being accessed?  LSASS.  Why?  Because of a single “Everyone: Full Control” auditing entry I added to the EFS\Current Keys registry key, to try to track down some odd behaviour a few months ago.  I’d forgotten about this ever since, and now I’m filling my 10 MB security log every 36 hours.
  • If you follow a VERY specific set of SACLs as in the EricFitz article linked above, then you will get some real value out of this category.
  • Recommendation: only enable Success and Failure auditing if you have specific activity you’re looking for, but be VERY careful when setting any SACLs on the system.

Policy Change

  • I’ve never seen anything in this category that helps really track down malicious behaviour
  • While it may be interesting to highlight attempted (or successful) changes to Audit policy or assigned user rights, I’m extremely skeptical that any of this information would be conclusive.
  • However, with Windows XP SP2 and the use of Windows Firewall, there are a number of very specific audit records (e.g. Event IDs 851, 852, 860) that track changes in the Windows Firewall configuration.  [It’s unfortunate that there’s not better info on the source of those changes.]
  • If you’re using the Windows Firewall in XP SP2, these records could well be useful in isolating the source, cause, or spread of a malware outbreak.
  • Recommendation: enable Success and Failure auditing when using Windows Firewall.

Privilege Use auditing

  • One of the greatest sources of log pollution, with little practical application.
  • This looks very useful to a security geek on paper, but in practice 99% of the recorded events will be (a) legitimate behaviour and (b) completely harmless.
  • Recommendation: No Auditing

Process Tracking

  • Aka “Detailed Tracking” (which is how these events are labelled in the security Event Log)
  • A great way to swell the size of your security logs, unless your PCs run a very small number of applications for very long periods of time.
  • However, when you’re using Windows Firewall, Failure auditing will record (in Event ID 861) a number of potentially useful pieces of information about any application that attempts to open an exception in the Firewall rules.
  • This logging can be very frequent (I show over 2000 events in the last 36 hours on my PC), but will give very detailed information on the the Port opened, the process that bound it, and whether the process is a service or RPC application.
  • (One good non-security use for this auditing capability is to troubleshoot unknown application behaviours.)
  • Recommendation: enable Failure auditing when using Windows Firewall.

System events

  • The only semi-useful information I’ve ever found from this auditing are the startup and shutdown events, and they’re much more useful in determining uptime statistics (and otherwise unseen BSOD events) than they are for security.
  • Unfortunately, these events get buried under the amazing number of 514, 515 and 518 events that accumulate in the space of a few days.
  • Recommendation: No Auditing

Summary: Windows XP Security Event Log auditing category recommendations

Security Event Log Category

Recommended Audit Level

Account Logon Success, Failure
Account Management Success, Failure
Directory Services access No auditing
Logon events No auditing
Object Access auditing No auditing*
Policy Change No auditing*
Privilege Use auditing No auditing
Process Tracking No auditing*
System events No auditing

* except in unusual circumstances, see above.

Advanced Oddities

Per-user Auditing

  • As of Windows XP SP2, auditing can be enabled or disabled for any or all users
  • Each category can be separately configured as well
  • On a PC with many user accounts, this would be useful to help remove the less interesting entries
  • However, where few accounts exist, and for PCs not joined to a domain, per-user auditing is not advised

Windows Firewall auditing

  • As I hinted above, there are some aspects of Windows Firewall’s operations that can be logged to the Security Event Log, and which don’t get logged to the pFirewall.log.
  • For organizations using Windows Firewall, and especially those that don’t have a perfect idea of all the exceptions they need to open up on their user’s systems, this auditing can be extremely useful.
  • Recommendation: To capture this data, you should enable Policy Change (success and failure) and Process Tracking (failure) auditing on the target systems

File/Registry access auditing

  • If you’re interested in detecting attacks that tamper with system files, then EricFitz has some fascinating work you should examine
  • His work became the input for the Security Configuration Wizard in Windows Server 2003 SP1
  • Having had a quick look at it, there’s nothing that looks dangerous or unsuitable for an XP client
  • Recommendation: if you’d like a quick & dirty way to detect changes to system files, cut and paste those “file access auditing” settings from the SCW templates, and make sure that you’ve also enabled Object Access auditing (success and/or failure, depending on whether you’re after actual changes or just attempted changes)

Full Privilege Auditing

  • You can toggle a Registry setting known as (duh) FullPrivilegeAuditing, but be warned: these are default disabled for good reason
  • Recommendation: do NOT enable this setting

Audit the access of global system objects

  • Ever since this got added late in the NT4 service pack cycle, I’ve never quite figured out what this really tells me.  Eric doesn’t seem to interested in this either for most of us.
  • Recommendation: turn this setting Off

Audit the use of Backup and Restore privilege

  • This setting blows me away — it’ll fill up the most generous security event log, ’cause it creates an entry for each file that is backed up or restored
  • Recommendation: do NOT enable this setting

CrashOnAuditFail aka “Shut down system immediately if unable to log security audits”

  • Are you nuts?  Have you ever met a sysadmin that voluntarily puts in place a predictable Denial of Service attack?
  • If you’re that one-in-a-million organization that can actually implement this setting, I want to hear from you.  Yours is a tale I just gotta hear…
  • Recommendation: duh, do NOT enable this setting

For More Information…

Eric Fitzgerald is an old colleague of mine from my days at Microsoft, and I have an incredible amount of respect for the depth and persistence with which he pursued issues in the Auditing subsystem of Windows over the years.  He’s like the Rain Main of Windows security eventing, except I don’t think he’s much of a fan of Wapner. 😉  Eric’s “Windows Security Logging and Other Esoterica” blog is chock full of Windows security auditing goodness.

Windows Security Log Encyclopedia — Randy Franklin Smith’s take on Security Event Logs

Technet Events & Errors Message Center — detailed information backing up each security Event ID and what it means.

Deciphering Account Logon Events — in case you wonder what “Logon Type 5” really means…

Account Management — disabling the noise — and we’re done!

 

[Apologies to anyone monitoring my external blog, as this is a straight repost.  However, I’m assuming very few of you know about both, so I’m going to start reposting anything that’s applicable to both audiences.]

As David Hsing says: Best. Troll. Ever.

Holy crap that’s funny:

http://talkback.zdnet.com/5208-12355-0.html?forumID=1&threadID=31199&messageID=579806&start=43

Reproduced here for those (like me) too lazy to click through:

You are kidding aren’t you?  Are you saying that this linux can run on a computer without windows underneath it, at all?  As in, without a boot disk, without any drivers, and without any services?

That sounds preposterous to me.

If it were true (and I doubt it), then companies would be selling computers without a windows.  This clearly is not happening, so there must be some error in your calculations.  I hope you realise that windows is more than just Office?  It’s a whole system that runs the computer from start to finish, and that is a very difficult thing to achieve.  A lot of people don’t realise this.

Microsoft just spent $9 billion and many years to create Vista, so it does not sound reasonable that some new alternative could just snap into existence overnight like that.  It would take billions of dollars and a massive effort to achieve.  IBM tried, and spent a huge amount of money developing OS/2 but could never keep up with Windows.  Apple tried to create their own system for years, but finally gave up recently and moved to Intel and Microsoft.

It’s just not possible that a freeware like the Linux could be extended to the point where it runs the entire computer from start to finish, without using some of the more critical parts of windows.  Not possible.

I think you need to re-examine your assumptions. 

YES (for the sarcasm-impaired), this is a joke, and it’s NOT my writing.  Don’t bitch at me if you are rabidly anti-Windows — click on the link above and rant away to your heart’s content.

Debugging a Word 2003 runaway thread…but not successfully

I just experienced one of the usual “hangs” in Microsoft Word 2003 that happen pretty regularly when working on multiple, large documents for any significant length of time.  The WINWORD.EXE process is taking up 50% of my CPU (which as a dual-core processor, means that there’s a thread that’s somehow taking up 100% of the logical CPU for which it’s scheduled), and has been doing this for at least ten minutes now with no letup.

In my experience, these “runaway consumers of CPU cycles” just never quiesce — eventually I have to decide to kill WINWORD.EXE from Task Manager or Process Explorer, or else the offending process will consume that “CPU” from now until the end of time.

Maybe I was just bored today, ’cause rather than just kill the runaway process, I decided to see if I could dig a little deeper.  [I think Mark Russinovich has infected me with the idea that these are surmountable problems — though I wouldn’t dream of trying to make a favourable comparison between my haphazard hacking and Mark’s mad skillz.]

Process Explorer

Let’s have a look at a few screenshots, shall we?

image 
(Performance stats, in case that’s useful to anyone — though it doesn’t provide me any telling evidence)

image
(Listing of the threads currently instantiated in WINWORD.EXE including the main thread, which is the one causing all the problems)

image
(Stack contents for the WINWORD.EXE thread)

image
(Stack contents for GdiPlus.DLL thread, which was the only other thread with any activity under the “CSwitch Delta” heading)

Process Monitor

Once I decided to investigate, I fired up Process Monitor and limited it to WINWORD.EXE.  The activity logged is almost entirely like this:

image

Don’t strain your eyes too badly on this — I’ve included this just to note the incessant nature of the major activity here: a rapidly-repeating WriteFile operation on a single Temporary file (~WRS1954.tmp), interrupted once in a while by a smaller (Length of anywhere between 512 and 3072) ReadFile operation on the same file:

image

Interestingly, these ReadFile operations occur in an irregular but repeating pattern:

image

Also of note is the fact that this temporary file is constantly growing in size, and not just temporarily swelling the data stored within a pre-allocated file — I confirmed that by right-clicking on the Path in Process Monitor, chose “Jump to Location…” and simply Refreshed on the folder to observe the reported file Size was incrementing every time (over a span of 50 minutes, it grew by approx. 222 Kb, or 233657856 bytes).

If I look closer at the Handles for WINWORD.EXE, I notice that this is one of many Temporary files open by Word, which implies that the problem we’re experiencing is very specific to one type of unexpected activity (and not just affecting Word’s handling of Temporary files):
image
(Note: I intentionally “hashed” out the original filename, which is the last entry in the list pictured.)

One other piece of information: I tried to resize the Window in which the active document was being displayed.  Word appended “(Not Responding)” to its Title Bar, and that seems to have changed the behaviour profile of the WINWORD.EXE thread.  Since that point in time, Process Monitor did not record any further increase in the size of the ~WRS1954.tmp file, but recorded one additional ReadFile operation on the WINWORD.EXE file itself (Offset: 3998720, Length: 4096).  [WINWORD.EXE File version = 11.0.8169.0, Digital signature timestamp = May 31, 2007 12:38:03 PM]

Finally, I grabbed a full memory dump of the WINWORD.EXE process, using windbg.exe and the .dump /ma command.  I can’t say I know much about debugging a dump file, but I’ve got it on the off-chance that I ever find a good guide to debugging.

What Caused This?

Three circumstances I think contributed to this, though in my opinion none of them should lead to hung process (since I’ve done this more often without incident):

  1. I had opened a Word 2003 document directly from Outlook (it was attached to an email).
  2. The document had Track Changes enabled, and I’d already added Comments throughout the document.
  3. In the Comment I was just editing, it had scrolled off screen…
    image
    …and I had just attempted to apply formatting (I’d typed [Ctrl]-B and [Ctrl]-I rapidly,to bold and italicize) to a single word in the Track Changes panel below the document (the one that opens automatically when you keep typing in Comments that have already “scrolled off screen”).
     image
    (Note: I intentionally redacted the confidential text — but it sure ain’t artistic)

Caveat: While my experience with Word over the years has taught me that heavy use and abuse of the Comments feature leads to instability, I’m still miffed that I’d lose the recent batch of edits just because I’d foolishly tried to emphasize my point using basic formatting in a Comment.

So What Can We Conclude So Far?

I don’t know much about reading a stack trace, so this is all guesstimation on my part (plus a little intelligence gathered from a good Russinovich article).  The WINWORD stack indicates that Word has called ntkrnlpa.exe aka the Windows kernel.  It looks like it’s basically stalled (KiDispatchInterrupt) while creating a new thread (KiThreadStartup).  Looking lower in the stack, the first caller in WINWORD is labelled only “0x1a772b” — whatever that is, it’s beyond my skills to unearth the identity of that API.

The next one down in the stack, however, is wdGetApplicationObject().  There’s no information in MSDN that references this function, though a few pages on the ‘net do allude to it (mostly in the same kinds of searches I made).  The best info I could find was here, which I’m guessing is Word’s way of getting a handle to the overall Word “application object”.  However, without any further context, it’s very hard to imagine what is really going on here.

Turning to the GdiPlus stack, it looks like another kernel call that’s stalled (many similar references to “WaitForMultipleObjects” functions), all boiling down to a call to the GdipCreateSolidFill() API.  From what MSDN documents, this seems like a pretty innocuous function, having nothing to do with temporary files, only to do with UI.  I can understand this — by the time I’d looked at the GdiPlus stack, I believe the UI had “hung” (aka it was non-responsive).  So while this thread was also active, it’s almost impossible for it to be involved in this issue.

Then the only thing I know for sure is the temp file was growing due to some runaway operation, and the runaway operation (which was probably related to an attempt to format Comment text) at some point obtained a handle to the Word application object.

I’m guessing that the only way to get any closer to the root cause would be to dig into the memory dump.  And…bugger me, the dump I grabbed ended up with this as its STACK_TEXT (from !analyze -v):

0adaffc8 7c9507a8 00000005 00000004 00000001 ntdll!DbgBreakPoint
0adafff4 00000000 00000000 00000000 00000000 ntdll!DbgUiRemoteBreakin+0x2d

Guess that’s “the wall” for me.

"Go/No-Go" Decisions on MyPicasaPictures, Attensa Sync to Google Reader, W2MW++

I’ve done a lot of investigatory work in the last few lunar cycles of different development projects I’d dreamed up.  However, after the investigation and the internal decision making was completed, I didn’t do a good job of “closing the loop” with any of you who have wondered “what happened all those projects?”.

I haven’t thought much about the royal “you” in this work — I’ve been sharing the steps and findings, but recently I started to wonder what people would think in the future if they happened to search on something that led them to one of these projects’ articles.  I’d feel pretty frustrated trying to find out where these things led (if anywhere) and where (if anywhere) there might be code that came out of these efforts.

Well then, it’s time to close the loop on these — at least, as much as I am “decided” on any of these so far.  That said, I’m never committed to any particular decision like this if any new evidence surfaces in the future to challenge my assumptions.  So if anyone is interested in picking up where I left off on any of this, drop me a line to let me know (I’m always interested in this kind of experimental work), and if you’d like to bounce some ideas off me, or see if I’d be interested in participating, I’ll always be open to such inquiries.

MyPicasaPictures: No-Go

Bottom line: while the effort to understand the VMC development environment was instructional and probably honed my ability to figure out what to look for in future explorations, my overall impression of MCML is that it’s just too damned hard for amount of value I might derive from it.

That, plus the chronic and unresolved stability issues I’m seeing with Vista Media Center (exacerbated by the merciless complaints and teasing I receive from my wife, who keeps saying “The XP box was much more stable, wasn’t it?”) have pretty much convinced me to pave the box, downgrade to Windows XP and to give Beyond TV a try.  [Their SDKs and more open, flexible architecture look like the perfect place to invest .NET development efforts, and the customer satisfaction with Beyond TV seems far superior to Windows Media Center, at least based on my initial research.]

Attensa Sync to Google Reader: No-Go

I had already decided to move from Attensa for Outlook to NewsGator Inbox, and then a few weeks ago NewsGator announced that their previously $30 Outlook client would henceforth be available for FREE to any and all concerned.

While there was no conversion possible from Attensa to NewsGator (well, I could import the OPML, but I couldn’t sync the “read/unread” status of all my articles, nor transparently migrate old articles to the new folder structure), everything else about this has been a positive experience.  I’m totally addicted to the NewsGator Mobile Reader for iPhone, and the fact that it syncs with my Outlook “read/unread” status is just awesome.  Congrats, NewsGator!

Attensa, I wish you luck in trying to survive the competitive pressures from NewsGator.  If I didn’t know better, I’d guess this is the beginning of the decline for Attensa, even though I think their Outlook client is superior to the current NewsGator Inbox offering.

W2MW++: Undecided

When I first read about the “export to MediaWiki” capability in OpenOffice Writer 2.3, I quickly concluded that any work I or the rest of the community had done for an Office add-in would become a moot point.  [Amusing but not-entirely-inaccurate Spoonerism: my wife knew a guy who insisted that the term was “a mute point”.]

However, after using Writer 2.3 to convert a few relatively simple Word 2003 documents to MediaWiki format, I realize that they still have a long way to go to preserve real fidelity of layout and formatting in Word documents.  I have faith that they’ll get there, and that eventually Writer’s integrated engine will become the translation engine for .DOC & .DOCX, but I now feel like there’s a significant unmet need that the work I’ve invested so far in W2MW++ could still address, and that that unmet need will exist for quite a while yet.

That said, there’s one thing that’s been bugging me for a few months now: the name.  WordToMediaWikiPlusPlus is a clever extension of the Word2MediaWikiPlus project, and it makes obvious the heritage of W2MW++, but it makes it sound like the project is more “hardcore” than it really is.  If I had my druthers, I’d rename the project “Word2MediaWiki.NET” (W2MW.NET), to make it clearer that the project is based in .NET code, not C++.  I’d hate to think anyone would be disappointed by the fact that it’s written in one of these “shiny new” languages — there’s something more “honest” or “obvious” about using the “.NET” suffix instead.

Now all I have to do is figure out how to Rename all the dozens of “++” references throughout the project AND figure out how to get a CodePlex project renamed.  [THAT should be fun :)]

MindManager 7 "ToDo List" Add-in development Part 2: Adventures in Add-in Installation

MindManager 7 provides the ability (through the MindManager options menu) to inspect and enable/disable already-installed add-ins.  However, it’s not clear from the UI nor Help file how to install an add-in for MindManager.  The DevZone article indicates that once I’ve built the assembly it should be installed in MM7 automatically, but I’ve built it many times and it definitely doesn’t show up in the listed add-ins in MindManager:

If the code compiled successfully, your add-in DLL was created and registered with MindManager. At this point, you are ready to test your new add-in.

I’d posted a couple of requests to the MM7 developer user forum and that’ll probably give me some clues, but in the meantime I happened to find this blog article (Creating a MindManager 7 Add-in Sample) from last summer, and spotted this gem:

“Probably the most useful thing the wizard does is create a Setup project that carries the Windows Registry settings needed to let the MindManager application locate the Add-in component at load-time.  These settings are used by MindManager to discover and load selected Add-in components.  If they are wrong, your Add-in never makes  it onto the available Add-ins list.”

[That sharp sound you heard was my hand hitting my forehead]  Duh, indeed.

Registry Settings Are the “Key”

It appears that the critical piece of info I hadn’t found in the documentation (MM7 Help file, DevZone walkthrough) was the existence of the Registry Key HKLM\Software\Mindjet\MindManager\7\Addins\.  The add-in downloadable from the “Sample” blog article creates the following in that Addins key:

  • Key = MmxSample.Connect [i.e. the ProgID for the add-in]
    • Value: FriendlyName (REG_SZ) = Pandimonium[sic] Productions Mmx Sample Add-in
    • Value: LoadBehavior (REG_DWORD) = 2
    • Value: Description (REG_SZ) = A sample MindManager Add-In to dump map contents

As well (though I wonder if this is optional — at least while developing the add-in), the Setup project creates the following entries under HKCR (HKEY_Classes_Root):

  • Key = MmxSample.Connect
    • Key = CLSID
      • Value: (Default) (REG_SZ) = {925b5786-bf6f-4ac5-9df1-61ee50a815ca}
    • Value: (Default) (REG_SZ) = MmxSample.Connect

Since these Registry values are static, it appears that MindManager enumerates the keys under \Addins at each startup.  Therefore, I believe that just building the add-in assembly does not magically make MindManager aware of the add-in you’re developing.

So perhaps I can just populate my Registry settings by hand?  The AddInSetupen.vdproj file for my add-in’s setup project intends to set these values:

  • [\Addins] Key = ParanoidMike.ToDoList.AddIn.1
    • Value: FriendlyName (REG_SZ) = MM7TODOList
    • Value: LoadBehavior (REG_DWORD) = 2
    • Value: Description (REG_SZ) = MM7TODOList|Built by ParanoidMike|Version 1.0.0

Grrr

Oh hell.  I just went back to the DevZone walkthrough article, and the next thing (just beyond the point at which I abandoned the walkthrough) is this page that documents exactly the Registry settings I just unearthed.  Man, this is truly time to let it go for the evening…

One Open Question

My project’s Setup does not currently populate any HKCR settings!  Is this the cause of the “unrecoverable error” when building the Setup project?

MindManager developer resources

These are the various sources of information I’ve stumbled across so far that are useful for me (a budding MindManager add-in developer):

Resources related to Custom Properties

I anticipate leveraging custom Properties in my add-in, so I’ll want to dig into these articles when I get to that point:

If you can’t pronounce it, you shouldn’t get to make policy on it

It amazes me that one of the most powerful people in the world (a Yale
“graduate”, though that just proves how little that must mean these
days) still hasn't learned how to pronounce “nuclear”.

I can understand that science can be a hard subject, and god knows
that man displays surprising lack of intellectual horsepower, but on
this my opinion is unwavering: if you can't even spend the time to
learn how the word is pronounced, you couldn't possibly convince me
that you're even listening to the “elevator pitch” summaries of the
key issues, let alone sat down and really weighed the difficult
questions around nuclear power.

So ParanoidMike's Rule of Power power is simple: if you can't
pronounce it, you don't get to create or influence policy on it. A
retarded chimp shouldn't have their hand anywhere NEAR the button.

Developing a MindManager Add-in for Staying On Top of my ToDo Lists

I’ve made a few attempts at staying “on top of” my workload using tools like the Getting Things Done add-in for Outlook, MindManager, and even tried the ResultsManager add-in for MindManager. Each of them help, but somehow they all seemed a bit too “high maintenance” for my needs — they required a great deal of management of metadata about each project and task, and yet I always found it hard to get a simple “to do list” summary of stuff I need to do.

It wasn’t that I couldn’t get some subset list or grouping of my tasks. I just couldn’t quite make it work for me in a way that made it easy to see what I really needed to work on.

My Woes with the Commercial Alternatives

With the GTD tool, I could see my tasks grouped by Project or by “context” (a GTD-ism for “if I’m near a phone, I should knock off all my calls; if I’m by my computer, I should knock off a bunch of computer-needing tasks all at once”). However, while I was really good about collecting all my tasks, I wasn’t so good about understanding which of them was most urgent — it all just became one big pile and I could never get a “meta-view”. I also could never get the hang of using the Prioritization field that should’ve allowed me to order & re-order all the tasks without regard for their project/context grouping.

Ages ago I’d even tried Taskline, which adds even more metadata to the Tasks in Outlook, but even with the combination of Taskline and GTD, I wasn’t able to make any more sense out of the 200+ tasks that I’d be able to collect, each time I gave these things a try.

With MindManager, I’m able to pull together a random set of ideas, tasks, steps, requirements and issues, and re-group them in ways that make sense once I’ve got them all in the same “place”. However, while it has some integration with Outlook, and I should be able to sync Tasks bidirectionally, I can’t say I’ve ever committed to the notion of marrying the incredible number of Tasks I’ve already got in Outlook to the scattered (and possibly overlapping or conflicting) musings I’ve got in MindManager.

When I added ResultsManager to MindManager, I was blown away by the UI, the great number of useful metadata I could assign to my “project planning” items (though such efforts on my part are a great insult to those skilled/sick individuals who actually know how to manage projects), and the really well-thought-out introduction process they used to familiarize customers and get them up and running quickly. However, I found that once I got all my projects, deliverables and tasks into the environment, I was still struggling to (a) find a ResultsManager template that would give me that “holy crap” daily/weekly view of my critical tasks, and (b) prioritize all my tasks relative to each other when they’re gathered together in one mind map. I’ve even tried discussing this with some of their technical evangelist types, but for all the work they did in trying to explain how to customize the ResultsManager environment, something about it didn’t click for me.

I really like the concepts behind ResultsManager — tagging items that are in multiple maps and gathering them into one “meta-map”, organizing projects into sub-deliverables and tasks, using icons and other visual elements to help annotate the information. I liked the flexibility in the design, and the implicit promise that it’ll help you see the patterns and overall workflow.

However, it doesn’t quite live up to that — at least not for me, with only a moderate amount of time invested in the training they provide for newbies (and poking around their forums and discussions). And frankly, I didn’t like what I saw when I looked under the hood — it’s all written in VBA, and becomes a real hog at any sort of scale. They’re interested in developing in .NET (or VSTA?), but between that and the effort to simplify the usability, I can’t imagine it would be really ready in time to keep me from getting fired. (I’m kidding, mostly.)

Build My Own MindManager add-in

So I’ve decided to explore the effort it would take to do something similar, but aimed at one single goal: produce a ToDo List from the task items scattered throughout my MindManager maps, and be able to prioritize (i.e. re-order) them in a persistent manner.

I know that Mindjet has produced some resources for developers who wish to add functionality to MindManager:

  • a Visual Studio template for C#/VB development
  • a Primary Interop Assembly (PIA) that installs by default with MindManager Pro 7
  • a free community portal where documentation and resources are available for registered developers

Once I downloaded the VS template, installed it, and created a new project from it, I was surprised at how many different files were generated by the wizard: there’s AssemblyInfo.cs, Connect.cs and Utility.cs in the Addin project, then a Common project and an AddinSetup_en project. This made me think there’s probably a tour of the different components in the MindManager add-in project somewhere on the Mindjet developer site, and that I’d probably earn a few shortcuts in my development time if I read up on this first.

Browse over to the Mindjet Devzone. That’s where folks like me (as well as professional development organizations) can get at the really cool developer resources. Once you’re registered, you’ll be able to access resources aimed at MindManager version 6 or version 7 such as “How to Create a MindManager 7 Add-in Using C#” and the “MindManager 7 Object Model Reference“. They even provide a downloadable archive of all their online documentation if you’d rather just dig through the info without having to login each time.

Now, it’s not well-documented where a guy like me should start, but it’s a pretty good guess that “How to Create a MM7 Add-in using C#” is a likely walkthrough for newbie developers. And as it turns out, this is definitely targeted at a C# developer who’s just starting into MindManager development.

You will need to read the guidance with a grain of salt, however; there’s a lot of steps specified in the first few sections that don’t apply if you’re using Visual Studio 2005 + the MM7 addin template (i.e. MM7AddInTemplateSetup2005.msi found in Mm7AddInTemplateSetup.zip).

[Also note: if you’ve got the same setup that I happen to have — which is to say, Visual Studio 2005 and Visual Studio 2008 installed side-by-side — then you’ll probably have to create your MM7 add-in project in VS2005 and then open it in VS2008. I couldn’t find a way to install the MM7 add-in template so that it showed up in the VS2008 “New Project” selection, but that’s probably because I haven’t uninstalled VS2005 yet.]

Brewing Problem

I don’t know why, but I decided to try building the Solution before I spent too much time writing code. It turns out that there are three errors with this Solution, and I don’t think the minor changes I’ve made could possibly have caused all this damage:

General failure building custom actions C:\personal\VS Projects\MM7TODOList\MM7TODOList\Common\Common.vdproj (Project=)Common

Unrecoverable build error C:\personal\VS Projects\MM7TODOList\MM7TODOList\Common\Common.vdproj (Project=)Common

Unable to import merge module ‘C:\personal\VS Projects\MM7TODOList\MM7TODOList\Common\Debug\Common.msm’ C:\personal\VS Projects\MM7TODOList\MM7TODOList\AddInSetUp\AddInSetupen.vdproj (Project=)AddInSetup_en

I figure I better get these problems resolved before too long, or else I won’t be able to debug this project and even bigger issues will go unnoticed. I’ve posted this issue to the MindManager developer forum, and I hope it gets answered soon. 🙂

Update: For the benefit of everyone who’s waited with baited breath…

Well, even if you just want to know how to deal with this, here’s what Mindjet Developer Support told me:

“The solution on the DevZone is based of VS 2005 that’s why (I am assuming) that you could not get it to compile on VS2008. I have modified your project a little bit (removed custom actions) and it is working fine.”

Couple of Open Questions

  1. What’s the difference between adding a Reference in the References section of the Solution Explorer, and adding the “using CLASSNAME” statement in each source file?
  2. If I wanted to rename a namespace after I created the project, can I just right-click on the name of the namespace (e.g. MM7TODOList) and choose Rename? Or do I need to find other dependent code fragments that don’t get updated automatically?

Certificate enrollment in .NET managed code: a primer on gathering the right tools

[y’know, I always thought that was pronounced “pr(eye)mer”, not “pr(imm)er”…]

So here I am with Visual Studio 2008 and .NET Framework 3.5, and I can’t for the life of me find a managed class that would submit an enrollment request to a Windows Certificate Server.  I know that the System.Security namespace has had a bunch of classes available (e.g. .Cryptography.Pkcs, .Cryptography.X509Certificates) that assist in the digital certificates arena.  However, there’s nothing in the framework (at least through v3.5) that appears to map in any way to the functionality in XENROLL (the Win32 container for certificate enrollment, which included COM interfaces) or CERTENROLL (the same control renamed in Windows Vista).

The only way I knew so far to take advantage of Win32 functionality in .NET was to use p/invoke to map/marshal the unmanaged call with a .NET “wrapper”.  However, when I went looking on pinvoke.net for anything mentioning XENROLL or CERTENROLL, I came up snake eyes.

The clue that finally broke the mystery wide open for me was this article (“XENROLLLib reference for C# and VB.NET”), that seemed to indicate there was some way of getting a set of classes that exposed the XENROLL functionality.  I tried pasting some of the example code into a new Visual Studio project but that didn’t work, and when I searched the Object Browser for any default classes that contained XENROLL, XENROLLLib, CENROLL or other terms that looked like they would be base classes, I still didn’t succeed.

I don’t recall how anymore, but somewhere I connected a few dots between that article and “adding a reference” to the COM object, and then it clicked!  Damn, it seems so obvious once you know what you were supposed to do.  All I had to do was look in the Solution Explorer view, right-click on References, choose “Add Reference…”, choose the COM tab, and select the Component name “xenroll 1.0 Type Library”.

Oh, that’s right, now I remember: there was some discussion about XENROLL being a COM object, and other discussions that helped me piece together various ways to “wrap” a COM object for use by managed code.

Your best bet would be to find the Primary Interop Assembly (PIA) — i.e. the “official” RCW for the COM object in which you’re interested.  [Unfortunately, the developers of XENROLL have so far refused to acknowledge any need for a PIA for XENROLL.]

Another option would be to build an interop assembly to wrap the COM object, which requires some degree of hand-coding, but not as bad as writing the p/invoke signatures around each and every function exposed by that COM object.

However, the easiest of the “do-it-yourself” options is by adding a Reference to the COM object, and letting Visual Studio “magically”, automatically create the interop assembly (aka/or RCW) that’s needed to access the functions.

It turns out that the XENROLLLib article I’d found was really just documenting what was exposed automatically by Visual Studio when you add the Reference to “xenroll 1.0 Type Library”, but that wasn’t obvious to me (and may not be obvious to most folks who happened to stumble on the article).

Tip: the IC* interfaces are COM (scripting) oriented, and the I* interfaces are C++ oriented.  Thus, any manual work to “wrap” the native cert enrollment code in .NET interop assemblies should probably focus on IEnroll4 (which inherits from IEnroll2 and IEnroll), rather than ICEnroll4 and its predecessors.

So if I’m going to add COM references in my code to create a Cert enrollment assembly, do I just need to reference XENROLLib?  Apparently not — this discussion indicates that I’ll also need a reference “CERTCLIENTLib” to kick off the actual submission of the Certificate enrollment request to the Windows CA’s web interface.

And which COM reference will this require then?  A quick Google search on CERTCLIENTLib.CCertRequest should give me a lead pretty quick.  And bingo!  The second link is to this article, which mentions “…code below that uses the CertCli library get the certificate from the CA”, and this corresponds in Visual Studio’s “Add Reference” COM tab to “CertCli 1.0 Type Library”.  Now I’m getting the hang of this!

One open question: how do I go about actually using the Interfaces vs. the Class implementations such as CEnroll or CEnrollClass?

Summary of Findings

So there we go: to write a certificate enrollment client in C# requires a whole lot of COM interop, using COM References to “xenroll 1.0 Type Library” and “CertCli 1.0 Type Library”.  That, plus leaning heavily on samples from others who’ve gone down this path before (like here and here), should enable a pretty reusable .NET certificate enrollment library.  [Now if only Microsoft’s CERTENROLL team would add “releasing a CERTENROLL PIA” to their development schedule.]

Additional References

These will be useful at least for myself, even if they’re not useful to anyone else.

MSDN: Mapping XENROLL functions to CERTENROLL

MSDN: implementation of initializing a certificate request using a cert template (including C# code in Community section)

some native code & discussion of using IEnroll “class” (though I don’t know if the concept is known as a “class” in Win32)

An MSDN newsgroup article on requesting a certificate in managed code

Converting from Microsoft Money to Quicken — finally, a documented solution!

After years of fighting and losing the battle to use Microsoft Money to stay on top of my finances, and after reading that Microsoft Money has only 1/4 of the market share that Quicken has (even after all these years of Microsoft trying to take over), I finally gave in (with a really sweet $33 deal via Costco.com) to sense and decided to switch my financial management to Quicken.

Unfortunately, as much as I would’ve figured that Quicken would want to make it dead-easy to convert MS Money data to the Quicken format, it turns out that not only is their conversion tool buggy and not well documented, but the conversion process is pretty damned fragile (and requires a lossy and manual process of exporting into an XML format).

I spent much of this weekend fighting with this software, troubleshooting all the various errors (mostly using Process Monitor — the best friend of anyone fighting with crappy, cryptic software) and finally came up with a solution that is (a) successful (unlike every report I’ve been able to find on the Internet) and (b) repeatable.

This is my gift to you, the many who have wisely determined that their foolish experiments with Microsoft’s finance software are best left behind.  If you’d like to hear the whole gory story, just keep reading.  If you’d prefer just the step-by-step recipe, just skip to the end of the article and enjoy!

First Error

CreateQWPAManager could not be found in qwutil.dll

I dug around Google for a while, which was not encouraging (it sounds like not one customer had ever found a tech support rep at Intuit that had any clue what this error message really means).

However, to confirm my suspicions I fired up DEPENDS.EXE (no, not an adult undergarment utility) and confirmed that the version of QWUTIL.DLL that ships with Quicken Deluxe 2007 does not include the CreateQWPAManager() API.

I tried to find a more up-to-date version of this file that I would’ve expected Intuit to make available for users of the Data Converter utility, but so far they have nothing there.  So I fired up my favourite torrent utility and “borrowed” a copy of Quicken 2008 Home & Business (which at the time was the only version of Quicken 2008 that was being “shared”).

In the DISK1 folder of the CD image there’s a file called DATA1.CAB.  Opening that up with Winzip, I was able to extract a copy of QWUTIL.DLL.

I then renamed the Quicken 2007 version, copied the Quicken 2008 version to the C:\Program Files\Quicken folder, and confirmed with DEPENDS.EXE that this 2008 version of QWUTIL.DLL indeed does include the CreateQWPAManager() API.

[Now, because the Data Converter utility loads QWUTIL.DLL directly from the Quicken program directory, it isn’t possible to just copy the QWUTIL.DLL into the C:\Program Files\Data Converter folder (which is what would normally work with most Windows apps).  Instead we have to “replace” the old file with the new one in the same location (and then restore the old file once we’re done).]

Second Error

The data converter can not find the Microsoft Money Account Transactions*.xml report.
Try re-creating the Account Transactions*.xml report.

I fired up Process Monitor, and spotted the MNY2QDF.EXE process failing to QueryDirectory for C:\Documents and Settings\mikesl\Desktop\Investment Transactions*.xml and :\Documents and Settings\mikesl\Desktop\Account Transactions*.xml.

So after a bit of head-scratching, I renamed the report XML files to “Investment Transactions.xml” and “Account Transactions.xml”.

Third Error

The data converter does not recognize the report as a Microsoft Money Account Transactions report.
This could be because the report was renamed or because it is not the correct report.

Edited the contents of the element in the XML file(s) to replace the unexpected filename (e.g. “Quicken export”) with the required filename (without the .xml suffix):

Filename

XML Tag

Investment Transactions.xml Investment Transactions
Account Transactions.xml Account Transactions

Note that this error can be caused by problems with either the Account Transactions or the Investment Transactions report.

Fourth Error

The Microsoft Money Investment Transactions report must include certain fields.
Make sure that the Investment Transactions report includes the Account, Date, Investment, Activity, Shares, Price and Amount fields, and create it again.

I temporarily renamed the “Investment Transactions.xml” file and Data Converter was able to complete its work on Account Transactions.xml”.

<Edit> A little more detail… This error message was caused by the simple fact that I didn’t include all of the fields it mentions here.  At first I was confused by this error because one of the many guides on the Quicken site spelled out exactly which checkboxes to include, and (I checked afterwards) it definitely missed one of the fields, which I dutifully did not check.  Later, once I re-ran the report with all the fields included, the data converter successfully converted the Investment Transactions report as expected.

(koty, a reader, asked me to clarify what I meant by “temporarily renamed” — it probably would’ve been less confusing if I’d said I temporarily removed the file so that the data converter would only focus on the Account Transactions file.) </Edit>

Fifth Error

The converter tried to launch Quicken 2007 automatically once it completed the conversion, but Quicken 2007 immediately stops when the 2008 QWUTIL.DLL is present.

While I’d hoped that Quicken 2007 could operate properly with the 2008 version of this file, I had to remove the 2008 version and replace it with the 2007 version of QWUTIL.DLL.

Then I had to locate where the converter had dumped the converted Accounts data.  I’d assumed it would copy the results into the currently-configured Quicken data file (the one I’d created when I figured launched Quicken 2007), but that was still empty.   It turns out that, even though ‘d made a point of storing the Quicken Data file that I’d created originally in a non-default location, the converter didn’t find that file, nor try to put its conversion results in the same folder.  Instead, it created a file QDATAMNY.QDF in My Documents\Quicken.

Sixth Error

When I asked Quicken 2007 Deluxe to open the QDATAMNY.QDF file, it gave me this warning:

Important
You are currently using Quicken 2007 Deluxe.
The current data file was last used with Quicken Home & Business.
To add the additional features of Quicken 2007 Home & Business again, click Unlock Again.

I chose Unlock Later.

This is the result of me temporarily “borrowing” the only Quicken 2008 version I could get my hands on, and just manually swapping the QWUTIL.DLL files back & forth depending on what I needed.  [Hopefully this doesn’t cause any long-term compatibility issues with the converted data.]

Once I switched back to the original version of QWUTIL.DLL, Quicken started up fine, and was able to open the QDATAMNY.QDF file that the Data Converter had just created.

Conclusions

  1. Intuit should be more forgiving when seeking the named reports on the Desktop — it’s hard-coded to look for the default names of those reports, and while that would work in most cases, I was one of those crazies that renamed the reports (in the “Title” field of the Customize Report UI).  Without any documentation that the Data Converter only looks for the default Report names, it was not at all easy for me to figure out the source of the Second Error.
  2. Intuit needs to clearly test and document the dependencies for the Data Converter and ensure that anyone who downloads the Data Converter can use it in the proscribed environment.  Currently, the version of the Data Converter that is available on from Intuit only works with the 2008 version of QWUTIL.DLL.
  3. Intuit needs to ensure that what the Data Converter requires from the MS Money Reports is what’s documented in their Help files.  For example, in this page‘s Step 4, #3, they fail to include the Account field.
  4. Intuit should be more forgiving about the naming of the MS Money Reports that it’s trying to convert.  There’s no good reason to both look for hard-coded names for the files and require the XML element inside the file be exactly the same as the file’s filename.
  5. MS Money is not required to be installed on the same computer where the Data Converter is run (Process Monitor watched MNY2QDF.EXE during startup and during the conversion, and never did I see Data Converter try to find, open or use any of the Money files or Registry settings).  However, you do have to have a copy of MS Money so you can create the specified Reports, and you need to get the reports onto the Desktop of the user running the Data Converter.

Bottom Line: Recipe for Converting MS Money transactions data to Quicken

  1. Start with the instructions here, and whenever I haven’t specified something here, do whatever the Quicken help says.
  2. Install your version of Quicken on your current computer.
  3. Download the Microsoft Money to Quicken Data Converter and install it on the same computer.
  4. Get a copy of QWUTIL.DLL from any Quicken 2008 edition (if you can’t find one elsewhere, you should be able to find a Quicken 2008 Home & Business version here).
  5. Rename the installed Quicken’s QWUTIL.DLL to QWUTIL.DLL.ORIGINAL (by default, it’s found under C:\Program Files\Quicken\qwutil.dll).
  6. Copy the 2008 version of QWUTIL.DLL to the folder where you renamed the original one (e.g. copy it to C:\Program Files\Quicken).
  7. Follow the instructions for creating the Account Transactions Report and Investment Transactions Report (e.g. Step 3 and Step 4 from the online Help).  Ensure you preserve the default Title of each report.  If the XML file(s) on the Desktop are not named Account Transactions.xml and/or Investment Transactions.xml, then rename the resulting XML file(s) found on your Desktop to Account Transactions.xml and/or Investment Transactions.xml and edit these files’ XML to match the settings in the table above.
  8. Click the “Import Into Quicken” button in Data Converter.  You’ll eventually see a flash of the Quicken splash screen, then you’ll notice that neither the Data Converter nor Quicken will not be running.
  9. Delete the 2008 version of QWUTIL.DLL from the Quicken folder, and rename QWUTIL.DLL.ORIGINAL back to qwutil.dll.
  10. Launch Quicken, open the My Documents\Quicken\QDATAMNY.QDF file and party on with your old MS Money data!  [Oh, and I believe you can safely ignore any warning about the Quicken data file having been opened last time with a version of Quicken you don’t have installed; that’s a one-time warning that is the result of this workaround.]