(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.