
“The truth is in fault” or try to program NanoCAD under Linux (MultiCAD.NET API)
Almost since the release of the first "capable" version of NanoCAD, among the user community, the question arose about the need to implement this CAD system under Linux. You
probably thought that this article was born because the developers finally "did it!". I hasten to reassure you - everything remains in their places . I still don’t know anything about the Linux version of NanoCAD. Therefore, we will try to use Wine.
So this short note will be not so much about using NanoCAD on Linux, but about programming for Nanocad on a system other than Windows, or more precisely, how I armed myself with Linux Mint, MonoDevelop and tried to build a library (.dll) for free version of NanoCAD usingMultiCAD.NET API.
If you are interested in what came of it, you are welcome to cut!

It seems that my new hobby will also eventually result in a mini-cycle of articles, and since we will refer to past developments, I will provide links to all previous articles under the spoiler.
In the beginning, just in case, I’ll clarify that I’m not a programmer, that I couldn’t be called a “confident Linux user”, and that I’m not connected with the developers of NanoCAD (CJSC Nanosoft) , so everything below this is my private and sometimes naive and unprofessional opinion. It will probably be appropriate to share the initial data with which I approached the solution of the problem:
Since there are so few people programming for NanoCAD, and among them there are so extreme and irresistible people who are ready to program for NanoCAD under Linix, I think that everything below will have no special practical value and can only be considered in order to satisfy the technical curiosity.
If after the previous paragraph you still continued to read this, then you have an excerpt like Chuck Norris , and this is worthy of respect. It is finally time to find out what awaits us in this article. Content:

It should be noted that developers, although they do not directly spend their resources on adapting to Linux, still sometimes worry about us. The impetus for the creation of this article was their post on Habré, which I accidentally stumbled upon - " Repost of the council: running nanoCAD free 3.5 / 3.7 under Linux using Wine" .
Of course, version 3.7 is already completely outdated, and I decided to try the more recent version of NanoCAD 5.1 , which is close to it .
If suddenly you are not at all familiar with Nanocad, then you can read the very first article in the series . In short, NanoCAD 5.1, although not an open source program, is still completely free for commercial use., personally, I think that if the developers made a sane adaptation for Linux, at least with the help of Wine, then thanks to the familiar interface and similarities with AutoCAD, in the functionality of the two-dimensional “electronic culman” it could well compete with the same FreeCAD and QCAD ( LibreCAD).
But for now, we will be content with what we have, and we have tips from the forum on how to run NanoCAD 5.1 under Wine 1.4 .
Unfortunately, I came across this material after I finally lost my enthusiasm, so if someone starts up normally after following this instruction, share in the comments.
And I will tell you what happened to me.
I also tried to install NanoCAD 8.5 under Wine, it, unlike NC 5.1, already requires NET Framework 4, and there are fewer problems with it, but then I got stuck on installing LocalDB prerequisite (apparently server components from MS). If someone can run, please share in the comments.
UPD (12.29.17):
As it turned out 32-bit version of NanoCAD 8.5 It is fully installed and even works! Even with the brakes.
It is only necessary to install Microsoft Visual C ++ Redistributable Package 2008 and 2012, as well as the .NET Framework 4.0.
If during the installation it will swear that it cannot find Visual C ++, then at the beginning click "OK", then "cancel" and continue the installation without them.
Having received a more or less efficient version of NanoCAD for testing our code, we’ll immediately try to check whether we can rebuild and run the previously written in C # and assembled library with a pseudo-three-dimensional door in Linux.
To build the project, I chose MonoDevelop (for Windows users, it may be familiar under the name Xamarin Studio).
I had never encountered it in its pure form (only as part of Unity) and was pleasantly surprised that it seems that everything we need in MonoDevelop is there.
We open the project already created earlier in MS Visual Studio and try to rebuild.
The full class code so that you do not have to look for anything in other articles, I will hide under the spoiler.

As you can see, the assembly was successful. Open NanoCAD, open the previously created .dwg file with a door and sheep (posted on GitHub ).

As you see, everything opens. And even an error warning intentionally included in the code made on the basis of Windows Forms opens correctly (although it looks crooked).

Since everything works, let's try and assemble something new and completely primitive, purely for educational purposes. But first, prepare yourself the tools.
In one of the articles I briefly described the process of creating a project for NanoCAD 5.1 in MS Visual Studio , in this I offer you the same brief instruction, only for MonoDevelop under Linux:
Since we all set up so well with you, let's write something. I decided to offer you a very simple code so that it starts without problems.
Under the spoiler is a code that draws us my "highly artistic vision" of a penguin. The class contains only the “Dping” command, which draws simple geometric objects and displays text.
UPD (12.29.17): The code is successfully compiled without any problems (well, maybe with small adjustments to the connected namespaces) for NC 8.5 if you connect the libraries from its SDK,but we won’t be able to test it on Linux, because as I said before NC 8.5 I didn’t “take off” at all under Wine . We can in the 32-bit version of NC 8.5.
By the way, our compiled library, then it will open without problems in the NC 5.1 version running directly under Windows (which is obvious in principle).
So, we transfer our library to the “C:” drive, open NanoCAD, enter the Netload command, select our library (I have ping.dll) and enjoy the sight.

As you can see under Wine 2.2, for unknown reasons, in the NanoCAD settings the options related to the purpose of the color are floundering (instead of the color value - a cross), I could not solve this problem. But the rest, the files seem to open, the print dialog works, simple objects are drawn, and I haven’t tested anymore.
Well, in order to make sure that everything is completely "cross-platform" with us, we will launch our library with a penguin in NC 5.1 for Windows.

UPD (12.29.17): As mentioned in the piece of the article added above, I managed to launch the x86 version of NanoCAD 8.5 under Wine, so catch the penguin from it.

To summarize: at first glance, it seems that directly programming in C # for NC 5.1 using the MultiCAD.NET API on Linux is quite possible, but testing your code is not so comfortable.
I understand almost nothing about all Linux-related issues, but it seems to me that it is technically possible to create a container, pack the correct version of Wine into it, install inactive NC 5.1 there, provide access to external disks in some way to the Wine container, and it will happiness to all.
Unfortunately, I myself will definitely not be able to do this for the foreseeable future, so I have to wait and hope for experienced and caring users or NanoCad developers.
But if suddenly one day I myself have something working out, I will definitely share this with you. All success and a good week!
probably thought that this article was born because the developers finally "did it!". I hasten to reassure you - everything remains in their places . I still don’t know anything about the Linux version of NanoCAD. Therefore, we will try to use Wine.
So this short note will be not so much about using NanoCAD on Linux, but about programming for Nanocad on a system other than Windows, or more precisely, how I armed myself with Linux Mint, MonoDevelop and tried to build a library (.dll) for free version of NanoCAD usingMultiCAD.NET API.
If you are interested in what came of it, you are welcome to cut!

Part I: ... gives no rest
It seems that my new hobby will also eventually result in a mini-cycle of articles, and since we will refer to past developments, I will provide links to all previous articles under the spoiler.
Other cycle articles
In the beginning, just in case, I’ll clarify that I’m not a programmer, that I couldn’t be called a “confident Linux user”, and that I’m not connected with the developers of NanoCAD (CJSC Nanosoft) , so everything below this is my private and sometimes naive and unprofessional opinion. It will probably be appropriate to share the initial data with which I approached the solution of the problem:
- OS - Linux Mint 18.3 "Sylvia" - Cinnamon (64-bit)
- Wine - PlayOnLinux (Wine 2.2)
- IDE - MonoDevelp 7.1 (Mono 5.2.0)
- Hands - “from the priests” (and great curiosity)
Since there are so few people programming for NanoCAD, and among them there are so extreme and irresistible people who are ready to program for NanoCAD under Linix, I think that everything below will have no special practical value and can only be considered in order to satisfy the technical curiosity.
If after the previous paragraph you still continued to read this, then you have an excerpt like Chuck Norris , and this is worthy of respect. It is finally time to find out what awaits us in this article. Content:

- Part I: ... gives no rest
- Part II: trying to start using Wine
- Part III: building a project in MonoDevelop
- Part IV: The Birth of the Penguin
Part II: trying to start using Wine
It should be noted that developers, although they do not directly spend their resources on adapting to Linux, still sometimes worry about us. The impetus for the creation of this article was their post on Habré, which I accidentally stumbled upon - " Repost of the council: running nanoCAD free 3.5 / 3.7 under Linux using Wine" .
Of course, version 3.7 is already completely outdated, and I decided to try the more recent version of NanoCAD 5.1 , which is close to it .
If suddenly you are not at all familiar with Nanocad, then you can read the very first article in the series . In short, NanoCAD 5.1, although not an open source program, is still completely free for commercial use., personally, I think that if the developers made a sane adaptation for Linux, at least with the help of Wine, then thanks to the familiar interface and similarities with AutoCAD, in the functionality of the two-dimensional “electronic culman” it could well compete with the same FreeCAD and QCAD ( LibreCAD).
But for now, we will be content with what we have, and we have tips from the forum on how to run NanoCAD 5.1 under Wine 1.4 .
Unfortunately, I came across this material after I finally lost my enthusiasm, so if someone starts up normally after following this instruction, share in the comments.
And I will tell you what happened to me.
- I started by installing Wine from the Mint distribution, and there was version 1.6, in the end it turned out, as mentioned in the two tips above from the articles. Incorrect icon colors and problems with some buttons. Actually, as it turned out, this could and will stop, because I did not achieve a much better result, but in the end I decided to put PlayOnLinux and continue to “revive Frankenstein”.
- To start, I tried version 1.4.1, in which everything should work, and I suspect that it would really work fine, but there is one problem - I could not install the .NET Framework 3.5 (and the .NET Framework 3 too ) I tried a bunch of everything, but as a rule, during the installation process in some places always some kind of error crashed.
NET Framework 2 is the last version that it was possible to install (the 4th version does not count), with this version of the NanoCAD framework, it even starts to load, and if you are lucky it will load most of it. Only libraries that are primarily associated with the API (which does not suit us) will not work.
The screenshot shows that you can draw and that all colors are displayed correctly, but unfortunately the Netload command does not work, which means that our library will not be loaded in the future, so go ahead. - Then I tried a bunch of versions of Wine for PlayOnLinux: 1.3.X, 1.5.X, 2.1, even WINE @ Etersoft tried it, there were installation problems everywhere. NET Framework 3.5.
- As a result, I settled on the latest version of Wine available to me in PlayOnLinux - 2.2, under it, by some miracle. NET Framework stood up, NanoCAD started completely, though there are still problems with colors. Screenshots of how it looks will be a little later.
- Another required prerequisite of Microsoft Visual C ++ 2008 SP1 Redistributable Package (x86) is almost always installed without problems (you can directly go with the program). Also, do not forget to install the development kit (SDK)
during the installation of NanoCAD. Sometimes the registration wizard jams during installation. I have had cases when direct on-line registration failed, then you can take the license file from an already installed version, for example, under full Windows (in the ProgramData \ Nanosoft \ RegWizard \ Licenses folder) and feed it to the license wizard.
I also tried to install NanoCAD 8.5 under Wine, it, unlike NC 5.1, already requires NET Framework 4, and there are fewer problems with it, but then I got stuck on installing LocalDB prerequisite (apparently server components from MS). If someone can run, please share in the comments.
UPD (12.29.17):
As it turned out 32-bit version of NanoCAD 8.5 It is fully installed and even works! Even with the brakes.
It is only necessary to install Microsoft Visual C ++ Redistributable Package 2008 and 2012, as well as the .NET Framework 4.0.
If during the installation it will swear that it cannot find Visual C ++, then at the beginning click "OK", then "cancel" and continue the installation without them.
Part III: building a project in MonoDevelop
Having received a more or less efficient version of NanoCAD for testing our code, we’ll immediately try to check whether we can rebuild and run the previously written in C # and assembled library with a pseudo-three-dimensional door in Linux.
To build the project, I chose MonoDevelop (for Windows users, it may be familiar under the name Xamarin Studio).
I had never encountered it in its pure form (only as part of Unity) and was pleasantly surprised that it seems that everything we need in MonoDevelop is there.
We open the project already created earlier in MS Visual Studio and try to rebuild.
The full class code so that you do not have to look for anything in other articles, I will hide under the spoiler.
Complete code for the door under NC 5.1
// Version 1.1 //Use Microsoft .NET Framework 3.5 and old version of MultiCad.NET (for NC 5.1) //Class for demonstrating the capabilities of MultiCad.NET //Assembly for the Nanocad 5.1 //Link mapimgd.dll from Nanocad SDK //Link System.Windows.Forms and System.Drawing //upd: for version 1.1 also link .NET API: hostdbmg.dll, hostmgd.dll //The commands: draws a pseudo 3D door. //This code in the part of non-infringing rights Nanosoft can be used and distributed in any accessible ways. //For the consequences of the code application, the developer is not responsible. // V 1.0. More detailed - https://habrahabr.ru/post/342680/ // V 1.1. More detailed - https://habrahabr.ru/post/343772/ // P.S. A big thanks to Alexander Vologodsky for help in developing a method for pivoting object. using System; using System.ComponentModel; using System.Windows.Forms; using Multicad.Runtime; using Multicad.DatabaseServices; using Multicad.Geometry; using Multicad.CustomObjectBase; using Multicad; //added in V 1.1. for monitoring using System.Security.Permissions; using System.IO; using Multicad.AplicationServices; using HostMgd.ApplicationServices; using HostMgd.EditorInput; namespace nanodoor2 { //change "8b0986c0-4163-42a4-b005-187111b499d7" for your Guid from Assembly. // Be careful GUID for door and wall classes must be different! // Otherwise there will be problems with saving and moving [CustomEntity(typeof(DoorPseudo3D_nc51), "b4edac1f-7978-483f-91b1-10503d20735b", "DoorPseudo3D_nc51", "DoorPseudo3D_nc51 Sample Entity")] [Serializable] public class DoorPseudo3D_nc51 : McCustomBase { // First and second vertices of the box private Point3d _pnt1 = new Point3d(0, 0, 0); private double _scale = 1000; private double _h = 2085; private Vector3d _vecStraightDirection = new Vector3d(1, 0, 0); private Vector3d _vecDirectionClosed = new Vector3d(1, 0, 0); public enum Status {closed , middle, open}; private Status _dStatus = Status.closed; //added in V 1.1. (monitor fileds) public enum Mon { off, on}; private Mon _monitor = Mon.off; private string _monFilePath = @"E:\test.txt"; // if it is serialized, you may not be able to copy the object in the CAD editor [NonSerialized] private FileSystemWatcher _watcher; [NonSerialized] private FileSystemEventHandler _watchHandler; [CommandMethod("DrawDoor", CommandFlags.NoCheck | CommandFlags.NoPrefix)] public void DrawDoor() { DoorPseudo3D_nc51 door = new DoorPseudo3D_nc51(); door.PlaceObject(); this.TryModify(); // this.Monitor = false; } public override void OnDraw(GeometryBuilder dc) { dc.Clear(); // Define the basic points for drawing Point3d pnt1 = new Point3d(0, 0, 0); Point3d pnt2 = new Point3d(pnt1.X + (984 * _scale), pnt1.Y, 0); Point3d pnt3 = new Point3d(pnt2.X + 0, pnt1.Y+(50 * _scale), 0); Point3d pnt4 = new Point3d(pnt1.X , pnt3.Y, 0) ; // Set the color to ByObject value dc.Color = McDbEntity.ByObject; Vector3d hvec = new Vector3d(0, 0, _h * _scale) ; // Draw the upper and lower sides dc.DrawPolyline(new Point3d[] { pnt1, pnt2, pnt3, pnt4, pnt1 }); dc.DrawPolyline(new Point3d[] { pnt1.Add(hvec), pnt2.Add(hvec), pnt3.Add(hvec), pnt4.Add(hvec), pnt1.Add(hvec)}); // Draw the edges dc.DrawLine(pnt1, pnt1.Add(hvec)); dc.DrawLine(pnt2, pnt2.Add(hvec)); dc.DrawLine(pnt3, pnt3.Add(hvec)); dc.DrawLine(pnt4, pnt4.Add(hvec)); // Drawing a Door Handle dc.DrawLine(pnt2.Add(new Vector3d( -190 * _scale, -0, _h*0.45 * _scale)), pnt2.Add(new Vector3d(-100 * _scale, 0, _h * 0.45 * _scale))); dc.DrawLine(pnt3.Add(new Vector3d(-190 * _scale, 0, _h * 0.45 * _scale)), pnt3.Add(new Vector3d(-100 * _scale, 0, _h * 0.45 * _scale))); } public override hresult PlaceObject(PlaceFlags lInsertType) { InputJig jig = new InputJig(); // Get the first box point from the jig InputResult res = jig.GetPoint("Select first point:"); if (res.Result != InputResult.ResultCode.Normal) return hresult.e_Fail; _pnt1 = res.Point; Stat = Status.closed; // Add the object to the database DbEntity.AddToCurrentDocument(); // added in v.1. return hresult.s_Ok; } ///
/// Method for changing the object's SC (the graph is built at the origin of coordinates). /// /// The matrix for changing the position of the object. ///
True - if the matrix is passed, False - if not. public override bool GetECS(out Matrix3d tfm) { // Create a matrix that transforms the object. // The object is drawn in coordinates(0.0), then it is transformed with the help of this matrix. tfm = Matrix3d.Displacement(this._pnt1.GetAsVector()) * Matrix3d.Rotation (-this._vecStraightDirection.GetAngleTo(Vector3d.XAxis, Vector3d.ZAxis), Vector3d.ZAxis, Point3d.Origin); return true; } public override void OnTransform(Matrix3d tfm) { // To be able to cancel(Undo) McUndoPoint undo = new McUndoPoint(); undo.Start(); // Get the coordinates of the base point and the rotation vector this.TryModify(); this._pnt1 = this._pnt1.TransformBy(tfm); this.TryModify(); this._vecStraightDirection = this._vecStraightDirection.TransformBy(tfm); // We move the door only when it is closed if not - undo if (_dStatus == Status.closed) _vecDirectionClosed = _vecStraightDirection; else { MessageBox.Show("Please transform only closed door (when its status = 0)"); undo.Undo(); } undo.Stop(); } //Define the custom properties of the object [DisplayName("Height")] [Description("Height of door")] [Category("Door options")] public double HDoor { get { return _h; } set { //Save Undo state and set the object status to "Changed" if (!TryModify()) return; _h = value; } } [DisplayName("DScale")] [Description("Door Scale")] [Category("Door options")] public double DScale { get { return _scale; } set { if (!TryModify()) return; _scale = value; } } [DisplayName("Door status")] [Description("0-closed, 1-midle, 2-open")] [Category("Door options")] public Status Stat { get { return _dStatus; } set { //Save Undo state and set the object status to "Changed" if (!TryModify()) return; // Change the rotation vector for each of the door states switch (value) { case Status.closed: _vecStraightDirection = _vecDirectionClosed; break; case Status.middle: _vecStraightDirection = _vecDirectionClosed.Add(_vecDirectionClosed.GetPerpendicularVector().Negate() * 0.575) ; break; case Status.open: _vecStraightDirection = _vecDirectionClosed.GetPerpendicularVector()*-1; break; default: break; } _dStatus = value; } } // Create a grip for the base point of the object public override bool GetGripPoints(GripPointsInfo info) { info.AppendGrip(new McSmartGrip (_pnt1, (obj, g, offset) => { obj.TryModify(); obj._pnt1 += offset; })); return true; } //Define the monitoring custom properties , added v. 1.1: // added in v. 1.1 [DisplayName("Monitoring")] [Description("Monitoring of file for door")] [Category("Monitoring")] public Mon Monitor { get { return _monitor; } set { //Save Undo state and set the object status to "Changed" if (!TryModify()) return; _monitor = value; if (_monitor==Mon.on) { StartMonitoring(); } else StopMonitoring(); } } // added in v. 1.1 [DisplayName("File path for Monitoring")] [Description("Monitoring of file for door")] [Category("Monitoring")] public string MonitoringFilPath { get { return _monFilePath; } set { // Get the command line editor DocumentCollection dm = HostMgd.ApplicationServices.Application.DocumentManager; Editor ed = dm.MdiActiveDocument.Editor; //for hot change filename if (Monitor==Mon.on) { StopMonitoring(); if (!TryModify()) return; _monFilePath = value; StartMonitoring(); ed.WriteMessage("Monitored file is changed"); } else { //Save Undo state and set the object status to "Changed" if (!TryModify()) return; _monFilePath = value; } } } //Define the methods, added v. 1.1: // added in v. 1.1 [PermissionSet(SecurityAction.Demand, Name = "FullTrust")] public void StartMonitoring() { DocumentCollection dm = HostMgd.ApplicationServices.Application.DocumentManager; Editor ed = dm.MdiActiveDocument.Editor; _watcher = new FileSystemWatcher(); if (File.Exists(_monFilePath)) { _watcher.Path = Path.GetDirectoryName(_monFilePath); _watcher.Filter = Path.GetFileName(_monFilePath); _watchHandler = new FileSystemEventHandler(OnChanged); _watcher.Changed += _watchHandler; _watcher.EnableRaisingEvents = true; } else ed.WriteMessage("File: " + _monFilePath + " " + "not Exists"); } // added in v. 1.1 public void StopMonitoring() { if (_watcher != null & _watchHandler != null) { _watcher.Changed -= _watchHandler; _watcher.EnableRaisingEvents = false; } } // added in v. 1.1 private void OnChanged(object source, FileSystemEventArgs e) { DocumentCollection dm = HostMgd.ApplicationServices.Application.DocumentManager; Editor ed = dm.MdiActiveDocument.Editor; ed.WriteMessage("File: " + e.FullPath + " " + e.ChangeType); //read new value from file try { if (File.Exists(_monFilePath)) { int mStatus = -1; ed.WriteMessage("File exists "); using (StreamReader sr = new StreamReader(new FileStream(_monFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) { if (sr.BaseStream.CanRead) { if (int.TryParse(sr.ReadLine(), out mStatus)) { if (Enum.IsDefined(typeof(Status), mStatus)) { if (!TryModify()) return; Stat = (Status)mStatus; // преобразование if (!TryModify()) return; DbEntity.Update(); McContext.ExecuteCommand("REGENALL"); ed.WriteMessage("Door state is changed"); } else ed.WriteMessage("Incorrect data in the file. Should be in diapason: 0, 1, 2 "); } } else ed.WriteMessage("Can't read file "); } } else ed.WriteMessage("File not exists "); _watcher.EnableRaisingEvents = false; // disable tracking } finally { _watcher.EnableRaisingEvents = true; // reconnect tracking } } } // TODO: There are many shortcomings in this code. // Including failures when working with copying, moving objects and saving files, you can improve it if you want. }

As you can see, the assembly was successful. Open NanoCAD, open the previously created .dwg file with a door and sheep (posted on GitHub ).

As you see, everything opens. And even an error warning intentionally included in the code made on the basis of Windows Forms opens correctly (although it looks crooked).

Since everything works, let's try and assemble something new and completely primitive, purely for educational purposes. But first, prepare yourself the tools.
In one of the articles I briefly described the process of creating a project for NanoCAD 5.1 in MS Visual Studio , in this I offer you the same brief instruction, only for MonoDevelop under Linux:
- Open the IDE and select the menu item Create a new solution (project) from the File menu.
- In the new window, select the type - C # class library
- Give him some name.
- We will connect the MultiCAD.NET libraries, we need to look for them in the Mint folder, in which the virtual disk of our Wine system is organized. The SDK is usually placed in the same folder as NanoCAD, the plug-in libraries are in the include folder. For this project, only mapimgd.dll is enough for us.
- Be sure to uncheck the option "copy locally."
- Then, by right-clicking on the project name in the object inspector, select the options item and set the .NET Framework 3.5 as the final platform, as in the picture.
- Then you can write code and build code with the Build (F8) command. Next, find our library in the debug folder of the project and copy it to the “C” virtual disk or to any other place where Wine has access, it is important that NanoCAD can see your .dll through its file open dialog.
Part IV: The Birth of the Penguin
Since we all set up so well with you, let's write something. I decided to offer you a very simple code so that it starts without problems.
Under the spoiler is a code that draws us my "highly artistic vision" of a penguin. The class contains only the “Dping” command, which draws simple geometric objects and displays text.
Full code for NC 5.1 in C #
using System.Collections.Generic;
using Multicad.Runtime;
using Multicad.DatabaseServices;
using Multicad.Geometry;
using Multicad.DatabaseServices.StandardObjects;
namespace nano
{
class penguin
{
[CommandMethod("DPing", CommandFlags.NoCheck | CommandFlags.NoPrefix)]
public void DrawFace()
{
DbCircle body = new DbCircle();
body.Center = new Point3d(200, 200, 0);
body.Radius = 105;
body.DbEntity.AddToCurrentDocument();
DbCircle eye1 = new DbCircle();
eye1.Center = new Point3d(150, 255, 0);
eye1.Radius = 8;
eye1.DbEntity.AddToCurrentDocument();
DbCircle pupil1 = new DbCircle();
pupil1.Center = new Point3d(148, 254, 0);
pupil1.Radius = 2;
pupil1.DbEntity.AddToCurrentDocument();
DbCircle eye2 = new DbCircle();
eye2.Center = new Point3d(250, 260, 0);
eye2.Radius = 8;
eye2.DbEntity.AddToCurrentDocument();
DbCircle pupil2 = new DbCircle();
pupil2.Center = new Point3d(252, 258, 0);
pupil2.Radius = 2;
pupil2.DbEntity.AddToCurrentDocument();
DbLine hand1 = new DbLine();
hand1.StartPoint = new Point3d(102, 239, 0);
hand1.EndPoint = new Point3d(72, 183, 0);
hand1.DbEntity.AddToCurrentDocument();
DbLine hand2 = new DbLine();
hand2.StartPoint = new Point3d(298, 236, 0);
hand2.EndPoint = new Point3d(325, 192, 0);
hand2.DbEntity.AddToCurrentDocument();
DbPolyline nose = new DbPolyline();
List nosePoints = new List() {
new Point3d(171, 222, 0), new Point3d(198, 177, 0), new Point3d(231, 222, 0) };
nose.Polyline = new Polyline3d(nosePoints);
nose.Polyline.SetClosed(false);
nose.DbEntity.Transform(McDocumentsManager.GetActiveDoc().UCS); //change coordinates from UCS to WCS for BD
nose.DbEntity.AddToCurrentDocument();
DbText spech = new DbText();
spech.Text = new TextGeom("Hello Habr!", new Point3d(310, 55, 0), Vector3d.XAxis, "Standard", 25);
spech.DbEntity.AddToCurrentDocument();
}
}
}
UPD (12.29.17): The code is successfully compiled without any problems (well, maybe with small adjustments to the connected namespaces) for NC 8.5 if you connect the libraries from its SDK,
By the way, our compiled library, then it will open without problems in the NC 5.1 version running directly under Windows (which is obvious in principle).
So, we transfer our library to the “C:” drive, open NanoCAD, enter the Netload command, select our library (I have ping.dll) and enjoy the sight.

As you can see under Wine 2.2, for unknown reasons, in the NanoCAD settings the options related to the purpose of the color are floundering (instead of the color value - a cross), I could not solve this problem. But the rest, the files seem to open, the print dialog works, simple objects are drawn, and I haven’t tested anymore.
Well, in order to make sure that everything is completely "cross-platform" with us, we will launch our library with a penguin in NC 5.1 for Windows.

UPD (12.29.17): As mentioned in the piece of the article added above, I managed to launch the x86 version of NanoCAD 8.5 under Wine, so catch the penguin from it.

To summarize: at first glance, it seems that directly programming in C # for NC 5.1 using the MultiCAD.NET API on Linux is quite possible, but testing your code is not so comfortable.
I understand almost nothing about all Linux-related issues, but it seems to me that it is technically possible to create a container, pack the correct version of Wine into it, install inactive NC 5.1 there, provide access to external disks in some way to the Wine container, and it will happiness to all.
Unfortunately, I myself will definitely not be able to do this for the foreseeable future, so I have to wait and hope for experienced and caring users or NanoCad developers.
But if suddenly one day I myself have something working out, I will definitely share this with you. All success and a good week!