Access Navision Stream From DotNet

Administrator
Member, Moderator, Administrator Posts: 2,506
Access Navision Stream From DotNet
Simple example how to pass Navision stream (InStream/OutStream) to COM DLL written in .NET (Framework 2.0).
VS2005 solution and sample Navision object are included in archive. Current example reading picture from Item.Picture field and saving it to disk.
Thank you everybody who kicked my in right direction (wakestar, chrido, TonyH and Reflector (tool) )
http://www.mibuso.com/dlinfo.asp?FileID=776
Discuss this download here.
Simple example how to pass Navision stream (InStream/OutStream) to COM DLL written in .NET (Framework 2.0).
VS2005 solution and sample Navision object are included in archive. Current example reading picture from Item.Picture field and saving it to disk.
Thank you everybody who kicked my in right direction (wakestar, chrido, TonyH and Reflector (tool) )
http://www.mibuso.com/dlinfo.asp?FileID=776
Discuss this download here.
0
Comments
-
Thank you for this really great and useful solution. I can use it as basis for the idea in one of my current project.
I've just one small annotation: Close the Streamwriter before return the flag1 value. So you can access the file with an extern process, otherwise first Navision has to be closed. Because the file handle will not be released.public bool LoadFromNavision([In, MarshalAs(UnmanagedType.AsAny)] object COMStream) { bool flag1 = true; Stream stream1 = new MemoryStream(); byte[] buffer1 = new byte[0xafc8]; this.rwBytes = Marshal.AllocHGlobal(4); IStream COMStream1 = COMStream as IStream; FileStream writer = new FileStream(@"C:\stream.dat", FileMode.CreateNew); int _rwBytes = 0; do { COMStream1.Read(buffer1, 0xafc8, this.rwBytes); _rwBytes = Marshal.ReadInt32(this.rwBytes); writer.Write(buffer1, 0, _rwBytes); } while (_rwBytes > 0); Marshal.FreeHGlobal(this.rwBytes); writer.Close(); return flag1; }
Greets from Switzerland
Andy0 -
Thanks for the very nice sample.
Does anyone have an example on how to pass a stream back to navision?
I wan't to pass the string representation of a msxml.xmldom to a .NET-Com-Controller and back to navision by using the stream objects in navision.
Why do you use 0xafc8 in byte[] buffer1 = new byte[0xafc8];?
I see that you can't get the length of the IStream object, so you have to initialize the byte array with a assumed maximum, but why 0xafc8?
thanks & best regards
tobias0 -
Access Navision Stream From DotNet
Simple example how to pass Navision stream (InStream/OutStream) to COM DLL written in .NET (Framework 2.0).
VS2005 solution and sample Navision object are included in archive. Current example reading picture from Item.Picture field and saving it to disk.
Thank you everybody who kicked my in right direction (wakestar, chrido, TonyH and Reflector (tool) )
Update 21.12.2006:
+ Added code to import data into NAV.
http://www.mibuso.com/dlinfo.asp?FileID=776
Discuss this download here.0 -
Hi.
Thanks for that sample.
I am making a DLL to convert any image format to BMP format to allow Navision show that.
The DLL have 2 functions, the first one get data from a Navision Stream and save it to a Bitmap variable with the original format, and the second return this Bitmap in BMP format to Navision Stream.
The first function works correctly and save the image, but the second one I do not obtain that it gives back stream directly, that I must pass it to a temporary BMP file and read it and pass it to a stream.
This is the code of the second function:public void GetIMGBuffer([Out, MarshalAs(UnmanagedType.AsAny)] object COMStream) { Stream stream1 = new MemoryStream(); System.Drawing.Imaging.ImageFormat BMPformat; BMPformat = System.Drawing.Imaging.ImageFormat.Bmp; BMPData.Save(stream1, BMPformat); BMPData.Dispose(); BMPData = null; IStream COMStream1 = COMStream as IStream; this.rwBytes = Marshal.AllocHGlobal(4); byte[] buffer1 = new byte[0xafc8]; //IStream COMStream = new IStream(); int _rwBytes = 0xafc8; int bytesRead = 0; do { bytesRead = stream1.Read(buffer1, 0, _rwBytes); Marshal.WriteInt32(this.rwBytes, bytesRead); COMStream1.Write(buffer1, bytesRead, this.rwBytes); } while (bytesRead > 0); //COMStream1.Commit(0); stream1.Dispose(); Marshal.FreeHGlobal(this.rwBytes); }
And this is the code with temporary file:public void GetIMGBuffer([Out, MarshalAs(UnmanagedType.AsAny)] object COMStream) { Stream stream1 = new MemoryStream(); System.Drawing.Imaging.ImageFormat BMPformat; BMPformat = System.Drawing.Imaging.ImageFormat.Bmp; BMPData.Save(stream1, BMPformat); BMPData.Save("C:/export.bmp", BMPformat); BMPData.Dispose(); BMPData = null; IStream COMStream1 = COMStream as IStream; this.rwBytes = Marshal.AllocHGlobal(4); byte[] buffer1 = new byte[0xafc8]; FileStream reader = new FileStream("C:/export.bmp", FileMode.Open); //IStream COMStream = new IStream(); int _rwBytes = 0xafc8; int bytesRead = 0; do { bytesRead = reader.Read(buffer1, 0, _rwBytes); //bytesRead = stream1.Read(buffer1, 0, _rwBytes); Marshal.WriteInt32(this.rwBytes, bytesRead); COMStream1.Write(buffer1, bytesRead, this.rwBytes); } while (bytesRead > 0); //COMStream1.Commit(0); reader.Close(); reader.Dispose(); Marshal.FreeHGlobal(this.rwBytes); System.IO.File.Delete("C:/export.bmp"); }
I think that I am reading bad stream.
Thanks for all.
PD: I can upload the VS2005 project to you if needed. I don't know if if this is the correct place to put it.
PD2: sorry for my bad English.0 -
Hey guys,
I've been messing around with getting this to work, but without any effort. It seems like there is no way to use the IStream interface out of .NET
The sample does not compile for me either. Here is what the linker says:Warning: Type contains [MarshalAs(AsAny)], which is only valid for PInvoke. The MarshalAs directive was ignored.
When trying to use the IStream interface directly, it tells me the following:Warning: Type library exporter could not find the type library for 'System.Runtime.InteropServices.ComTypes.IStream'. IUnknown was substituted for the interface.
I use a fresh installation of VS 2005 Professional with SP1 (?) extension. According to Navisions Application Designers Guide, Navision is able to use VT_STREAM (with is IStream) and maps it to its In-/Outstream types in C/SIDE. To be honest, i think this sample does not work at all, because it uses VARIANT instead of IStream.
There must be a working way to use the IStream interface out of C#.NET, but how? Any ideas?0 -
Bastian Selonke wrote:...To be honest, i think this sample does not work at all, because ...
To be true, I tried it and it worked for me. Ok, I did some minor (but may be irrelevant) changes:
I'm running VS2005 .NET express edition and Navision 5.0.
The project compiled as downloaded except the warnings you mentioned and an unused int variable "bytes", which I deleted. As the compiler said, the MarshalAs directive is ignored, I deleted it, too and the project finally compiled without any warnings. To make things easy, I checked "Register for COM Interop" in the project properties and what shall I say, it worked promptly (I tested only the LoadFromNavision method since it is the only one I will need for the moment...) -
Many Thanks to Alexey for this very usefull sample piece of code.New kits on the blog: https://massivedynamicsblog.wordpress.com0 -
Hi all,
I'm using the code given in NAV4.03. It works great. But the problem is: it crash randomly. Sometimes it success; somtimes just memory error.
Sometimes NAV error saying cannot read from empty BLOB.
any one has the some experience?0 -
I'm also using this since a year or so in production without crash. The component is something like a http server and raises data into Navision, in peak hours about ~200 requests per minute.
I had also crashes. You have to be very careful with multiple threads. I have a queue before raising the data into Navision as an event. Then I'm waiting till the event has finished and i get the returnvalue, manual garbage collection, waiting additional a few ticks and then raise the next blob into Navision.
With Navision 3.70a i never had these problems.
... I personally see this solution as a hack and under normal circumstances I wouldn't use it in production, but their is currently no better solution which provides a similar performance.0 -
Just a small notice.
If you receive a very general error message "Object reference not set to an instance of an object", be sure to check whether you InStream in Navision is created properly.
Hope this saves you a couple of hours...0
Categories
- All Categories
- 73 General
- 73 Announcements
- 66.6K Microsoft Dynamics NAV
- 18.7K NAV Three Tier
- 38.4K NAV/Navision Classic Client
- 3.6K Navision Attain
- 2.4K Navision Financials
- 116 Navision DOS
- 851 Navision e-Commerce
- 1K NAV Tips & Tricks
- 772 NAV Dutch speaking only
- 617 NAV Courses, Exams & Certification
- 2K Microsoft Dynamics-Other
- 1.5K Dynamics AX
- 320 Dynamics CRM
- 111 Dynamics GP
- 10 Dynamics SL
- 1.5K Other
- 990 SQL General
- 383 SQL Performance
- 34 SQL Tips & Tricks
- 35 Design Patterns (General & Best Practices)
- 1 Architectural Patterns
- 10 Design Patterns
- 5 Implementation Patterns
- 53 3rd Party Products, Services & Events
- 1.6K General
- 1.1K General Chat
- 1.6K Website
- 83 Testing
- 1.2K Download section
- 23 How Tos section
- 252 Feedback
- 12 NAV TechDays 2013 Sessions
- 13 NAV TechDays 2012 Sessions