IStream interface w/o need for unsafe code or MemoryStream

Wednesday, March 18, 2009 by Administrator

Looking back at the earlier posts of this blog; i have to admit time really flies by fast. It has been almost a year since my last post on the subject of the GotCAL.CSideInstaller. There have been lots of comments and new threads mainly on www.mibuso.com on the subject, and peoples interesting discoveries.

The main purpose of publishing the code i had, was to share and learn more about it. Here is a great comment, that i think deserves a post by itself from ghuebner:

"@Soren:
There is annother way to handle the IStream interface without the need for unsafe code or MemoryStream. The essential point is, that some methods of IStream use int* (Pointer to int) as parameters. This gives rise to a problem, if one implements those pointers in the managed memory area as IntPtr, e.g. - The trick is to simply define the pointers in the unmanaged memory area (global heap). The following (minimized) code-snipet copies an object to a file:

IntPtr pLEN = Marshal.AllocHGlobal(4);
IStream pOutStm;
CreateStreamOnHGlobal(0, true, out pOutStm);
INSObjectDesigner IOD = (INSObjectDesigner)RunningObjectTable.GetRunningCOMObjectByName("!C/SIDE!navision://client/run?");
int res = IOD.ReadObjects("WHERE(Type=CONST(Table),ID=CONST(3))", pOutStm);
pOutStm.Seek(0, 0, pLEN);
FileStream outputStream = new FileStream(@"C:\Temp\Table3.txt", FileMode.Create, FileAccess.Write);
int cnt, LEN = 4096;
byte[] buffer = new byte[LEN];
do
{
  pOutStm.Read(buffer, LEN, pLEN);
  cnt = Marshal.ReadInt32(pLEN);
  outputStream.Write(buffer, 0, cnt);
}
while (cnt == LEN);

The essential point is the variable pLEN which resides on the (unmanaged) global memory heap."

Dynamics NAV meets Guitar Hero/Rockband!

Saturday, November 22, 2008 by Administrator

Check out this great post/video from the dynamics mobile team: http://blogs.msdn.com/dynamicsmobile/archive/2008/11/21/microsoft-dynamics-mobile-case-study-at-roskilde-festival-watch-the-video.aspx

Interesting deployment of a mobile solution, and guess it all has become better now that version 1.5 is released. Enjoy.

NAV Text Object Handler by Jeremy Vyska

Saturday, September 27, 2008 by Administrator

Look at the great work from Jeremy Vyska on mibuso.com. Spending one day with C# he wrapped up this little automation for Dynamics NAV - based on the GotCAL.CSIDEInstaller class.

I have been way to busy, but i will get some other example uses posted here during the coming week. Actually im visiting Denmark for a week to go to Navtilus 10 year anniversary. Going to be nice to see present and past colleagues.

Anyways, drop a message if you have any ideas or comments in general, thanks.

Dynamicsplanet.com example w. GotCAL.CSIDEInstaller

Monday, August 18, 2008 by Administrator

Take a peek at http://dynamicsplanet.com. They have posted a small commandline utility featuring our CSIDEInstaller class. Nice for importing/exporting objects in text format without use of object designer.

Stay tuned for more upcoming posts....

NAV Launcher, for SQL and local navtive DB's

Wednesday, April 16, 2008 by Administrator

As a developer working on multiple customers databases, you know the issue: What client version to use with the database? Wouldn't be nice you could just open the .fdb file or connect to the SQL database, without worrying about by accident converting the database.

With NAV Launcher, which builds on the original "Navision Starter" by Sergey Gazizyanow, you can do this. It is shell integrated, so you just have to double click on the .fdb file, or select the SQL database - the program will then open the client version that corresponds to the database version.

How is this done? In SQL you can find the database version in dbo.[ndo$dbproperty].databaseversionno. In a local native database you can find this in the actual fdb file at position 0x2004, here is a list of the possible values:

Client versionSQL / databaseversionno  FDB, native 0x2004
 3.70 17 0x10
 4.0 30 0x11
 4.0 SP2 40 0x11
 4.0 SP3 60 0x12
 5.0 80 0x13
 5.0 SP1 95 0x13

As you can see some releases did no changes for the native version, and the latest servicepack for 5.0, is a SQL db-version upgrade only. I assume there are other issues fixed in the client, so it should still be worth upgrading - guess it will work with the same server version when they have same db-version.

NAV 5.x and Web Services

Wednesday, April 16, 2008 by Administrator

Stumbled over this cool webpost from the Dynamics NAV Blog. It is about Webservices in version 5.x. It includes a nice project for at COM object in C#, to communicate with the webservice. It is written by Kris Rafnsson.

I have not installed the project yet, but will start looking at it right away, as i need this for another project. I will post my comments on it then.

For now take a look at:
http://blogs.msdn.com/nav/archive/2008/04/15/using-web-services-to-access-microsoft-dynamics-nav-5-0.aspx 
and here the c# project:
http://code.msdn.microsoft.com/nav/Release/ProjectReleases.aspx?ReleaseId=896

GotCAL.CSideInstaller Source

Monday, March 24, 2008 by Administrator

(note this is a post in progress, please post comments etc.) 

This is the second part of Dynamics NAV and the ROT Table, which was posted in december 2007. In this article i will discuss some of the uses of the interfaces, and also give give you access to the sourcecode for a simple application created in Visual Studio 2005.

First off let's take a look at the Interface for the NSObjectDesigner class:

IObjectDesigner.cs:
namespace GotCAL.CSIDEInstaller
{
    using System;
    using System.Runtime.InteropServices;
    using System.Runtime.InteropServices.ComTypes;

    [ComImport, Guid("50000004-0000-1000-0001-0000836BD2D2"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface IObjectDesigner
    {
        [PreserveSig, DispId(1)]
        int ReadObject([In] int objectType, [In] int objectId, [In] IStream destination);
        [PreserveSig, DispId(2)]
        int ReadObjects([In] string filter, [In] IStream destination);
        [PreserveSig, DispId(3)]
        int WriteObjects([In] IStream source);
        [PreserveSig, DispId(4)]
        int CompileObject([In] int objectType, [In] int objectId);
        [PreserveSig, DispId(5)]
        int CompileObjects([In] string filter);
        [PreserveSig, DispId(6)]
        int GetServerName(out string serverName);
        [PreserveSig, DispId(7)]
        int GetDatabaseName(out string databaseName);
        [PreserveSig, DispId(8)]
        int GetServerType(out int serverType);
        [PreserveSig, DispId(9)]
        int GetCSIDEVersion(out string csideVersion);
        [PreserveSig, DispId(10)]
        int GetApplicationVersion(out string applicationVersion);
        [PreserveSig, DispId(11)]
        int GetCompanyName(out string companyName);
    }
}

as you can see we import the COM library, which we discovered in the registry. In the registry it shows it has 14 methods, so far i only know 11 of them. These were found using reflection on the Celenia Version Control software, and it is also the way (i guess!) the Developers Toolkit can extract the ojbects through the CSide Client.

Most of the methods are very simple, and just return a string, and thus they are very easy to implement, eg.:

public string GetDatabaseName()
        {
            string databaseName;
            int num = this._objectDesigner.GetDatabaseName(out databaseName);
            return databaseName;
        }

As most of you who have been playing around with this after the first post have discovered the biggest issue, is reading and writing the streams that holds the actual objects. At first I used "AuthHelper.dll" a library that somehow could handle the reading and writing of streams. But here is a StreamSupport class that handles it in .NET:

  namespace GotCAL.CSIDEInstaller
{
    using System;
    using System.IO;
    using System.Runtime.InteropServices.ComTypes;

    public class StreamSupport
    {
        public static unsafe IStream ToIStream(Stream stream, ref IStream comStream)
        {
            byte[] buffer = new byte[stream.Length];
            stream.Read(buffer, 0, buffer.Length);
            uint num = 0;
            IntPtr pcbWritten = new IntPtr((void*) &num);
            comStream.Write(buffer, buffer.Length, pcbWritten);
            return comStream;
        }

        public static unsafe MemoryStream ToMemoryStream(IStream comStream)
        {
            MemoryStream stream = new MemoryStream();
            byte[] pv = new byte[100];
            uint num = 0;
            IntPtr pcbRead = new IntPtr((void*) &num);
            do
            {
                num = 0;
                comStream.Read(pv, pv.Length, pcbRead);
                stream.Write(pv, 0, (int) num);
            }
            while (num > 0);
            return stream;
        }
    }
}

Hope to get some feedback from all you out there, please post a comment, idea, or just a quick hello.

Download the sample application here.

Cash in with your Dynamics knowledge

Monday, March 24, 2008 by Administrator

It's a prize draw competition which you can enter by signing up to the Dynamics Community. 

To join the fun, first visit: http://community.dynamics.com/ and sign in with your Windows Live ID. Then visit http://cashinwithdynamics.com/ to where you can spin the wheel to get points. The grand prize is a Vegas trip with all inclusive, but check out the site there is a lot of other prices. 

Extra points can be gained when someone joins the community and your screen name is entered. Btw. My screen name is “Soren Nielsen”.

Microsoft Dynamics NAV Test Drive

Friday, December 14, 2007 by Administrator

"By logging onto our test drive environment using your web browser, you will be able to experience Microsoft Dynamics NAV first hand without the need of installing it on your computer. You can explore the product on your own, or follow along guided exercises and demos."

http://www.dynamicsnavtestdrive.com/

That is pretty cool! It seems to use a ActiveX "'Virtual Server VRMC Advanced Control' from Microsoft. Anyways check it out, if you are not already familiar with NAV.

Dynamics NAV and the ROT Table

Monday, December 10, 2007 by Administrator

With the introduction of hyperlinks for the Dynamics NAV client, the approach taken was the Running Object Table (ROT Table). From the http://msdn2.microsoft.com/en-us/library/ms695276.aspx article: "The most common type of moniker provider is a compound-document link source. This includes server applications that support linking to their documents (or portions of a document) and container applications that support linking to embeddings within their documents."

Im not a wizard in to this, and it has been a lot of googling for the information, so if you have additional information on this issue, any hints and information would be very helpful.

Where do we find information about the interfaces? In the registry, take a look at this key:

ROTregistry

Here are the some class names from the registry:

  1. INSHyperlink
  2. INSObjectDesigner
  3. INSApplication
  4. INSForm
  5. _INSApplicationEvents
  6. INSHook
  7. INSTable
  8. INSRec
  9. INSMenuButton
  10. _INSMenuButtonEvents
  11. INSAppBase
  12. INSCallbackEnum

For now i have only been able to find Interfaces to INSObjectDesigner (as they are used in Celenia Version Control), which of course is very interesting. It exposes methods for these functions:

ObjectDesignerInterface

But where is the "documenation" on these interfaces??????

The format for the Read and Write functions are text files, like the ones that can be imported/exported through the object designer.

Currently i have created small installers for code dropping into NAV objects, that uses the ReadObject, then parses the file, and inserts the code, and finally imports back into NAV with WriteObjects.

Here is some screenshots from a simple application reading objects into a texteditor, allows editing, and then writing back to NAV:

Step 1: Read object into editor

edit0

Step 2: Find documentation trigger

edit1

Step 3: Add text

edit2

Step 4: Write back to NAV

edit3

Step 5: Code changed in NAV

edit4

So currently im interested in finding information about the other interfaces. I will continue this series of post here when i get some decent frameworks done in .NET. Perhaps making a Dynamics NAV Installer project in the open source community would be interesting, what do you think?

Other resources:

http://www.codeproject.com/KB/cs/automatingvisualstudio.aspx
http://www.mibuso.com/dlinfo.asp?FileID=776

Not to forget, kudo's go out to Claus Hornbæk, Alexey Pavlov and Lutz Roeder.