Microsoft Visual Studio Tools window does not open

Patrick Roth - Click for blog homepageThis week an ISV logged a support incident to determine why their Visual Studio Tools for Microsoft Dynamics GP (VSTools) form wouldn't open.  The customization worked fine on the developer's machine (of course) but didn't work when deploying it to the customer site.

The ISV was using the Menus for Visual Studio Tools for Microsoft Dynamics GP application to display a menu for their .NET VSTools form.  The menu displayed correctly but when the item was selected, the window didn't open.  No error messages, just nothing.  I received the assembly from the ISV and found I could repro the issue here as well.

I had an idea of the issue but the first step is to run a Script.log to determine if anything is going wrong on the Dexterity side of the Menus for Visual Studio Tools application.

Script.log Result

 1 'VSTM_Command_Form_COMMAND_Command00 on form VSTM_Command_Form'
2    'Process() of form VSTM_Command_Form', 0, 0
3        'VSTM_Command_Form_COMMAND_Command01 on form VSTM_Command_Form', 0
4        'API CmdID_CHG on form VSTM_Command_Form'
5        '[0]'
6            'Callback()', 0

The Script.log is above from my own test is above.  I added the line numbers for clarification.

Looking at the Script.log, I could tell that everything seemed to be working correctly.  The only that that we don't know and cannot tell is what the Tag for this command is.  So there is a possibility there is an issue with returning the correct tag.  However this is a GP menu and there are no known issues with commands in the core dictionary.

What is the code above doing and why do I suspect that all is OK?

The explanation for the Script.log lines are below.

  1. This is you clicking on the menu item and the Dexterity command being invoked. It is the "Command00" (number 0) item by name. So this was the first menus for VSTools item registered. Probably the only one that exists on the system if you only have the one window.
     

  2. Shows the command calling the Process() function and passes in the command selected (the numeric value; 0-99). Since this is a function the first param is the return value (which we don't see because Script.log is "in" only) and the number of the command which was 0. So far so good.
     

  3. Had me stumped for bit is that seems a different command that was selected. But it isn't. The Process() function has likely has pass through sanScript in it which Dexterity assigns temp resids to compile the pass through sanScript and they sometimes match up with real ones which show in the Script.log as something else. That is what #3 is -the pass through.  And we know that for sure because we see 1 parameter passed to it (the 0) and a command cannot have parameters. Since there wasn't a crash, we know that didn't really happen and it was a method call
     

  4. This the "run script" on the CmdID field that your VSTools event triggers on. In the dex code, nothing is happening as there isn't any code on that field
     

  5. This is your VSTools code calling the Callback function to get the current tag.  VSTools events that access a field, run a field script, or execute a procedure show as [0] in the Script.log.

    Tag = MenusForVisualStudioTools.Functions.Callback.Invoke();
     

  6. Lastly, this is the Callback function itself running.

From here, there are 2 reasons I can think of that would cause your .NET form to not open.

  1. The tag returned isn't the one that you received on registration.  While possible, I find this unlikely to be the issue.
  2. Your code is opening your form however it is causing an exception which Dexterity/Dynamics does not display.

I'm going with #2 on this one, but how to prove it?

Two ways that I can think of.

  1. Load Visual Studio or Windbg and your source code on the machine.  Attach to the Dynamics.exe process and set a breakpoint in your code and step through your code.  You should see that a first chance exception happened.  Apart from the licensing aspect of installing VS2008 on the customer machine (full version as the Express version cannot attach to process), you have to deploy source etc.  So we went with the 2nd option.
  2. Recode your application slightly to trap and display the exception.

Code ISV had to open the form

DynamicsGPForm1 f = new DynamicsGPForm1();
f.Show();

Because I was sure that the form was throwing an unhandled exception which was caught silently by Dexterity, the solution is to catch and show the exception in the ISV application.

Suggested Code Change

try
{
     DynamicsGPForm1 f = new DynamicsGPForm1();
     f.Show();
}
catch (Exception fException)
{
     MessageBox.Show(fException.Message);
}

After making the change and deploying the new code, we hit pay dirt.  An exception was caught - the error was:

Can't load file
Could not load file or assembly 'Microsoft.VisualBasic.Powerpacks.Vs, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f57f11d50a3a' of one of its dependencies. The system cannot find the file specified.

Now we're getting somewhere.  We just need to install this assembly on the client machine and we should be good.

The name didn't seem familiar to me and so I did a search for the assembly.  I learned a few things in my search:

  1. The assembly is from the Visual Basic Powerpack 
  2. There are versions 2.0 and 3.0 available on MSDN for free
  3. It is installed with Visual Studio 2008 SP1.

After installing both the 2.0 and 3.0 versions on my machine, I found I still couldn't access the form.  Why not?

Well, apparently there was a "name change" in the dll.  In the public downloadable version, the name of the assembly is Microsoft.VisualBasic.Powerpacks.dll.  Note that there is no "Vs" at the end as hers was using.

From a bit more research, I found that is the version that is included with VS 2008 SP1 and you cannot download it "standalone".  The only way to get the "Vs" version installed to the client is to make an installer package that invokes the bootstrapper assembly for the package.

This form post talks about it.  I'm sure you can find more information if you search.

Because the ISV really wanted to use this component, the only solutions would be to:

  1. Create the installer to invoke the Powerpacks bootstrapper (a bit of work)
  2. Load the 3.0 version on the development machine(since the most recent).  Switch the reference to the new version.  Recompile and fix any name issues.  Then on the customer machines, just manually download and install the 3.0 Visual Basic Powerpack and your .NET addin form should open correctly.

Regards
Patrick

// Copyright © Microsoft Corporation. All Rights Reserved.

// This code released under the terms of the

// Microsoft Public License (MS-PL, https://opensource.org/licenses/ms-pl.html.)