User Tools

Site Tools


com_module_sample_vs

Creating a COM module in X# for a Visual Objects application using Visual Studio

(Side-by-Side / DLL registration with manifest)

It is not too difficult to create a X# DLL and use it from VO; you can even enter other languages like C# in the same DLL and call C# methods from X# (or v.v.).

You can refer to docs.xsharp.it/doku.php?id=com_module_sample in which Wolfgang explains the procedure using Xide. I have done it in Visual Studio

To use the DLL, you need to register it, as follows:

Regasm WCFINterfaces.dll /tlb (in an Admin DOS prompt)

This can be avoided which is easier for installing the program to a customer but it is more of a challenge. These are the steps:

X#

  • Prepare a GUID

The GUID is a unique number and one can be created at https://www.guidgenerator.com/online-guid-generator.aspx. E,g,

587BF093-A8F9-4119-12EB-414AA8FCF344

  • Create a new X# Class library in Visual Studio or Xide. I call the namespace DotNetLibForVO and the class VoDotNetClass

In the startprogram after BEGIN NAMESPACE add the following 3 lines, with the generated guid from above. Note that there are no empty lines in between. The code then looks as follows:

BEGIN NAMESPACE DotNetLibForVO
[ClassInterface(ClassInterfaceType.AutoDual)];
[Guid("587BF093-A8F9-4119-12EB-414AA8FCF344")];
[ComVisibleAttribute( TRUE )];
CLASS VoDotNetClass
PROTECT lInvalid AS LOGIC 

  CONSTRUCTOR()
  RETURN
  • Add methods. Here's a working sample: a method to get a file (e.g. one copied to the %temp% directory) in the clipboard, which is not (easily) possible from VO.
METHOD SaveImageFromClipboard(cFile AS STRING) AS LOGIC
//#s Save jpg cFile from clipboard DvK 15-9-2014
//#p cFile: path+file

LOCAL data AS System.Windows.Forms.IDataObject
LOCAL image AS System.Drawing.Image
LOCAL lCreated AS LOGIC

IF (System.Windows.Forms.Clipboard.GetDataObject() != NULL)
	data := System.Windows.Forms.Clipboard.GetDataObject()
	IF (data:GetDataPresent(System.Windows.Forms.DataFormats.Bitmap))
		image := (System.Drawing.Image)data:GetData(System.Windows.Forms.DataFormats.Bitmap, TRUE) 
		image:Save(cFile, System.Drawing.Imaging.ImageFormat.Jpeg)
		lCreated:=TRUE
	ELSE
		lCreated:=FALSE
	ENDIF
ELSE
	lCreated:=FALSE
ENDIF
RETURN lCreated
  • Make sure to compile in Release mode otherwise your registration will fail. Compile your DLL and make sure that all depending DLL's in the Release directory are copied in the VO program directory.
  • Click on DotNetLibForVO, right mouse button, Properties
  • In Build Events (VS: click Edit Post-build) :

Enter the 3 lines below on Post build Event Comment Line. Note that you may need to check the exact location of mt.exe and make sure that you do not use the mt.exe in x86 if you are on a 64 bits Windows. This should work too:

"$(FrameworkSDKDir)bin\mt.exe" -

But it's better not to rely on it.

Also note the rem in red, omit it in the first run.

rem "C:\Program Files (x86)\Windows Kits\10\bin\x64\mt.exe" -managedassemblyname:$(TargetFileName)  -nodependency -out:$(ProjectDir)\$(ProjectName).manifest
"C:\Program Files (x86)\Windows Kits\10\bin\x64\mt.exe"  -manifest "$(ProjectDir)\$(ProjectName).manifest" -outputresource:"$(TargetFileName)"
Copy "$(TargetDir)*.dll" "d:\SomeDirWithWriteRights"

At Run the post-build event choose: On successful build

  • Build the project. The manifest is now being created the project directory, (DotNetLibForVO.manifest). The DLLs are copied top the directory indicated. Then edit again the Post Build events by adding the REM in the first line so it won't be executed again. Build once more. Your DLL should now contain the manifest info.

VO

  • Retrieve c:\cavo28\Appwiz\cctl6.man, modify the program name, set the version number to 2.0.0.0 and add the relevant part of the generated manifest code as Dependency (see example above) and save it in a directory of your choice e.g. c:\VoManifests. For the X# DLL make sure that processorArchitecture = “msil (and not” * “)
  • Add a module Manifest containing RESOURCE CREATEPROCESS_MANIFEST_RESOURCE_ID RC_RT_MANIFEST c:\VoManifests\DotNetLibForVO.manifest. Note that after every change in the manifest you should touch the manifest mef and select Rebuild All for the VO Applications . E.g.:

RESOURCE CREATEPROCESS_MANIFEST_RESOURCE_ID RC_RT_MANIFEST c:\VoManifests\ChosenName.manifest

It could look as dollows:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity name="iconnect.exe" version="2.0.0.0" type="win32" processorArchitecture="*" />
<description>This file helps to load the .NET Components without registration in the registry</description>
<description>It should be linked as RC_RT_MANIFEST in the VO EXE</description>
 
<dependency>
 <dependentAssembly>
  <assemblyIdentity name="DotNetLibForVO" version="1.0.1.1" processorArchitecture="msil" />
 </dependentAssembly>
</dependency>
 
<description>Visual Objects Application.</description>
<dependency>
    <dependentAssembly>
        <assemblyIdentity
            type="win32"
            name="Microsoft.Windows.Common-Controls"
            version="6.0.0.0"
            processorArchitecture="X86"
            publicKeyToken="6595b64144ccf1df"
            language="*"
        />
    </dependentAssembly>
</dependency>
 
</assembly>
  • To use a method from the library, write code in VO like the code below. For OleAutoObject you use, between {“Namespacename.Classname”} (as chosen in 1)
METHOD PasteImage () CLASS Something
LOCAL oDotNet AS OBJECT
//….
oDotNet:= OLEAutoObject{"DotNetLibForVO.VoDotNetClass"}
oDotNet:Finit
cTempFilename:=GetTempFilePath()+"lImage.JPG"
lOk:=oDotNet:SaveImageFromClipboard(cTempFilename)

Also note that you may come across Finit errors. This usually means that the manifest is not correctly 'recognized”. You may need to try more than once to touch the manifest mef, rebuild the project, or maybe even reindex. IF the program doesn't start, this may also something which can be solved after multiple retries. If it persists, also try to create an .exe and if that works the program may work from the VO IDE as well. Otherwise:

In Start menu select Event viewer and go to Windows logs, Application. This may show:

Activation context generation failed for “d:\XSharpVOTest\XSharpVOTest.DBG”.Error in manifest or policy file “d:\XSharpVOTest\DotNetLibForVO.DLL” on line 1. Component identity found in manifest does not match the identity of the component requested. Reference is IC2ExtLibForVO,processorArchitecture=“x86”,version=“1.0.65534.65534”. Definition is DotNetLibForVO,processorArchitecture=“msil”,version=“1.0.65534.65534”. Please use sxstrace.exe for detailed diagnosis.

Note that the architecture In yellow is what Windows found in the manifest and in blue what was found in the DLL (from the project settings in e.g. VS). The manifest line in 8), see in blue, must match the one in the DLL, otherwise this error occurs.

  • For more info on the error there's one of those terrible command line tools from Microsoft, SX Trace

SXTrace

The program should be at location: C:\Windows\System32\sxstrace.exe Administrative privileges are required to use sxstrace.exe

  • Open Command Prompt (Admin)
  • Start SxSTrace by running the command: sxstrace.exe Trace -logfile:tracetest.log

Note: Make sure you run the command on a directory with write permissions. As an alternative, point the –logfile parameter to a directory with write permissions

  • Run the program causing the error message (from Explorer or another prompt). When the error message appears click OK
  • Stop Trace (by pressing Enter in the DOS box)
  • Convert log to readable format. The tracetest.log from above is a binary formatted file. This command will convert into human readable format by parsing the binary log file and creating a text file

sxstrace.exe Parse -logfile:tracetest.log -outfile:tracetest.txt

Sample:

C:\Windows\System32\sxstrace.exe Trace -logfile:c:\temp\tracetest.log C:\Windows\System32\sxstrace.exe Parse -logfile:c:\temp\tracetest.log -outfile:c:\temp\tracetest.txt

Sample: courtesy by Dick van Kooten

com_module_sample_vs.txt · Last modified: 2018/06/08 05:40 by wolfgangriedmann