Microsoft Dynamics NAV: OS Integration

Exclusive offer: get 50% off this eBook here
Microsoft Dynamics NAV 2009 Programming Cookbook

Microsoft Dynamics NAV 2009 Programming Cookbook — Save 50%

Build better business applications with Microsoft Dynamics NAV 2009 with this book and eBook

$35.99    $18.00
by Matt Traxinger | October 2010 | Enterprise Articles Microsoft

In this article by Matt Traxinger, author of Microsoft Dynamics NAV 2009 Programming Cookbook, we will cover:

  • Using HYPERLINK to open external files
  • Working with environment variables
  • Using SHELL to run external applications
  • Browsing for a file
  • Browsing for a folder
  • Checking file and folder access permissions
  • Querying the registry
  • Zipping folders and files within NAV

 

Microsoft Dynamics NAV 2009 Programming Cookbook

Microsoft Dynamics NAV 2009 Programming Cookbook

Build better business applications with NAV

  • Write NAV programs to do everything from finding data in a table to integration with an instant messenger client
  • Develop your own .NET code to perform tasks that NAV cannot handle on its own
  • Work with SQL Server to create better integration between NAV and other systems
  • Learn to use the new features of the NAV 2009 Role Tailored Client
  • Easy-to-read recipes with detailed explanations and images
  • Maximize your learning with short tutorials that tell you exactly what you need to know without all of the fluff
        Read more about this book      

Introduction

If you have programmed with Windows or used a Windows-based operating system for any length of time you will see that it is really an all-encompassing OS, at least for our needs. Unlike with other types of software development, we don't need to interact with device drivers or create three dimensional graphics for our users. Most of what we need to do involves integrating with the file system; that is searching for files or folders and running external applications.

Occasionally, we may need to go a little deeper. There may be instances where we need to check the user's environment, query the registry, or check for specific administrator permissions. These can all be performed within NAV, although many require a little outside help from a built-in or custom automation control.

As Windows is such a large piece of software, it already contains ways for us to do these things. As a result, the recipes in this article are not very lengthy or complicated, but that does not make them any less useful. They explore the basics of what you can do with the OS and it is up to you to decide when and how to make the best use of them.

It is important to note that many of these recipes will require additional coding to make them work with the RoleTailored client. This is because the code is actually executing on a server, not your own computer as it does with the Classic client.

Using HYPERLINK to open external files

Many times you may need to open files external to the NAV program. NAV has a built-in function that interacts with the file system to open the file with the appropriate application.

How to do it...

  1. Create a new codeunit from Object Designer.
  2. Add the following global variable:

    Name Type
    Selection Integer

  3. Add the following code to the OnRun trigger:

    Selection := STRMENU('Image,Website');
    IF Selection = 1 THEN
     HYPERLINK('C:\Users\Public\
       Pictures\Sample Pictures\Penguins.jpg')
    ELSE
     HYPERLINK('HTTP://www.mibuso.com');

  4. Save and close the codeunit.

How it works...

When you run the codeunit you will be presented with a simple selection menu that asks you to choose between an image and a website. Depending on your choice we will use the HYPERLINK command to load a specific file. This command takes in a single string which points to a location and loads that pointer using the default program on the current machine.

If you choose Image then the Penguins image that ships with Microsoft Windows 7 will load in the default program you have set to open pictures, usually Windows Photo Viewer.

Microsoft Dynamics NAV: OS Integration

If you choose Website then the Mibuso website will open in your default internet browser, typically Internet Explorer.

There's more...

With the RoleTailored client, it is best to use HYPERLINK with shared drives and folders. This is because the actual HYPERLINK command is running on the NAV service tier, not on the local computer or client. It has no idea about the user's system. This example is for the Classic client (thus the link to a file on the C: drive), but changing the parameter to a shared file on your network should work just fine.

See also

  • Using SHELL to run external applications
  • Browsing for a file
  • Checking file and folder access permissions

Working with environment variables

Environment variables are a set of named values that can affect the way processes and applications run on a computer. NAV has a built-in function to reference these variables and lets you change the way it functions.

How to do it...

  1. Create a new codeunit from Object Designer.
  2. Add the following code to the OnRun trigger:

    MESSAGE(' OS: %1\Temp: %2\WinDir: %3', ENVIRON('OS'),
         ENVIRON('TEMP'), ENVIRON('WINDIR'));

  3. Save and close the codeunit.

How it works...

The ENVIRON function takes in a single string and returns a string. Our codeunit uses the ENVIRON function to return three common environment variables: the name of the operating system, the path to the temporary folder for the current user, and the path to the Windows installation directory.

In Windows 7, in order to see all of the options available to the ENVIRON command, simply right-click on My Computer and go to Properties.

Microsoft Dynamics NAV: OS Integration

Click on Advanced system settings, the Advanced tab, and then on the Environment Variables button. You will find them in the System variables section of the window.

Microsoft Dynamics NAV: OS Integration

There's more...

This recipe is not compatible with the RoleTailored client. The code running on the NAV service tier does not know anything about the client operating system. There is, however, a way around this. We need a way to force code to be executed on the client-side instead of the server-side.

ENVIRON for the RoleTailored client

We can force our code to execute on the client-side by creating an Automation. Start by creating a new project in Visual Studio with the following code:

using System.Management;
using System.Runtime.InteropServices;

namespace RemoteSystemInfo
{
 [ClassInterface(ClassInterfaceType.AutoDual)]
 [ProgId("RemoteSystemInfo")]
 [ComVisible(true)]
 public class RemoteSystemInfo
 {
  public string GetSysInfo(string domain, string machine,
      string username, string password, string variable)
  {
   ManagementObjectSearcher query = null;
   ManagementObjectCollection queryCollection = null;
   ConnectionOptions opt = new ConnectionOptions();
   opt.Impersonation = ImpersonationLevel.Impersonate;
   opt.EnablePrivileges = true;
   opt.Username = username;
   opt.Password = password;

   try
   {
    ManagementPath p = new ManagementPath(@"\\" +
      machine + @"\root\cimv2");
    ManagementScope msc = new ManagementScope(p, opt);
    SelectQuery q = new SelectQuery("Win32_Environment");
    query = new ManagementObjectSearcher(msc, q, null);
    queryCollection = query.Get();

    foreach (ManagementBaseObject envVar in queryCollection)
    {
     if (envVar["Name"].ToString() == variable)
     {
      return envVar["VariableValue"].ToString();
     }
    }
   }
  catch (ManagementException e)
  {
   throw new ManagementException("Management Exception:
        " + e.Message);
  }
  catch (System.UnauthorizedAccessException e)
  {
   throw new ManagementException("Access Exception:
       " + e.Message);
  }
  return "";
  }
 }
}

When using the Automation in your NAV objects you must do the following:

CREATE(MyAutomation, FALSE, TRUE);

The third parameter tells the system to create the instance of the Automation on the client (TRUE) and not the server (FALSE). As the code executes on the client machine it can query the environment variables and easily return the correct result. Just pass the appropriate values to the GetSysInfo function.

See also

  • Using SHELL

Using SHELL to run external applications

Just as external files can be opened from within NAV, so can external programs. This recipe will show you how to launch one of such applications.

How to do it...

  1. Create a new codeunit from Object Designer.
  2. Add the following code to the OnRun trigger:

    SHELL(ENVIRON('WINDIR') + '\notepad.exe');

  3. Save and close the codeunit.

How it works...

The SHELL command takes in a required string parameter representing the application to launch. There is an optional second parameter that will be passed as an argument to the application to be launched (not used here). This argument could represent a file to open or other flags incorporated into the program.

See also

  • Querying the registry

 

Microsoft Dynamics NAV 2009 Programming Cookbook Build better business applications with Microsoft Dynamics NAV 2009 with this book and eBook
Published: October 2010
eBook Price: $35.99
Book Price: $59.99
See more
Select your format and quantity:
        Read more about this book      

Browsing for a file

You will perform many modifications that require input from a file on the Windows file system. Instead of requiring the user to remember the full path and name of the file, we will show you how to use an out-of-the-box codeunit to let them select the file using a dialog box.

How to do it...

  1. Create a new codeunit from Object Designer.
  2. Add the following global variables:

    Name Type Subtype Length
    CommonDialogMgt Codeunit Common Dialog Management

     

    SelectedFile Text

     

    255

  3. Add the following code to the OnRun trigger:

    SelectedFile := CommonDialogMgt.OpenFile('NAV File Browser',
           SelectedFile,1,'Filter',0);
    MESSAGE('You selected %1', SelectedFile);

  4. Save and close the codeunit.

How it works...

NAV provides a codeunit, number 412, named Common Dialog Management. It uses an OCX that references to the Microsoft Common Dialog Control. This codeunit provides a function that allows you to open a simple dialog box in either Open or Save mode. This function, OpenFile, takes five parameters.

The first is the title of the dialog box or Window. Next is the default file name to look for. The third and fourth parameters work together. The third is the default file type. When this is set to Custom the function uses the filter string passed in parameter four. The final argument tells the dialog box which mode to open in, that is Open or Save.

Microsoft Dynamics NAV: OS Integration

Should you choose to open the dialog box with a custom file type, you will have to enter a filter. You can see how these filters are formed by examining the global text constants, but we have also provided an example here:

Text Files (*.txt)| *.txt | All Files (*.*) | *.*

See also

  • Using HYPERLINK to open external files
  • Checking file and folder access permissions
  • Browsing for a folder

Browsing for a folder

NAV provides us with a way to browse for a file right out-of-the-box, but it does not let us browse for a folder. This recipe will show you a work around using automation controls that should already be installed on your system.

How to do it...

  1. Create a new codeunit from Object Designer.
  2. Add the following global variables:

    Name Type Subtype Length
    MSShell Automation 'Microsoft Shell Controls And Automation'.Shell

     

    Folder Automation 'Microsoft Shell Controls And Automation'.Folder3

     

    FilesInFolder Automation 'Microsoft Shell Controls And Automation'. FolderItems3

     

    CurrentFile Automation 'Microsoft Shell Controls And Automation'. FolderItem2

     

    SelectedFolder Text

     

    1024

  3. Add the following code to the OnRun trigger:

    CREATE(MSShell, FALSE, TRUE);
    Folder := MSShell.BrowseForFolder(0, 'NAV Folder Browser', 0);
    FilesInFolder := Folder.Items();
    CurrentFile := FilesInFolder.Item();
    SelectedFolder := FORMAT(CurrentFile.Path);
    MESSAGE('Selected Folder: %1\Contains %2 files',
          SelectedFolder, FilesInFolder.Count());

  4. Save and close the codeunit.

How it works...

This recipe depends entirely on the classes found in the Microsoft Shell Controls and Automation package.

For a list of the objects found in this package you can search MSDN or go to
http://msdn.microsoft.com/en-us/library/bb776890%28VS.85%29.aspx.

The code may seem like a lot just to get a folder name, but let's go through it line-by-line and explain why we are doing what we are doing. First we create or instantiate our MSShell variable, just as we do with every Automation variable. This one has a function called BrowseForFolder that launches the dialog box.

Microsoft Dynamics NAV: OS Integration

Unfortunately, this function returns a Folder object, which does not have text representation. So we have to take it a step further. We then retrieve a list of the files contained in that folder. This list is stored in our FilesInFolder variable. We can access the first item in this list. This file has a path and we can store that as our selected folder.

See also

  • Browsing for a file
  • Checking file and folder access permissions

Checking file and folder access permissions

Many systems have batch processes which read and write files to folders on the file system. In order to avoid some of the standard Windows error messages and prevent errors in the middle of the process you may want to check access permissions.

How to do it...

  1. Create a new Class Library project in Visual Studio.
  2. Create a new file with the following code:

    using System;
    using System.Security.Permissions;
    using System.Runtime.InteropServices;
    namespace FolderAccess
    {
     [ClassInterface(ClassInterfaceType.AutoDual)]
     [ProgId("RegistryQuery")]
     [ComVisible(true)]
     public class FolderAccess
     {
      public bool TestFolderAccess(string folder, string access)
      {
       System.Security.Permissions.FileIOPermissionAccess
           accessLevel;
       switch (access.ToUpper())
       {
        case "NOACCESS": accessLevel =
            FileIOPermissionAccess.NoAccess; break;
        case "READ": accessLevel =
            FileIOPermissionAccess.Read; break;
        case "WRITE": accessLevel =
            FileIOPermissionAccess.Write; break;
        case "APPEND": accessLevel =
            FileIOPermissionAccess.Append; break;
        case "PATHDISCOVERY": accessLevel =
            FileIOPermissionAccess.PathDiscovery; break;
        case "ALLACCESS": accessLevel =
            FileIOPermissionAccess.AllAccess; break;
        default: return false;
       }
       FileIOPermission permission = new
             FileIOPermission(accessLevel, folder);
       try
       {
         permission.Demand();
       }
       catch (Exception ex)
       {
         return false;
       }
      return true;
      }
     }
    }

  3. Save, compile, and close the project.
  4. Create a new codeunit from Object Designer.
  5. Add the following global variable:

    Name Type Subtype
    FolderAccess Automation 'FolderAccess'.FolderAccess

  6. Add the following code to the OnRun trigger:

    CREATE(FolderAccess, FALSE, TRUE);
    MESSAGE('Access: %1',
         FolderAccess.TestFolderAccess('C:\', 'WRITE'));

  7. Save and close the codeunit.

How it works...

Our custom C# function, TestFolderAccess, takes in two parameters: the path or folder to check and the type of permission to check for. Using the FileIOPermission class we set these values and demand the access level. The Demand function will throw an exception if we do not currently have access to the folder. In that case we return false, but in all other cases we return true.

See also

  • Browsing for a file
  • Browsing for a folder

Querying the registry

You may never need to query the registry on the computer when creating a NAV modification, but you should consider it as an option.

How to do it...

  1. Create a new Class Library project in Visual Studio.
  2. Create a new file with the following code:

    using System;
    using System.Runtime.InteropServices;
    using Microsoft.Win32;
    namespace RegistryQuery
    {
     [ClassInterface(ClassInterfaceType.AutoDual)]
     [ProgId("RegistryQuery")]
     [ComVisible(true)]
     public class RegistryQuery
     {
      public string GetKeyValue(string key, string name)
      {
       RegistryKey regKey = Registry.Users.OpenSubKey(key);
       if (regKey == null)
       {
        return "Key not found!";
       }
       else
       {
        object value = regKey.GetValue(name);
        if (value != null)
        {
          return value.ToString();
        }
        else
        {
        return "Name not found!";
        }
       }
      }
     }
    }

  3. Save, compile, and close the project.
  4. Create a new codeunit from Object Designer.
  5. Add the following global variable:

    Name Type Subtype
    RegistryQuery Automation 'RegistryQuery'.RegistryQuery

  6. Add the following code to the OnRun trigger:

    CREATE(RegistryQuery, FALSE, TRUE);
    MESSAGE('%1', RegistryQuery.GetKeyValue('.DEFAULT\Environment',
              'TEMP'));

  7. Save and close the codeunit.

How it works...

You may never have an instance where you need to examine registry values in your NAV code. In most instances, it will be easier to add a column to User Setup or store the information in a custom table. As a NAV developer, and less specifically, a business applications developer, you may encounter a situation that warrants this type of development. Let's take a look at the code.

Our C# code works for a specific root in the registry, HKEY_USERS. We access the subkey passed in the first parameter to our function using the Registry.Users.OpenSubKey function. If the key is not found, or null, we return an appropriate message. You could modify the code to access the other root folders by passing an additional parameter.

Next, we try to access the names stored in the key. Again, if we are unable to find the key equal to the second parameter of our function, we return null. If we do find it, we return its value.

Microsoft Dynamics NAV: OS Integration

Our NAV code looks for the temporary folder assigned to the user, similar to what ENVIRON('TEMP') returns. Do not think that this is only limited to things that can also be found using the ENVIRON function, though. You can query any value in the registry.

There's more...

You can also perform other actions on the registry using the CreateSubKey and DeleteSubKey functions. Be warned, though. You should not play with the registry unless you know what you are doing. You can easily corrupt the entire system if you are not careful.

For more information about the registry you can view this MSDN article:
http://msdn.microsoft.com/en-us/library/h5e7chcf.aspx

See also

  • Working with environment variables

Zipping folders and files within NAV

This might not be a common task, but creating files and e-mailing them from within NAV is. You can combine this with those recipes to send large groups of files at once.

How to do it...

  1. Create a new codeunit from Object Designer.
  2. Add the following global variables:

    Name Type Subtype
    ZipFile File

     

    MSShell Automation

    'Microsoft Shell Controls And Automation'.Shell

    ZipFolder Automation 'Microsoft Shell Controls And Automation'.Folder

  3. Add the following code to the OnRun trigger:

    ZipFile.CREATE(
       'C:\Users\Public\Pictures\Sample Pictures\Pictures.zip');
    CREATE(MSShell, FALSE, TRUE);
    ZipFolder := MSShell.NameSpace(
        'C:\Users\Public\Pictures\Sample Pictures\Pictures.zip');
    ZipFolder.CopyHere(
        'C:\Users\Public\Pictures\Sample Pictures\Desert.jpg');

  4. Save and close the codeunit.

How it works...

A ZIP file is really just a folder that happens to have its contents compressed. We can create this file or folder just as we would create a text file, using the CREATE command.

Next, we assign the namespace of our MSShell object to this ZIP file. This means that whatever we do with our MSShell variable we will be doing to this file.

As the ZIP file is really just a folder, we can perform any file system action on it. In this case, we want to copy files into the folder. We achieve this by using the CopyHere function where the "Here" refers to our namespace and the parameter passed tells the function which file to copy.

Summary

In this article we covered the following recipes:

  • Using HYPERLINK to open external files
  • Working with environment variables
  • Using SHELL to run external applications
  • Browsing for a file
  • Browsing for a folder
  • Checking file and folder access permissions
  • Querying the registry
  • Zipping folders and files within NAV
Microsoft Dynamics NAV 2009 Programming Cookbook Build better business applications with Microsoft Dynamics NAV 2009 with this book and eBook
Published: October 2010
eBook Price: $35.99
Book Price: $59.99
See more
Select your format and quantity:

About the Author :


Matt Traxinger

Matt Traxinger graduated from the Georgia Institute of Technology in 2005 with a B.S. in Computer Science, specializing in Human Computer Interaction and Cognitive Science. After college he took a job as an add-on developer using a language he was unfamiliar with for a product he had never heard of: Navision. It turned out to be a great decision.

In the years following Matt learned all areas of the product and earned Microsoft Certified Business Solutions Professional certifications in both technical and functional areas of NAV. He continues to stay current with new releases of the product and is certified in multiple areas for versions 4.0, 5.0, and 2009.

Currently Matt works in Norcross, GA, for Canvas Systems, one of the largest resellers of new and refurbished computer equipment as an in-house NAV Developer and Business Analyst. He supports multiple offices in the United States as well as locations in the United Kingdom and the Netherlands.

In his spare time you can find him on the online communities Mibuso.com and DynamicsUser.net under the name MattTrax, helping others learn more about the Dynamics NAV software.

Books From Packt


Microsoft Dynamics NAV 2009 Application Design
Microsoft Dynamics NAV 2009 Application Design

Microsoft Windows Communication Foundation 4.0 Cookbook for Developing SOA Applications
Microsoft Windows Communication Foundation 4.0 Cookbook for Developing SOA Applications

Microsoft Silverlight 4 and SharePoint 2010 Integration
Microsoft Silverlight 4 and SharePoint 2010 Integration

WCF 4.0 Multi-tier Services Development with LINQ to Entities
WCF 4.0 Multi-tier Services Development with LINQ to Entities

PostgreSQL 9.0 High Performance
PostgreSQL 9.0 High Performance

Microsoft Silverlight 4 Data and Services Cookbook
Microsoft Silverlight 4 Data and Services Cookbook

Applied Architecture Patterns on the Microsoft Platform
Applied Architecture Patterns on the Microsoft Platform

Learning jQuery 1.3
Learning jQuery 1.3


No votes yet

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
y
4
w
Y
x
L
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software