dotNet

 

WinBatch supports access to the Microsoft dotNet Framework. WinBatch makes this possible by hosting the common language runtime (CLR) and exposing functionality for creating and accessing the members of classes, structures and enumerations of managed code assemblies (DLLs) that are part of or based on the Framework.

The WinBatch CLR hosting environment works by wrapping Framework based classes, structures and enumerations in light weight COM Automation objects to take advantage of the WinBatch interpreter's existing understanding of COM syntax and semantics. This approach lessens the challenge of using managed objects in WinBatch script for those already familiar with COM Automation. However, it is still recommended that you have a basic understanding of object oriented programming concepts as used by the Framework.  It is also important to carefully read and understand the documentation for a Framework based type before using it in a WinBatch script.

WinBatch access to the Framework uses COM but it is not completely dependent on the Framework's COM interop. This is because the WinBatch directly hosts the CLR.  The hybrid approach offers significant advantages over a COM interop only implementation.

First, assemblies do not need to be registered in the Windows registry to be accessed. Second, whole classes, class methods and class properties do not need to be attributed as COM visible to be accessed through WinBatch. Third, WinBatch CLR hosting is not tied to a specific Framework Class Library (FCL) or CLR version. WinBatch only requires that the Framework be installed on the system.

ObjectClrNew creates a class, structure or enumeration implemented by a managed assembly. The function returns a Framework based type as a COM Automation reference that can be used to access the members of the underlying Framework based type. The assembly implementing the type specified by 'typename' must be loaded into the WinBatch process before this function can be called to create the type.  The exceptions to this requirement are types implemented by the "mscorlib" assembly. This assembly is automatically loaded by WinBatch when the CLR is loaded. All other assemblies must be loaded into the WinBatch process using the ObjectClrOption function's Use or UseAny option.

The Typename passed to ObjectClrNew must be  fully qualified by including the dot (.) separated namespace prefixed to the type's immediate name.  The namespace name and immediate name must also be separated by a dot character. Ctorparm is the constructor parameters to be used when creating a type. Since type constructors can be overloaded, the type and number of these parameters control which constructor will be used to create the type.

Members of the returned object reference are called using the same variable-name+dot+member-name syntax used by standard COM Automation object references. However, there are some important differences between regular COM calls and CLR type member calls. The most significant difference is that CLR constructors and type member names can be overloaded. This means that more than one member can have the same name. When more than one member has the same name, WinBatch and the CLR determine which member to call based on the number and type of the parameters passed in the call statement. The combination of member name, parameter types and parameter count is called the member's signature. This means that using the correct type for each parameter is crucial to calling the correct member.

Both member overloading and the fact that WinBatch cannot query the object for type information before making a member call as it does with regular COM Automation references mean that the colon (:) type qualifier needs to be used more frequently on CLR object member parameters. Fortunately, WinBatch will take standard variant type names like BSTR, UI8, BOOLEAN, R8, e.g., and convert them to equivalent Framework types automatically. It will also automatically deduce the correct Framework type for variant variables passed as parameters to a member without needing to specify a type with the colon qualifier.  

When a Framework based type does not have equivalent variant type, the fully qualified Framework based type name can be used with colon type qualifier on a parameter. This is most often necessary when the object member is expecting an up-cast or down-cast of Framework based class, when it is expecting a value from a Framework based enumeration, or when  it is expecting an array with elements of a specific Framework based type. In the case of arrays, the type qualifier should be the Framework based type of the elements prefixed to the variable name of a variable that holds either a WIL array or a variant safearray. No array type information ('ARRAY' or 'System.Array') should be included in the type qualifier.  When using a Framework type name qualifier with any parameter the type  qualifier's assembly must be loaded before the member with the qualified parameter is called.

Another significant difference between standard COM Automation object and Framework based wrapped objects is that unlike standard COM Automation objects, Framework based object member names are case sensitive.  

ObjectClrOption sets CLR configuration options before the CLR is loaded and loads an assembly into the current WinBatch process.  Available options are Version, Appbase, Use or UseAny.

Version is used to instruct WinBatch to load a specific version of the CLR. The option-value parameter string must start with the character "v" followed by the first three parts of the version number. Currently, Microsoft provides the following CLR versions "v1.0.3705", "v1.1.4322", "v2.0.50727" and "v4.0.30319".  The option must be set before the first call to ObjectClrOption with the Use or UseAny option or before the first call to the ObjectClrNew function.  If the Version option is not used before the CLR is loaded, WinBatch will attempt to load the current system's latest installed version of the CLR.

Appbase is used to indicate the full file system path that presents the location of assemblies you plan on using in your script that are not installed into the global assembly cache (GAC) of the system running the script. This option must be set before the first call to ObjectClrOption setting a Use or UseAny option or before the first call to the ObjectClrNew function. You DO NOT use the name of the file containing the assemblies with the 'Appbase' option. You Do specify the full (not partial) path to the location of the assemblies you are going to use in your script that are not in the GAC.   Logically this means that all non GAC assemblies need to be placed in the same directory for a given script.

ObjectClrOption('appbase','c:\DotNet\ThirdParty\MailSystem\ActiveUp.MailSystem_May2013_Binaries\Release\')

 

Use is used to load assemblies into the WinBatch process. Assemblies must be loaded before the types the assembly implements can be used.  The option-value parameter for the option must be a string variable or literal containing an assembly name.  If an assembly is stored in the Global Assembly Cache (GAC), it is generally necessary to use the fully qualified assembly name.  The fully qualified assembly name has the format:

 "assembly's name, version=x.x.x.x, culture=xxxx, PublickeyToken=xxxxxxxxxxxxxxxx".

  

For example, the fully qualified name of the "System.Data" assembly is

"System.Data, version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

 

Full assembly names can be found by using the Mscorcfg.msc tool, by viewing the global assembly cache directory directly, or by using the Gacutil.exe tool.

UseAny is similar to the function's "use" option for loading assemblies except that it does not require a strong assembly name.   Instead the option attempts to load an assembly using the assembly's weak name. An assembly's weak name is an assembly name without the Version, Culture, PublicLeyToken and optional processorArchitecture values. The function performs the "useany" task by searching the Global Assembly Cache (GAC) for the latest version of the named assembly.  It is not necessary to use the option to load non-GAC assemblies because the CLR does not require that non-GAC assemblies have strong assembly names.  Setting the CLR version using this function's "version" option limits "useany" to search for GAC assemblies associated with the specified version and older versions of the CLR.

ObjectClrType is used to either associate a Framework based type name with a value, or to up-cast or down-cast Framework based object references.  If the second parameter is a simple string, integer, float, variant that is not a reference to a Framework based object, the returned reference can only be used as a parameter to a Framework based object method call, as the right-hand side of a Framework based object property assignment or a constructor argument in a call to ObjectClrNew.  In other words, the returned reference does not have user callable methods, properties or fields.  On the other hand, if the second parameter is a reference to a Framework based object and the first parameter is the typename of a base or derived type of that object then the returned reference can be used to access the members of either the base or derived type of the input object.

Typename is the name of a Framework based class, structure or enumeration. The name must be fully qualified by including the dot (.) separated namespace prefixed to the type's immediate name.  The namespace name and immediate name must also be separated by a dot character.

Value-reference is value or Framework based object reference to associate with Typename. If it does not contain a Framework based object reference, the assembly implementing  typename must be loaded before the return reference is used as a method parameter, property value or constructor argument. If it contains a Framework based object reference, the assembly implementing typename must be loaded before ObjectClrType is called.

dotNet Limitations in WIL

While WinBatch CLR hosting has many advantages, it has limitations that should be considered before deciding whether or not to implement a solution using Framework based assemblies. The following is a partial listing of those limitations: