...
- Selecting C# as the language, create a new project of type Class Library. Ensure that the selected project type targets .NET or .NET Standard, not .NET Framework.
2. For convenience, set your project name to the desired name of your plugin. For this example, we will use the name CSiNET8PluginExample1
3. Select .NET 8.0 as the desired Framework
4. Once your project is created, add a reference to the CSI API library. This will be located in the installed program directory, e.g. C:\Program Files\Computers and Structures\ETABS 22\ .
...
5. Almost all plugins will depend on other (, non-CSI ) libraries to execute complicated functionality. To simulate demonstrate the correct management of these dependenciesdependent libraries, this plugin makes trivial use of the popular Newtonsoft.Json serialization/deserialization library. It is freely available on GitHub and can be added to your project using the NuGet package manager within Visual Studio.
5. Some manual edits must be made to the project file in order for the plugin to run successfully. Open the project file (in our example, CSiNET8PluginExample1.csproj ) in a text editor, and make the following edits:
- Change the <TargetFramework> from net8.0 to net8.0-windows . This is necessary to allow our plugin to open a Windows form (Note: this plugin has only been tested to work on the Windows platform)
- Add the <UseWindowsForms>true</UseWindowsForms> attribute to the <PropertyGroup> . This will allow us to add a Windows form to our class library.
- Add the <EnableDynamicLoading>true</EnableDynamicLoading> attribute to the <PropertyGroup> . This will allow the CSI product to load our project as a plugin.
- Add the
...
| language | xml |
|---|
...
After the above changes, your project file should look approximately as shown below on the right. It's ok if doesn't match exactly.
Before:
| After:
|
|---|
...
6. With the modifications to the project file, you should be able to add a new Windows Form to your project. Name the form Form1 .
7. Edit the form using the Windows Forms Designer. The exact layout of the plugin form is not important, but for the copy and paste code in the steps below to operate correctly, the form must be named Form1, and must contain a Button control named button1 and RichTextBox control named richTextBox1 richTextBox1 .
8. Open the Form1.cs file and paste in the following code
...
| Code Block | ||
|---|---|---|
| ||
using CSiAPIv1; using Newtonsoft.Json; namespace CSiNET8PluginExample1 { public partial class Form1 : Form { protected cSapModel _sapModel; protected cPluginCallback _pluginCallback; public Form1() { InitializeComponent(); FormClosing += Form1_FormClosing; } public void SetSapModel(ref cSapModel inSapModel, ref cPluginCallback inPluginCallback) { _sapModel = inSapModel; _pluginCallback = inPluginCallback; richTextBox1.Text = "Hello CSI Friends"; } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { // It is very important to call _pluginCallback.Finish(0) when the form closes, !!! // otherwise, the CSI program will wait and be hung !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! _pluginCallback.Finish(0); } private void button1_Click(object sender, EventArgs e) { try { CreateStructure(richTextBox1.Text// Exercise some simple Newtonsoft.Json functionality string jsonText = JsonConvert.SerializeObject(richTextBox1.Text); string deserializedText = JsonConvert.DeserializeObject<string>(jsonText); //MessageBox.Show(richTextBox1.Text + " == " + deserializedText + " : " + (richTextBox1.Text == deserializedText)); CreateStructure(deserializedText); } catch (Exception ex) { MessageBox.Show("The following error terminated the Plugin:" + Environment.NewLine + ex.Message); } finally { this.Close(); } } public void CreateStructure(string text) { int CallResult; int i; string FrameName = "FrameName"; var aVectorFont = new cVectorFont(); double CharHeight = 200.0; var HAlignment = cVectorFont.TextAlignment.kTA_HLeft; var VAlignment = cVectorFont.TextAlignment.kTA_VTop; double[] textX = new double[1], textY = new double[1]; int NumPts; // test for exception handling if (string.Equals(text, "crash", StringComparison.InvariantCultureIgnoreCase)) { textX[99] = 0; // out of bounds } aVectorFont.FillTextVertices(text.ToUpper(), CharHeight, HAlignment, VAlignment, ref textX, ref textY); NumPts = textX.Length; CallResult = _sapModel.InitializeNewModel(); CallResult = _sapModel.File.NewBlank(); for (i = 0; i < NumPts - 2; i++) { FrameName = "FrameName" + (i / 2).ToString(); CallResult = _sapModel.FrameObj.AddByCoord(textX[i], textY[i], 0, textX[i + 1], textY[i + 1], 0, ref FrameName); i++; } _sapModel.View.RefreshView(0, false); } } } |
...


