.NET COMPONENT DEVELOPMENT GUIDE PIPELINE PILOT INTEGRATION COLLECTION 2017 Copyright Notice

©2016 Dassault Systèmes. All rights reserved. 3DEXPERIENCE, the Compass icon and the 3DS logo, CATIA, SOLIDWORKS, ENOVIA, DELMIA, , GEOVIA, , 3D VIA, BIOVIA and are commercial trademarks or registered trademarks of Dassault Systèmes or its subsidiaries in the U.S. and/or other countries. All other trademarks are owned by their respective owners. Use of any Dassault Systèmes or its subsidiaries trademarks is subject to their express written approval.

Acknowledgments and References

To print photographs or files of computational results (figures and/or data) obtained using BIOVIA software, acknowledge the source in an appropriate format. For example: "Computational results obtained using software programs from Dassault Systèmes BIOVIA. The ab initio calculations were performed with the DMol3 program, and graphical displays generated with Pipeline Pilot."

BIOVIA may grant permission to republish or reprint its copyrighted materials. Requests should be submitted to BIOVIA Support, either through electronic mail to [email protected], or in writing to:

BIOVIA Support 5005 Wateridge Vista Drive, San Diego, CA 92121 USA Contents

Chapter 1: Introduction 1 About .NET Component Development 1 Who Should Read this Guide 1 Requirements 1 Getting Started with .NET Component Development 1 .NET Component API 2 Component Interface 2 Additional Information 2 Chapter 2: .NET Integration Components and Examples 3 Dynamic .NET (on Server) Component 3 Dynamic C# (on Server) and Dynamic VB.NET (on Server) Components 3 Dynamic C# Example 3 .NET (on Server) Component 6 Packaging for the .NET (on Server) component 7 Activating the Package 7 .NET Example, Visual Studio 2008 7 .NET Example, Visual C# 2010 Express 8 Configuring the component in Pipeline Pilot Client 8 Debugging your assembly in Visual Studio 2008 9 Chapter 3: Key Interfaces 11 .NET Component API Reference 11 Appendix A: Running .NET Components without Internet Access 12 Chapter 1: Introduction About .NET Component Development The Integration collection includes tools for developing components using any language supported by the Microsoft .NET Framework, such as C# or VB.NET. Who Should Read this Guide This guide provides steps for creating a new component using the .NET API, including the necessary architectural background and technical instructions for creating, testing, and deploying your customized .NET components. Requirements In the development and deployment process, a given computer can play one or more of the following roles: Client, Server, and Development. Client Server Development Non- Pipeline Pipeline Pilot Microsoft Visual Studio: 2008, 2010, 2010 Express dynamic Pilot Client Server installation See: http://www.visualstudio.com/en- .NET installation .NET Framework US/products/visual-studio-express-vs runtime version Access to the server machine for uploading the 2.0 or later* developed assembly if the Development and Server machines are not one and the same. Dynamic Pipeline Pipeline Pilot Any development is done on the client machine .NET Pilot Client Server installation installation Note: If the server lacks an appropriate version of the *.NET Framework .NET Framework runtime, this error message is runtime version displayed: 2.0 or later "Failure to initialize the .NET Framework runtime. Please ensure the .NET Framework runtime [version_ number] is installed."

Getting Started with .NET Component Development The tools available for developing components for the .NET platform include: Examples that demonstrate how to design .NET components that access the Pipeline Pilot data model to carry out a variety of tasks. See Chapter 2: .NET Integration Components and Examples. .NET-based components, which are listed in Chapter 2: .NET Integration Components and Examples. The .NET Component API reference in the Pipeline Pilot Help Center. Microsoft Visual Studio (or equivalent), including the .NET Framework and accompanying documentation.

Introduction | Page 1 .NET Component API The .NET Component API provides a convenient way to access and modify the data structures, including the data records that flow through the components, the various parameter settings, and the global properties of the enclosing protocol. The API is implemented in an object-oriented fashion that reflects the natural syntax and features of the .NET programming languages. For the .NET API definition, see Microsoft's published API References for C# and VB.NET (or any other .NET language). Component Interface The IComponent interface, which resides in the com.scitegic.pilot namespace, allows your .NET components to be used in a protocol. Your .NET component must implement all three methods of the IComponent interface: OnInitialize: Executed once before processing the first data record. Even a component that receives no input will have this method called exactly one time. OnProcess: Executed for each data record passed as input or generated by the component. OnFinalize: Executed after processing the last data record. Note: This document assumes you are familiar with Component Lifetime Management, explained in the Protocol Development Quick Start Guide.

Additional Information For more information about the Pipeline Pilot Integration collection and other BIOVIA software products, visit https://community.3dsbiovia.com.

Page 2 | Pipeline Pilot • .NET Component Development Guide Chapter 2: .NET Integration Components and Examples

The following components can be used for integrating third-party applications using a .NET solution: Dynamic .NET (on Server) Dynamic C# (on Server) and Dynamic VB.NET (on Server) .NET (on Server) Note: These components are currently only available on Windows and require that the server has Microsoft .NET Framework version 2.0 or later.

Dynamic .NET (on Server) Component Dynamic .NET (on Server) allows for the dynamic execution of source code of any .NET language (such as C# and VB.NET), with the assumption that the appropriate .NET compiler is installed on the server. It performs an on-the-fly compilation of the source code, generating a binary assembly, which is passed internally to the .NET (on Server) component for execution. The main advantage of a dynamic component is its ease of use for setup and simple coding tasks, such as examples and rapid prototyping. A use case is integrating the existing functionality of an assembly into Pipeline Pilot. Additional Parameters: Parameter Description Source The source code to compile in the .NET language specified by the Language parameter. Language The .NET language of the source code, such as C# or VB. .NET Compiler 2.0 Version 3.0 3.5 4.0

Dynamic C# (on Server) and Dynamic VB.NET (on Server) Components Dynamic C# (on Server) and Dynamic VB.NET (on Server) are specialized versions of the Dynamic .NET (on Server) component that provide boilerplate code you can run as is, using default parameters. Note: The default code, which is specified by the Source parameter, is template code for your custom functionality.

Dynamic C# Example The following example shows how to use the Dynamic C# (on Server) component. To create a protocol that uses a component written in C#:

.NET Integration Components and Examples | Page 3 1. Open the Pipeline Pilot Client and create a new protocol. (It will match the Protocol named Hello World using Dynamic C#) 2. Add a Generate Empty Data component. If you change the C# component code to create data records, you do not need this component. 3. Add a Dynamic C# (on Server) component and connect it to the Pass port on Generate Empty Data. 4. Add a Data Record Tree Viewer component and connect it to the Pass port on Dynamic C# (on Server). 5. In the Dynamic C# (on Server) component, set the .NET Class parameter to HelloWorld. 6. Edit the Source parameter by pasting in the following code: using System;

using com.scitegic.pilot;

public class HelloWorld : IComponent { private String m_name;

public State OnInitialize(IContext context) { // Retrieve component parameters. IPropertyCollection parameters = context.GetComponentParameters (); IProperty property = parameters.FindByName(@"Name"); // If the property 'Name' is specified, we will use its value, otherwise // we will just use a hard-coded string. if (property != null) m_name = property.GetValue().GetString(); else m_name = @"HelloWorld";

// Request to process any input data records. // Note: For information on choosing the right return value for the specific // component purpose, see the 'Protocol Development Quick Start Guide' // document, 'Component Lifetime Management' section. return State.ReadyForInputData; }

public State OnProcess(IContext context, IDataRecord data) { // Create a property on the data record. INode node = data.GetRoot(); node.GetProperties().Define(@"Hello World").SetValue(@"From " + m_name);

// Ready to process any additional input data records. // Note: For information on choosing the right return value for the specific // component purpose, see the 'Protocol Development Quick Start

Page 4 | Pipeline Pilot • .NET Component Development Guide Guide' // document, 'Component Lifetime Management' section. return State.ReadyForInputData; }

public void OnFinalize(IContext context) { // Nothing to do in this case. } } 7. Run the protocol. The result is:

8. To close the Data Record Tree Viewer dialog, click either Hide or Show Next. 9. Add a String parameter Name to the C# component: a. Right-click the C# component and select Edit. b. Click Add Parameter . c. In the Define Parameter dialog, assign the name of Name, then open the drop-down list, select StringType, and click OK. d. In Compiler Parameters, set the Name to Fred Flintstone.

10. Run the protocol. The result is:

11. To close the Data Record Tree Viewer dialog, click either Hide or Show Next.

.NET Integration Components and Examples | Page 5 .NET (on Server) Component .NET (on Server) is very similar to the other components for Programmatic Integration, such as Java (on Server) and Perl (on Server), and the programmatic API is very similar to the API provided for Java components. This component takes as input an already-compiled .NET assembly that is located on the server. A typical deployment scenario uses this component as opposed to a dynamic .NET component. Advantages of this approach include better performance, ease of maintenance, code obfuscation, and being able to make full use of a rich development environment, such as Microsoft Visual Studio. In contrast, dynamic components are less complex for initial setup. Note: This option is recommended because it allows mixing of various versions without the component being aware of which version is installed on the server.

Parameter Description .NET Class The fully-scoped name of the class specified by the code in the Source parameter that implements the component. The class must implement the IComponent interface, which is in the com.scitegic.pilot namespace, and implement these three interface methods: public State OnInitialize(IContext context); public State OnProcess(IContext context, IDataRecord data); public void OnFinalize(IContext context);

.NET Framework The value specifies the target .NET Framework version and can be any of the Version following: 2.0 3.0 3.5 4.0 Latest Available or Already Loaded Note: This option is recommended because it allows mixing of various versions without the component being aware of which version is installed on the server.

IMPORTANT! Visual Studio 2008 targets the 3.5 Framework by default, whereas Visual Studio 2010 (including the Express version) targets the 4.0 Framework by default. To debug using Visual Studio 2008 if you have the 4.0 framework installed, explicitly set this parameter to 3.5 or earlier.

Use Packages The name of any packages that contain assemblies that this component depends on. (See the section below.) Paths The explicit paths to any assemblies that this component depends on.

Page 6 | Pipeline Pilot • .NET Component Development Guide Packaging for the .NET (on Server) component We recommend packaging because it makes deployment more convenient and robust. With packaging, the user does not have to specify the path to the assembly. Instead, the user indicates the name of the package (by specifying the Use Package parameter), which in turn can contain multiple assemblies and multiple related components. 1. In Visual Studio, set up a project post-build step to automatically copy the assembly (Project > Properties > Build Events > Edit Post-build) to the "apps//bin//" directory on the Pipeline Pilot server, where is win64 or win32, depending on the build configuration. By including the platform type in the path, you can include both 32- and 64-bit versions of the assembly in the package. 2. In the package holding the assembly, edit and add the following directives to ensure that your assembly is copied from your package into the bin folder when the package is activated and then removed again when the package is deactivated. Please note that the copy command should all be on one long line. copy -sources "$(package)\bin\$(platform)\*.dll" -destdir "$(sciroot) \bin" –copylist "$(package)\logs\installedfiles.txt" delete -filelist "$(package)/logs/installedfiles.txt" 3. Also add to the "package.conf" file an entry similar to the following (substituting your assembly dll file name). The ASSEMBLY lines reference the .NET library copied into the bin folder by the commands added in the step above. ASSEMBLY $(sciroot)/bin/HelloWorld.dll ASSEMBLY $(sciroot)/bin/.dll 4. Your named component implements the IComponent interface. Specify its class name in the Use Package parameter in the .NET (on Server) component(s). Activating the Package 1. In a command prompt window, change directories to "/bin". 2. Use pkgutil on the command line to activate the package (such as "your_ company/coolstuff"): pkgutil -i your_company/coolstuff

Note: For details on the pkgutil command, see the Application Packaging Guide.

.NET Example, Visual Studio 2008 The following example shows how to implement a component in C# using Visual Studio 2008 and configure it for use with Pipeline Pilot. To generate a .NET assembly and configure it for use with the .NET (on Server) component: 1. In Visual Studio 2008, select File > New > Project > Other Language > Visual C# > Class Library, and enter the name and path for the project.

.NET Integration Components and Examples | Page 7 2. Select Project > Add Reference > Browse, and browse to the "com.scitegic.pilot.dll" file in the installation bin directory, such as "C:\Program Files\BIOVIA\PPS\bin". 3. To get a starting set of source code, replace the default source code provided by Visual Studio with a copy of the boilerplate code from the Source parameter of the Dynamic C# (on Server) component. 4. Add your component logic. 5. Compile the code. .NET Example, Visual C# 2010 Express The following example shows how to implement a component in C# using Visual C# 2010 Express and configure it for use with Pipeline Pilot. To generate a .NET assembly and configure it for use with the .NET (on Server) component: 1. In Visual C# 2010 Express, select File > New Project… 2. Select Class Library | Visual C# and enter the name for the project. Click OK. 3. Select Project > Add Reference > Browse, and browse to the "com.scitegic.pilot.dll" file in the installation bin directory. 4. To get a starting set of source code, replace the default source code provided by Visual Studio with a copy of the boilerplate code from the Source parameter of the Dynamic C# (on Server) component, even though we use the .NET (on Server) component instead. 5. Add your component logic (optional). 6. Compile the code. Note: You can set breakpoints in your .NET code and use the other aspects of the debugger.

Configuring the component in Pipeline Pilot Client 1. In the Pipeline Pilot Client, add a .NET (on Server) component to a new protocol. (Do NOT use the Dynamic C# (on Server) component.) 2. Set the .NET Class to the fully-qualified name of the C# class that implements the component logic, such as "MyComponent" if using the boilerplate source. In this case, we are using a class named HelloWorld. 3. Set the .Net Framework Version parameter to match the version of Visual Studio. 4. Select the Paths parameter, browse to the generated assembly, and allow the Pipeline Pilot Client to upload the binary to your user directory (or ensure that you copied the assembly to a location where the server can access it). In this example, we use "C:\Program Files\BIOVIA\PPS\bin", which already contains "com.scitegic.pilot.dll", and now also contains "HelloWorldTest.dll". 5. Run the protocol.

Page 8 | Pipeline Pilot • .NET Component Development Guide Debugging your assembly in Visual Studio 2008

1. Make sure that you have a local installation of the server so you can connect to the localhost server rather than an external server. 2. In the Pipeline Pilot Client, insert the component Attach to Visual Studio Debugger before any .NET component that you want to debug. 3. Make sure that any .NET components have the .NET Framework Version parameter set to 3.5 or earlier. This also applies to the Attach to Visual Studio Debugger component. 4. Start Visual Studio 2008 and load the project that contains the .NET component code. 5. Set one or more breakpoints in the code to be reached when the debugger has attached to the server. 6. In Pipeline Pilot Client, run the protocol against the localhost server. 7. The protocol will attempt to attach to the debugger: click Yes, debug scisvr.exe in the dialog that opens. 8. Select the existing instance of Visual Studio 2008 and click Yes. 9. If you see a disassembly window, select File > Continue in the debugger. The debugger will stop at the first breakpoint it reaches. 10. Note that the breakpoint appears in Visual Studio:

.NET Integration Components and Examples | Page 9 Page 10 | Pipeline Pilot • .NET Component Development Guide Chapter 3: Key Interfaces

The interfaces listed below are already implemented for you internally. IContext: A component uses a context object to interact with the protocol. IDataRecord: The data upon which the component operates to implement its function. INode: An INode represents a node in a hierarchical tree of nodes. INodeCache: An INodeCache stores serialized INodes in a cache. IProperty: One of the name/value pairs in a property collection. IPropertyCalculator: Properties are calculated using a property calculator. IPropertyCollection: An ordered set of name/value pairs used to hold the properties assigned to each node and to represent parameter settings. IContext: Passed to the Component interface methods above, to allow access to component parameters and global properties. IValue: Properties have values. Native .NET types are extracted out of them. Note: For further details, see Protocol Development Quick Start.

.NET Component API Reference To access the .NET Component API Reference from the Pipeline Pilot Help Center, on the Developers tab, go to Server-side Integration > Language-based Integration > .NET > .NET Component API.

Key Interfaces | Page 11 Appendix A: Running .NET Components without Internet Access The Pipeline Pilot .NET runtime library includes a digital signature, which tries to verify with a certificate authority via an internet connection. If your server is offline, you will see a delay in running .NET components while this process times out. If you are planning to run offline, bypass the validation process with the following steps: 1. Create a scisvr.exe.config file in the /bin folder. 2. Edit the content of the scisvr.exe.config to:

Page 12 | Pipeline Pilot • .NET Component Development Guide