Visual Studio – run as administrator

This is something that I generally forget whenever I create a new dev-box. Visual Studio needs to be running as Administrator otherwise you’ll get messages such as “Access to the path ‘K:\AosService\PackagesLocalDirectory\Bin\InstalledVersion.json’ is denied”:

Skærmbillede 2020-03-23 kl. 07.35.17.png

and “Visual Studio is not running as administrator. Finance and Operations (Dynamics 365) requires Visual Studio to be running as administrator. Please restart Visual Studio as administrator”:

Skærmbillede 2020-03-23 kl. 07.35.28.png

You can always right-click on your VS-shortcut and select “Run as administrator”, but if you’re even remotely like me, you’ll forget that approx 82% of the times.

So what you need to do is to modify the shortcut you’re using. In my case I modify the shortcut in my Taskbar. Right click on the shortcut for Visual Studio and instead of clicking “Run as administrator” you click Properties:

Skærmbillede 2020-03-23 kl. 09.27.35.png

In the properties window you click the Advanced button:

Skærmbillede 2020-03-23 kl. 09.29.37.png

In the window that opens up tick the “Run as administrator”:

Skærmbillede 2020-03-23 kl. 09.30.03.png

Click OK and OK and you’re done. Next time you use the shortcut it runs VS as administrator.

Enable developer mode in the MPOS without rebuilding

In the Dynamics 365 POS it’s possible to enable a developer mode that gives you some additional options like seeing the id of the strings, grid views, coloring aids and so on. To enable these features you need to rebuild the POS with the value config.isDebugMode to true in the pos.js file. That’s easy in the CPOS but requires some build/deploy in MPOS.

Our POS developer gave me a tip to shortcut that … a lot. It’s a few easy steps and they go like this:

Enable Developer mode in Windows. That’s done in settings on the box running the POS

Developer mode Windows

Start the POS and hit F12 to enable the developer aid

In the bottom of the console type in Commerce.Config.isDebugMode=true and press Enter

Set debug mode

Go to your POS settings to enable the Developer mode flag in here.

Developer mode in POS

This will make some things way easier. Notice, that when done like this it is only for the current session. Doing it in the pos.js file-way is permanent.

Running the CRT samples on AX7

The RetailSDK delivered with AX7 includes a lot of great sample code making it easier to get things rolling when learning how to customise the solution.

One of the sample projects is the CommerceRuntimeSamples. Before you are able to run it you need to do a couple of tweaks though. If not it will crash and burn with error messages that do point you in the right direction on how to fix it. This blog post is made to safe you some time and getting it fixed without having to go troubleshooting.

The first error that pops up is this one:

operatinguniterror

A configuration error in the Microsoft.Dynamics.Commerce.Runtime.dll. The reason is that it cannot find the right Operation Unit Id. It is specified in the commerceruntime.config and all you have to do is put in the operating id of the channel you would like to work with. In this case I use Houston, which has the id 039:

operating-unit

Next is this error:

storageerror

A storage exception in the same dll and same piece of code. This time we have to look in the app.config file. In here we have a list of connection strings that all point at database names as they appeared in AX 2012 Retail. In AX7 demo servers all data for all channels is in the AxDB database so the fix is to change the database names in the connection strings to AxDB:

catalog-db-name

Now you are able to run the samples and start debugging to learn.

debugactive

 

 

Make your own add-ins in the AOT context menu

When spending a lot of your working day in the AOT you end up with a lot of ideas to tools that could make your development tasks easier, help you do things faster or just automate repetitive tasks.

In this blog post I will show you how to quickly make the foundation for a new add-in. The example will create a record counter that simply returns a record count in the info log when activated from a table node in the AOT.

To do so we need 4 things:

  1. The class that does the actual work
  2. A menu item that triggers the class
  3. A reference to this menu item in the context menu
  4. Few lines of code in a standard class to make sure the menu item only shows when positioned on a table

Let us start up with the class. In this example I have a class that looks like this:

class DemoAOTTool
{
}
private void run(Args _args)
{
    TreeNode treeNode;
    // Check that we are executing from a context menu
    if (SysContextMenu::startedFrom(_args))
    {
       // Get the tree node of the context menu
       treeNode = _args.parmObject().first();
      // Check that we have a hit and that we are on a table element
       if (treeNode && treeNode.utilElement().recordType == UtilElementType::Table)
       {
          // Present the record count to the user
          info(strFmt("@SYS97212", new SysDictTable(tableName2id(treeNode.treeNodeName())).recordCount()));
       }
    }
}
public static void main(Args _args)
{
   new DemoAOTTool().run(_args);
}

That is a very simple example; but to show the concept it should do.

Next step is to create a menu item. There is no fancy stuff here. Just a plain menu item.

In the AOT find the SysContextMenu under the Menus node. This is the menu shown when you right click in the AOT and select Add-ins. Drag your new menu item to the menu to the position in the menu you prefer.

We are almost there. All we need now is to make sure that the menu item only is shown when you right click on a table. To do so find the class SysContextMenu and the method called verifyItem.

What this method does is to look at the menu item and menu item type given as parameters and return a 0 or 1 equals hide or show. The method is structured fairly simple with switches to locate the switch on menu item type matching your above created menu item and in the nested switch add the following case :

case menuitemDisplayStr(DemoAOTTool):
    // Check that we are not on an old node and only one node is selected
    if (this.selectionCount() != 1 || firstNode.AOTIsOld())
       {
          return 0;
       }
       // Check that we are on a table node
       if (!docNode && _firstType==UtilElementType::Table)
       {
          return 1;
       }
       return 0;

And now your done. Test it by right clicking on a table in the AOT, select Add-ins and your new menu item.