Creating an assembly from the command line
Follow the instructions in this topic to generate C# classes and build a Synergy assembly using command-line utilities.
If your Synergy code is on UNIX or OpenVMS, you can use the command-line tools to generate the XML file there, and then move the file to Windows to run gencs and create the assembly. |
You will need to do the following:
1. | Create an XML file with the genxml utility. See Creating an XML file with genxml below. |
2. | Use the XML file and the gencs utility to generate the C# classes. See Generating C# classes with gencs. |
3. | (optional) Edit the source files. See Editing the generated C# files. |
4. | Run the batch file to compile the classes, build the assembly, and (optionally) create the XML file that can be used to generate API documentation. See Building an assembly from the command line. |
5. | (optional) Complete the API documentation using a third-party utility. See Generating API documentation. |
Creating an XML file with genxml
The genxml utility creates an XML file from SMC method definitions and repository structure definitions. This is an intermediate step in creating the C# classes.
The genxml utility checks structure sizes in the SMC against the corresponding structures in the repository and reports a warning if there are discrepancies. Although the XML file is generated anyway, you should use the MDU’s Verify Catalog utility to update the structure sizes in the SMC. (See Verifying repository structure sizes and enumerations.) Failure to do so can cause errors at runtime because the structure information in the component, which was pulled from the repository, will differ from that in the SMC. |
The genxml utility is installed in the DBLDIR directory. It runs on all supported Synergy/DE platforms.
dbr genxml -f xmlFilename -i intName [-a altIntName] | -all [-d targetDir] [-s smcDir] [-m rpsMain -t rpsText] [-n] [-v msgLevel] [-?]
Options
-f xmlFilename
The name to use for the XML file. This name will also be used for the assembly. You can include the complete path if desired. If you do not specify an extension, “.xml” is used.
-i intName
Name of the interface from the SMC to include in the XML file. You may pass multiple interface names; each must be preceded with the -i option. A C# class will be created for each interface specified. Remember, the interface name is case sensitive.
-a altIntName
(optional) Alternate interface name. Use this name for the interface previously specified with the -i option. Genxml uses the associated -i interface to pull methods from the SMC; the alternate name is included in the XML file and is used as the class name when gencs is run. If you pass multiple interface names, each may have an alternate name. Each alternate name must be preceded with the -a option. See Examples.
When using alternate names, sequence matters. The -a option must follow the -i option that it applies to. You may specify multiple interface names, and each may have an associated alternate name immediately following it. |
-all
Export all methods from the SMC. This option is an alternative to listing individual interfaces with the -i option. A C# class will be created for each interface in the SMC. If both -i and -all are included on the command line, -all takes precedence.
The -all option may not be suitable for some SMCs because it exports all methods, even those that are not included in an interface. An XML file that contains methods that are not in an interface will cause the error “Empty interface name. Execution aborted” when you run gencs. You may have such methods in your SMC if it contains the xfServerPlus API routines. |
-d targetDir
(optional) The target directory for the XML file. If not passed, the XML file is created in the directory specified in the -f option. If no directory is specified with -f, the file is created in the current directory.
-s smcDir
(optional) Directory where the SMC files (cdt.is? and cmpdt.is?) are located. If not passed, DBLDIR is used.
-m rpsMain
(optional) Full path to the repository main file that contains the structures referenced in the SMC. Use with -t. This option is used only if you are passing structures as parameters. If not passed, genxml uses the environment variable RPSMFIL to determine the name of the repository main file; if that is not set, it uses RPSDAT:rpsmain.ism. If RPSDAT isn’t set, genxml looks in the current directory for rpsmain.ism.
-t rpsText
(optional) Full path to the repository text file that contains the structures referenced in the SMC. Use with -m. This option is used only if you are passing structures as parameters. If not passed, genxml uses the environment variable RPSTFIL to determine the name of the repository text file; if that is not set, it uses RPSDAT:rpstext.ism. If RPSDAT isn’t set, genxml looks in the current directory for rpstext.ism.
(optional) Indicates that you want to use the value in the Repository Alternate name field instead of the value in the Name field as the property or field name. This option pertains only if you are passing structures as parameters. If not passed, the field name in the structure becomes the property/field name in the C# class. If passed, the value in the Alternate name field is used when it exists; else, the value in the Name field is used.
-v msgLevel
(optional) Level of verbosity in messages:
0 = no messages
1 = error messages and warnings
2 = everything included in level 1, plus success messages (default)
3 = everything included in level 2, plus return codes and the location of the SMC and repository files
-?
(optional) Displays a list of options and the version number for genxml.
This example creates an XML file named ConsultIt.xml. This will also be the name of the assembly. The XML file will include information about two interfaces, AppLogin and Consultant. The target directory for the XML file is c:\work, which is also where the SMC files are located.
dbr DBLDIR:genxml -f ConsultIt -i AppLogin -i Consultant -d c:\work -s c:\work
This example uses alternate interface names. Instead of classes named AppLogin and Consultant, the assembly will have classes named Login and Consult.
dbr DBLDIR:genxml -f ConsultIt -i AppLogin -a Login -i Consultant -a Consult -d c:\work -s c:\work
On OpenVMS, you’ll need to define genxml as a foreign command and then execute it. In the example below, we quoted the XML filename and the interface names to preserve the case. (The DCL interface on OpenVMS uppercases names. If names are not uppercase in the SMC, you’ll need to put them in double quotes on the genxml command line, or genxml will generate an error. You will likely also want to put quotes around the XML filename, since it becomes the name of the Synergy component.)
$ GENXML:==$DBLDIR:GENXML $ GENXML -F "ConsultIt" -I "AppLogin" -I "Consultant" - -D SYS$WORK: -S SYS$WORK:
Generating C# classes with gencs
The gencs utility takes as input the Synergy XML file created by genxml and outputs the following:
- C# source files. By default, there will be one C# class file for each interface you specified when running genxml, as well as a C# class file for each structure, group, and enumeration in the interface. There will also be a C# interface file generated for each interface you specified when running genxml.
- A batch file named xmlFilename.bat, which is used to compile the classes, generate the assembly, and create the XML file for the API documentation.
- A response file named xmlFilename.rsp, which is used by the batch file to compile the classes.
- A file named AssemblyInfo.cs, which contains information about the assembly. You can customize this file; see Editing information in AssemblyInfo.cs. Once created, this file will not be overwritten if you regenerate classes.
The gencs utility is installed in the xfNLNet directory.
The gencs utility must be installed on your local machine. Attempting to run it on a remote machine using a mapped drive will result in a .NET security error. |
gencs -f xmlFilename [-d targetDir] [-nd] [-n namespace] [-o outputDir] [-s keyFilename] [-t] [-a] [-g] [-nb] [-r] [-nr] [-p] [-i interfaceName:count] [-w] [-v msgLevel] [-?]
Options
-f xmlFilename
The full path and filename of the XML file generated with genxml. If you do not specify the file extension, “.xml” is assumed.
-d targetDir
(optional) The directory for the generated files. If not passed, defaults to the Documents folder (a.k.a. My Documents). The gencs utility creates a subdirectory, named with the XML filename, within targetDir and places all the generated files in it.
-nd
(optional) Don’t create a subdirectory for the generated files. Pass this option to place the generated files directly in the directory specified with -d or, if -d is not specified, in the Documents folder.
-n namespace
(optional) The namespace that the assembly will use. If specified, all classes generated for the assembly will use this namespace. If not specified, the namespace will be xmlFilenameNS.
The namespace is used to ensure that each class is unique. Microsoft recommends that namespaces use the format CompanyName.ProductName (e.g., ABCComputers.ConsultPro). The namespace is appended to the beginning of the class name (e.g., ABCComputers.ConsultPro.MyClass).
-o outputDir
(optional) The directory that the assembly will be created in. If not passed, the assembly will be put in the same location as the class files (see -d and -nd, above).
-s keyFilename
(optional) Full path and filename of the strong name key file that will be used to strong name the assembly. You must create the file using Microsoft’s sn.exe utility and place it in the desired location before running gencs. The gencs utility will verify that the file exists and then write the path to the batch file. See Using your own key file for more information.
If not passed, xfNetLink .NET will generate public and private keys in a strong name key file named with the assembly name.
-t
(optional) Assembly will be delay signed. Use with -s. See Using your own key file for more information.
-a
(optional) Generate an XML file that can be used to generate API documentation. This option adds a command to create the XML file to the batch file. In order to have useful documentation, you must add comments for your methods and parameters. See Generating API documentation for more information.
-g
(optional) Generate structure members as public fields. If not passed, structure members are generated as properties with private fields. If you are planning to use .NET controls, generate properties; the properties have “get” and “set” methods, which can be assigned to .NET controls in Visual Studio. You must also generate properties to take advantage of Repository’s read-only flag and the class Changed property.
If you are not planning to use .NET controls, and don’t need the read-only flag, Changed property, or the INotifyPropertyChanged event, you can generate either fields or properties; using fields may improve performance.
-nb
(optional) Convert binary fields in repository structures to strings. By default, a binary field in a repository structure is converted to a byte array of the size specified in the Repository field definition. This feature was added in version 9.3, and can be used, for example, to store an RFA that can then be used to ensure you update the correct record when data is returned to the server. To retain the pre-9.3 behavior and convert binary fields to strings, use the -nb option. This option is not available when creating an assembly from Workbench. See Appendix C: Data Type Mapping for xfNetLink .NET for more information on data type conversion. Note that you should use the procedure described in Passing binary data in xfNetLink .NET, rather than a binary structure field, to pass most binary data.
-r
(optional) Include the Original property in structure classes. This property is used to store a copy of a structure within the object. By default it is not included. This option is not available when creating an assembly from Workbench. See Using the Original property for details.
-nr
(optional) Generate output parameters (that is, parameters marked as “out” in the SMC) as “out” types in the C# code, with the exception of arrays, which are always generated as “ref”. If not passed, output parameters are generated as “ref” types in the C# code. (Prior to version 9.5.1, all “out” parameters were generated as “ref” by default.)
-p
(optional) Include the INotifyPropertyChanged class in generated structure classes. This enables you to use the PropertyChanged event on structure fields (properties) bound to controls. This option cannot be used with -g; it is valid only when you generate properties.
-i interfaceName:count
(optional) Generate multiple classes of the specified interface name. Specify the total number of classes desired with count. The first instance of the class will be named as usual with the interface name (or alternate name, if specified). Subsequent instances will be named with the interface name followed by a number, which will increment. (See Examples.) You can pass multiple interface names; each must be preceded with the -i option. If -i is not specified for an interface, a single class will be generated. (See Using multiple copies of the same class for more information on using this feature.)
-w
(optional) Generate WCF contracts. Use this option if you want the assembly to use WCF contracts, such as for a web service. The generated classes will include code that makes the assembly hostable. In addition, this option changes the way ArrayList and structure collection parameters are handled: rather than being generated as ArrayLists, they are generated as List<T> parameters (where T is the data type of the elements). Consequently, in your client code, you must use a List<T> class instead of an ArrayList class for a parameter that is defined as ArrayList or structure collection in the SMC.
-v msgLevel
(optional) Level of verbosity in messages.
0 = no messages
1 = error messages
2 = error messages and success messages (default)
-?
(optional) Displays a list of options for the utility.
This example creates .cs files from ConsultIt.xml, and indicates that you want to create an XML file for API documentation. The namespace uses the standard CompanyName.ProductName format (in our example, ABCComputers.ConsultPro). A subdirectory named ConsultIt will be created within c:\work, and the .cs, .bat, and other generated files will be placed there. This example also includes a strong name key file and the -t option to delay sign the assembly. This is a continuation of the genxml example, so the new files will be named AppLogin.cs and Consultant.cs.
gencs -f c:\work\ConsultIt.xml -d c:\work -a -n ABCComputers.ConsultPro -s c:\corp\ABCComputersPublic.snk -t
The XML file ConsultIt.xml contains two interfaces, AppLogin and Consultant. In the following example we use the -i option to specify that we want to create multiple classes (three total) from the interface AppLogin. These classes will be named AppLogin.cs, AppLogin1.cs, and AppLogin2.cs. Because we have not specified the Consultant interface with the -i option, only one Consultant class will be generated.
gencs -f c:\work\ConsultIt.xml -d c:\work -a -n ABCComputers.ConsultPro -s c:\corp\ABCComputersPublic.snk -t -i AppLogin:3
Gencs also appends numbers to the ends of interface names when it encounters names that differ only in case or a structure name that is the same as an interface name. Consequently, the numbers appended to the additional class files created with the -i option may not start with 1. See the note under the Interface name field for more information. |
Building an assembly from the command line
Before building the assembly, you may need to edit the generated C# class files or the AssemblyInfo.cs file. See Understanding the generated C# classes and Editing the generated C# files.
The gencs utility creates a batch file (xmlFilename.bat) and places it in a subdirectory under the directory specified with the gencs -d option. The batch file includes commands to compile the C# classes, build the assembly, and—if you included the gencs -a option—generate an XML file that can be used for API documentation.
If desired, you can pass C# compiler commands to gencs by setting the SYNCSCOPT environment variable to any valid C# compiler command before running the batch file.
1. | Open a Visual Studio Developer Command Prompt. |
2. | (optional) Set SYNCSCOPT. |
3. | Run the batch file created by gencs. For example, to continue with our previous scenario: |
c:\work\ConsultIt\ConsultIt.bat
To enable the classes in your assembly to be pooled, you must run the batch file with the -p option. For example:
c:\work\ConsultIt\ConsultIt.bat -p
Using the -p option causes the generated procedural classes to be derived from the ServicedComponent class. It also changes the status of some methods from public to private or protected, and causes the getConnect() and shareConnect() methods to be excluded from the procedural classes. Thus, you should use -p only when you are certain the object will be pooled. See Understanding .NET pooling and Implementing .NET pooling for more information on pooling. |
The assembly (named ConsultIt.dll in our example) will be placed in the directory specified with the gencs -o option, if specified, or in the same directory as the generated classes. If you opted to create an XML file to be used for API documentation, the XML file will be placed in the subdirectory under the directory specified with the gencs -d option.