So i tried a HoloLens today

WP_20150430_12_29_57_Pro

Today i participated in the HoloLens Academy and it was an awesome experience.

The actual devices was guarded in a no-personal-electronics-zone so the picture above was the closest my camera came to a HoloLens.

The academy was a walk through with Unity and Visual Studio to create our own HoloLens App.

The first hologram we got to play with was a test app. A remote controlled car that we could get to drive around – Mind Blown ! This actually works !!

But this was a developer session, and we wanted our own holograms. So introducing Unity (beta):

We started by creating a simple scene in Unity, adding a few object. Then we replaced the standard camera with a HoloLens camera and pressed build. After that we needed to open the outputted solution with Visual Studio 2015 and pressed run…

And we got our own holograms, mind blown again :)

Then followed a series of making this demo app more and more complex. Adding voice commands, adding object interaction, adding surround sound..

The final state of our app included a hole in the floor where we could look into a “underworld” with bird, clouds and a landscape..

Mind blown again !

Final comments:

If you are using glasses, you need to remove the nose piece, otherwise the “screen” will not be placed correctly.

The field of view is much smaller than the keynote presentation showed us. This does not take anything away from HoloLens, and you forget it after a short while.

This is a awesome piece of hardware, and I can’t wait to try this again, thanks to Dave for being a great mentor during the academy.

Dynamics at //Build 2015

EH-LUMIA2520 - WIN_20150429_095236Right now the keynote for //Build 2015 is running. And something has changed, Dynamics has already being mentioned TWICE !!
At Build 2012 in Seattle Dynamics wasn’t even on a slide with ERP system shown at the keynote.

One more, Dynamics AX mentioned during the Office Graph talk.

Dynamics apps in the new Windows Store For Business

I will keep updating this post with Build+Dynamics impressions.

Stupid error on a friday :)

Today I upgraded a virtual machine running NAV2015 from Update 5 to Update 6. Not a big deal, but during the process I managed to delete the CustomSettings.config file – Stupid mistake on my part.

This file holds the entire configuration for the NAV Service Tier, from authentication of client to SQL Server connection and more.

But the real question I’m left with is:

Why does NAV keep its setting files under C:\Program Files ?

With the introduction of Longhorn (Windows Vista/Windows Server 2008) and UAC – Writing inside c:\Program Files became a elevated operation, so only users with Administrator rights could write there. After that, most programs began to use c:\ProgramData or storing setup and data under c:\Users. There is even a blog from Microsoft on the subject.

Funny enough, SQL Server still defaults its location for DATA under c:\Program files unless changed during the install. They properly keept it there for historic reasons – It has been that way since SQL Server 6.5.

But NAV does not have that history restriction, so from my perspective, this can be added to Luc’s  Lets clean up NAV list.

Anyway, that was my friday rant :)

User documentation of a NAV solution

In this series of articles I will explain a alternative method of handling user documentation for Microsoft Dynamics NAV 2015 code.

In E Foqus we use this for our ISV product Foqus Finance, but it can be used for any NAV solution, ranging from a small customer modification to huge ISV solutions (as Foqus Finance)

We have tried to solved a series of challenges with documentation:

First challenge: Documentation is dead the minute you’re finish writing it. Code changes, customers want it work differently, change requests keeps popping up. And the documentation (if any) stays at the initial level

Second challenge: Documentation is kept in documents (Word/PDF) sitting on local drives, attached to email, stored on file shares, often in multiple versions without any clear version strategy.

Third challenge: Customer want F1 help, and this has historical been an nightmare to create with NAV – from compiling CHM files with 3rd party tools to distribute files to clients.

Fourth challenge: New formats comes along all the time, creating an ebook with the help would be a very modern thing to do.

Read on for our solution to all this:

Step 1 – Organizing the input text
Step 2 – Getting structure into our documentation
Step 3 – Graphical Layout
Step 4 – Updating the Help Server Table Of Content (ToC.XML)
Step 5 – Editing and storing help text with NAV Code
Step 6 – Running the whole thing

Download the current version of the help toolkit:

EFoqusHelpToolkit 0.03

Further development:

Step 7 – Producing automated screenshots from NAV

Update the NAV2015 ToC.XML

The ToC.XML is a simple recursive structure with entries like this:

<?xml version="1.0" encoding="utf-8"?>
<Node Name="DynamicsHelp" DisplayName="Help" Page="conGettingStarted.htm">
    <Node Name="TechRef" DisplayName="Technical Reference" Page="conTechnicalReference.htm">
      <Node Name="CSIDERef" DisplayName="C/SIDE Reference Guide" Page="conCSIDEReferenceGuide.htm" />
      <Node Name="DevEnvCmds" DisplayName="Development Environment Commands" Page="conDevelopmentEnvironmentCommands.htm" />
      <Node Name="CSIDEwindows" DisplayName="Windows Overview" Page="conWindowOverviews.htm" />
    </Node>
    <Node Name="Upgrade" DisplayName="Upgrading to Microsoft Dynamics NAV 2015" Page="oriUpgradingToNAVCrete.htm">
      <Node Name="MigratingToMultitenancy" DisplayName="Migrating to Multitenancy" Page="conMigratingTenantDatabases.htm" />
    </Node>
  </Node>
</Node>

Just a name, a title and a page, and that looks very similar to the structure we already have in place from the manual. So we do here, is run through our own Structure.XML, and inserts matching entries into the ToC.

This is the main piece of code that will generate the html files, and update the ToC at the same time:

public bool GenerateAllContentAsHtml()
        {
            XDocument TOC = XDocument.Load(ConfigurationManager.AppSettings["input-toc"]);

            XElement root = (from xml2 in TOC.Descendants("Node")
                             where xml2.Attribute("Name").Value == ConfigurationManager.AppSettings["projectname"]
                             select xml2).FirstOrDefault();
            if (root == null)
            {
                root = GetNode(ConfigurationManager.AppSettings["projectname"], Data.manual.Title, ConfigurationManager.AppSettings["projectname"] + ".htm");
                TOC.Element("Node").Nodes().FirstOrDefault().AddAfterSelf(root);
            }
            root.Nodes().Remove(); // If we already have our stuff in this TOC remove it first

            StringBuilder ChapterList = new StringBuilder();
            foreach (var chapter in Data.manual.Chapters)
            {
                root.Add(GenerateChapter(chapter));
                string str = "<a href=\"" + ConfigurationManager.AppSettings["projectname"] + "_" + chapter.No + ".htm\" xmlns=\"http://ddue.schemas.microsoft.com/authoring/2003/5\">";
                str += chapter.Title + "</a><br>";
                ChapterList.Append(str);
            }

            Article preface = Data.Articles.Find(m => m.ID == Data.manual.Preface.ID);
            if (preface == null)
            {
                preface = new Article()
                {
                    ID = Data.manual.Preface.ID,
                    Text = "TODO: Article " + Data.manual.Preface.ID,
                    Title = "TODO: Article Caption " + Data.manual.Preface.ID
                };
            }
            StringBuilder topic = new StringBuilder(File.ReadAllText(ConfigurationManager.AppSettings["helppage-html"]));
            topic.Replace("$1$", preface.Title);
            topic.Replace("$1$", preface.Title);
            topic.Replace("$2$", ConvertMarkdown(preface.Text, "html") + ChapterList);
            File.WriteAllText(
                ConfigurationManager.AppSettings["output-path-helpserver"] + @"\" +
                ConfigurationManager.AppSettings["projectname"] + ".htm", topic.ToString());

            TOC.Save(ConfigurationManager.AppSettings["output-toc"]);
            return false;
        }

The NAV Based Help Editor System

When installing the FOB file from the download, you will get 2 tables and some support objects. Its important to say right up, that these objects are not “production quality” they are simply good enough for our use. That means hard-coded path and name of a an Markdown editor (Called MarkdownPad Pro) and no nice icons – You get the pictures, these are objects developed for developers, and once it works – that fine :) Fell free to extend them.

There are two types of help texts that you can maintain with these objects:

1. Articles – Very simple list of articles.
2. Content Help – This is help to objects (and fields) It is possible to populate this table with all the entries needed.

The last piece in the NAV objects is a XML Port to import/export the all the help. This is done in XML format and of-cause, this file

Running the Help processor

To get the whole thing running, take a look at the HelpTest.exe.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="miktex-path" value="C:\Program Files (x86)\MiKTeX 2.9\miktex\"/>
    <add key="pandoc-path" value="C:\Projects\Help\Tools\"/>
    <add key="template-xml" value=".\template.xml"/>
    <add key="content-xml" value=".\NAV.xml" />
    <add key="structure-xml" value=".\structure.xml"/>
    <add key="projectname" value="Demo Help"/>
    <add key="helppage-html" value=".\HelpPage.html"/>
    <add key="input-toc" value=".\input-toc.xml"/>
    <add key="output-toc" value=".\output\output-toc.xml"/>
    <add key="output-path-helpserver" value=".\output"/>
    <add key="output-path-manual" value=".\output"/>
  </appSettings>
  <startup> 
      <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
</configuration>

You  need to install the following to be ready:

MikTex 2.9 http://miktex.org/download

Pandoc https://github.com/jgm/pandoc/releases

And update the paths in the config file

After this you need to update all the setup paths and xml files. These should point to the content from the ZIP file.

Running HelpTest.exe from a prompt should generate output that looks a bit like this: (This is the output from Foqus Finance)

Building manual
Generate Topic 6030550 (Table)
Generate SubTopic 6030551 (Table)
Generate SubTopic 6030553 (Table)
Generate SubTopic 6030554 (Table)
Generate SubTopic 6030555 (Table)
Generate SubTopic 6030556 (Table)
Generate SubTopic 6030569 (Table)
Generate SubTopic 6030558 (Table)
Generate SubTopic 6030559 (Table)
Generate SubTopic 6030568 (Table)
Generate SubTopic 6030567 (Table)
Generate SubTopic 6030581 (Table)
Generate Topic 6030562 (Table)
Generate Topic StageSales (Article)
Generate Topic StageEstab (Article)
Generate Topic StageAdmin (Article)
Generate Topic StageRearr (Article)
Generate Topic StageArchive (Article)
Generate Topic 6030560 (Table)
Generate Topic 6030561 (Table)
Generate Topic 6030582 (Table)
Generate Topic 6030695 (Table)
Generate Topic 6030696 (Table)
Generate Topic 6030740 (Table)
Generate Topic 6030741 (Table)
Generate Topic 6030650 (Table)
Generate Topic 6030666 (Table)
Generate Topic 6030563 (Table)
Generate Topic 6030565 (Table)
Generate Topic 6030651 (Table)
Generate Topic 6030700 (Table)
Generate Topic 6030557 (Table)
Generate Topic 6030703 (Table)
Generate Topic 6030652 (Table)
Generate Topic 6030680 (Table)
Generate Topic 6030653 (Table)
Generate Topic 6030654 (Table)
Generate Topic 6030655 (Table)
Generate Topic 6030656 (Table)
Generate Topic 6030677 (Table)
Generate Topic 6030679 (Table)
Generate Topic ContractFlow (Article)
Generate SubTopic 6030901 (Table)
Generate SubTopic 6030902 (Table)
Generate SubTopic 6030904 (Table)
Generate Topic 6031008 (Table)
Generate SubTopic 6031009 (Table)
Generate SubTopic 6031010 (Table)
Generate SubTopic 6031011 (Table)
Generate SubTopic 6031000 (Table)
Generate SubTopic 6031001 (Table)
Generate SubTopic 6031002 (Table)
Generate SubTopic 6031003 (Table)
Generate SubTopic 6031004 (Table)
Generate SubTopic 6031005 (Table)
Generate SubTopic 6031006 (Table)
Generate SubTopic 6031007 (Table)
Generate Topic CostSetup (Article)
Generate SubTopic 6030659 (Table)
Generate SubTopic 6030702 (Table)
Generate SubTopic 6030675 (Table)
Generate Topic TaskSetup (Article)
Generate SubTopic 6030658 (Table)
Generate SubTopic 6030701 (Table)
Generate SubTopic 6030676 (Table)
Generate SubTopic 6030571 (Table)
Generate SubTopic 6030572 (Table)
Generate Topic ServiceIns (Article)
Generate SubTopic 6030566 (Table)
Generate SubTopic 6030663 (Table)
Generate SubTopic 6030664 (Table)
Generate SubTopic 6030669 (Table)
Generate SubTopic 6030670 (Table)
Generate SubTopic 6030671 (Table)
Generate SubTopic 6030672 (Table)
Generate SubTopic 6030673 (Table)
Generate Topic CreditApprov (Article)
Generate SubTopic 6030950 (Table)
Generate SubTopic 6030951 (Table)
Generate SubTopic 6030952 (Table)
Generate SubTopic 6030953 (Table)
Generate SubTopic 6030954 (Table)
Generate SubTopic 6030955 (Table)
Generate Topic FoqusDocSetup (Article)
Generate SubTopic 6030910 (Table)
Generate SubTopic 6030911 (Table)
Generate SubTopic 6030912 (Table)
Generate SubTopic 6030913 (Table)
Generate SubTopic 6030914 (Table)
Generate SubTopic 6030915 (Table)
Generate SubTopic 6030916 (Table)
Generate SubTopic 6030920 (Table)
Building helpserver files
Generate Topic 6030550 (Table)
Generate Topic 6030562 (Table)
Generate Topic StageSales (Article)
Generate Topic StageEstab (Article)
Generate Topic StageAdmin (Article)
Generate Topic StageRearr (Article)
Generate Topic StageArchive (Article)
Generate Topic 6030560 (Table)
Generate Topic 6030561 (Table)
Generate Topic 6030582 (Table)
Generate Topic 6030695 (Table)
Generate Topic 6030696 (Table)
Generate Topic 6030740 (Table)
Generate Topic 6030741 (Table)
Generate Topic 6030650 (Table)
Generate Topic 6030666 (Table)
Generate Topic 6030563 (Table)
Generate Topic 6030565 (Table)
Generate Topic 6030651 (Table)
Generate Topic 6030700 (Table)
Generate Topic 6030557 (Table)
Generate Topic 6030703 (Table)
Generate Topic 6030652 (Table)
Generate Topic 6030680 (Table)
Generate Topic 6030653 (Table)
Generate Topic 6030654 (Table)
Generate Topic 6030655 (Table)
Generate Topic 6030656 (Table)
Generate Topic 6030677 (Table)
Generate Topic 6030679 (Table)
Generate Topic ContractFlow (Article)
Generate SubTopic 6030901 (Table)
Generate SubTopic 6030902 (Table)
Generate SubTopic 6030904 (Table)
Generate Topic 6031008 (Table)
Generate Topic CostSetup (Article)
Generate SubTopic 6030659 (Table)
Generate SubTopic 6030702 (Table)
Generate SubTopic 6030675 (Table)
Generate Topic TaskSetup (Article)
Generate SubTopic 6030658 (Table)
Generate SubTopic 6030701 (Table)
Generate SubTopic 6030676 (Table)
Generate SubTopic 6030571 (Table)
Generate SubTopic 6030572 (Table)
Generate Topic ServiceIns (Article)
Generate SubTopic 6030566 (Table)
Generate SubTopic 6030663 (Table)
Generate SubTopic 6030664 (Table)
Generate SubTopic 6030669 (Table)
Generate SubTopic 6030670 (Table)
Generate SubTopic 6030671 (Table)
Generate SubTopic 6030672 (Table)
Generate SubTopic 6030673 (Table)
Generate Topic CreditApprov (Article)
Generate SubTopic 6030950 (Table)
Generate SubTopic 6030951 (Table)
Generate SubTopic 6030952 (Table)
Generate SubTopic 6030953 (Table)
Generate SubTopic 6030954 (Table)
Generate SubTopic 6030955 (Table)
Generate Topic FoqusDocSetup (Article)
Generate SubTopic 6030910 (Table)
Generate SubTopic 6030911 (Table)
Generate SubTopic 6030912 (Table)
Generate SubTopic 6030913 (Table)
Generate SubTopic 6030914 (Table)
Generate SubTopic 6030915 (Table)
Generate SubTopic 6030916 (Table)
Generate SubTopic 6030920 (Table)
Done

MiKTex might show some warnings like this, ignore those :)

This is makeindex, version 2.15 [MiKTeX 2.9] (kpathsea + Thai support).
Scanning input file FoqusFinance.idx.....done (1271 entries accepted, 1 rejected).
Sorting entries.............done (14618 comparisons).
Generating output file FoqusFinance.ind.....done (925 lines written, 0 warnings)
.
Output written in FoqusFinance.ind.
Transcript written in FoqusFinance.ilg.

** WARNING ** Couldn't open font map file "kanjix.map".

After this, oyu should have a PDF, a new ToC.xml and a bunch of HTML Files.

 

 

Graphical Layout for manuals and Help Server

The only components missing now before we are ready to put all this together, is graphical layout. Both help pages and a manual needs a “look”.

On the help server, the layout is given by Microsoft. We cannot have “our” help pages look completely different from those supplied by Microsoft if we want our users to have consistent user experience across different parts of NAV.

So we grab one the pages from the help server and strip all text. We insert “markers” into the page where we want to add text.

Currently we are using the following markers:

$1$ = Title
$2$ = Body text

More can easily be added, but for now, it is sufficient for our need.

Next, we need layout for our book, this is a bit more complicated (typesetting is an art form for some people), so we have introduced another xml file to our setup, called template.xml.

Template.xml holds bits of Latex code that the manual will be contructed from, it has the following bits:

<ManualStart> = The code that define the book (or ebook) imports all needed latex modules
<ManualEnd> = The code that gets appended at the end of the book
<ChaperHead> = The code that starts a chapter in the book
<ChapterBetweenTopics> = Placed between topics within a chapter
<ArticleTopicHead> = Head of an article
<ArticleTopicText> = Body on an article
<TableTopicHead> = Head of a table
<TableTopicIntro> = Introduction to a table
<TableTopicFields> = Fields in the table
<Field> = A single field
…..
And more. All these building block combined with the raw text, converted from Markdown to Latex, will produce a manual in PDF.

** Now we want to create pages for the NAV Help server

This is done with the same content as the manual. We need to do two steps:

1. Create each piece of help content we have as a HTML help page

2. Add references for our new pages into the ToC.xml file

** Create HTML pages for content

Again we use a template (called helppage.html) to add our content into. This time we use pandoc to convert the markdown to HTML and insert the HTML into the page. And we actually only inserts two pieces of information into the page:

1. The body text
2. The title

A difference compared to the PDF manual, is that we don’t show the fields together with the table. Instead we’ll create a list of fields that links to the individual pages for each field.

Getting structure into the documentation

Putting our pieces together now, gives us a database for storing the help, an editor (MarkdownPad) for editing, and a converter (Pandoc) for performing conversion and a typesetting system XeTeX.

But there are still a few thing missing, the first thing we need a way to describe the structure of our help. Dynamics NAV is based on “objects” indexed with numbers. The catch is, that there is no “user understandable” logic to the numbering. So we cannot say that the content in the manual should be ordered by object numbers.

We created a XML description of the structure, called structure.xml, it look a bit like this:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Manual>
  <Info>
    <Title>Demo Documention</Title>
    <Author>E Foqus Documentation 2015 (c)</Author>
    <Preface Type="Article" ID="Introduction" />
  </Info>
  <Chapters>
    <Chapter No="1" Title="The First Chapter">
      <Preface Type="Article" ID="chapter1intro" />
      <Topics>
        <Topic Type="Table" ID="18">
          <SubTopics>
            <SubTopic Type="Table" ID="21" />
          </SubTopics>            
         </Topic>
      </Topics>
    </Chapter>
    <Chapter No="2" Title="A chapter to far..">
      <Preface Type="Article" ID="charpter2intro" />
      <Topics>
        <Topic Type="Table" ID="24" />
      </Topics>
    </Chapter>
  </Chapters>
</Manual>

If you look at the table of content (ToC) in a book, this closly resembles what we have in structure.xml. The other element called <Manual> has a <Info> section with setting for the frontpage and an preface article. Then follows the <Chapters> section with multiple <Chapters>.

Each <Chapter> has a title, a preface article and a series of topics with sub-topics embedded.

Every time we have a preface, a topic or a sub-topic, it can have the following types:

* Article – Points to an article
* Table – Points to a table
* Page – Points to a page
* Report – Points to a report
* XMLport – Points to a XML Port

Each of these can be found in our NAV database.

When we look at the NAV 2015 Help server, we see the collapsible menu on the left, this structure resembles the ToC of a manual, and is stored in a filed called ToC.xml on the server. We can use our structure.xml to fill out the Help Server ToC.xml file.