(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#
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
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
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
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
VO
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>
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.
SXTrace
The program should be at location: C:\Windows\System32\sxstrace.exe Administrative privileges are required to use sxstrace.exe
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
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