How to call C# .dll from a C++/CLI application? - dll

I'm trying to call the LumenWorks .csv file reading library from a C++/CLI application and having some issues. I've added a dependancy on LumenWorks.Framework.IO.dll but when I try to then use the library:
namespace MyNamespace
{
using namespace Lumenworks::Framework::IO::Csv;
// <My code definitions here>
}
I get a message that the compiler doesn't recognise 'Lumenworks'. Do I need to reference header files from the sources or is there a way to get the same information from the .dll?

Maybe try "LumenWorks" (based on article on codeproject)? And add ; at the end of line.

Related

ADTF SDK: import manifest AND handle it

I'm trying to run a full ADTF configuration from my own C++ command-line application using the ADTF SDK. ADTF version: 2.9.1 (pretty old).
Here's what I have (want) to do:
Load manifest file
Load globals-xml
Load config-xml
2 & 3 are done, using the session-manager service - see ISessionManager interface: https://support.digitalwerk.net/adtf/v2/adtf_sdk_html_docs/classadtf_1_1_i_session_manager.html , functions LoadGlobalsFromFile & LoadConfigFromFile.
The problem is that I don't know how to do point 1: currently, instead of loading a manifest, I manually load the list of services myself using _runtime->RegisterPlugin, _runtime->CreateInstance and _runtime->RegisterObject.
What I've managed to do is to load only the namespace service and use the INamespace interface which has a method for loading manifest files: https://support.digitalwerk.net/adtf/v2/adtf_sdk_html_docs/classadtf_1_1_i_namespace.html - see ImportFile with ui32ImportFlags = CF_IMPORT_MANIFEST.
But this only loads the manifest settings into the namespace, it doesn't actually instantiate the services. I could do it manually, by:
Do _runtime->RegisterPlugin for every url under
root/plugins/ in the namespace
Do _runtime->CreateInstance for every objectid under
root/services/ in the namespace
But I want this to be more robust and I'm hoping there's already a service that handles the populated namespace subsequently and does these actions. Is there such a service?
Note: if you know how this could be done in ADTF3 that might also be of help for me, so don't hesitate to answer/comment
UPDATE
See "Flow of the system" on this page: https://support.digitalwerk.net/adtf/v2/adtf_sdk_html_docs/page_service_layer.html
Apparently the runtime instance itself handles the manifest file (see run-levels shutdown & kernel) but I don't know how I'm supposed to tell it where it is.
I've tried setting the command-line arguments to be count = 2 and the 2nd = manifest file path when instantiating cRuntime. It doesn't work :).
In ADTF3 you can just use the supplied cADTFSystem class to initiate an ADTF system and then use the ISessionManager interface to load a session of your choice.
Found the answer, not exactly what I expected though. I tried debugging adtf_runtime.exe to find out what arguments it passes to cRuntime.
The result is indeed similar to what I've suspected (and actually tried):
arg1 = adtf_runtime.exe (argv[0] in adtf_runtime)
arg2 = full path to manifest file (e.g. $(ADTF_DIR)\bin\adtf_devenv.manifest)
arg3 = basename of manifest file, without extension (e.g. "adtf_devenv")
While this suggested that cRuntime indeed is responsible with loading and handling the manifest, it turned out to be NOT quite so, passing the same arguments to it did not do the job. The answer came when I noticed that adtf_runtime.exe was actually using an extension of cRuntime called cRuntimeEx which is NOT part of the SDK (at least I haven't found it).
This class IS among the exported symbols of the ADTF SDK library, i.e. a "dumpbin /symbols adtfsdk_290.lib" renders at some point:
public: __cdecl adtf::cRuntimeEx::cRuntimeEx(int,char const * *
const,class ucom::IException * *)
but it is NOT part of the SDK (you won't find a header file defining it).
Among its methods you'll also find this:
protected: long __cdecl adtf::cRuntimeEx::LoadManifest(class adtf_util::cString const &,class std::set,class std::allocator > *,class ucom::IException * *)
Voila. And thus, unfortunately, I cannot achieve what I wanted in a robust fashion. :)
I ended up manually implementing the manifest-loading logic, since cRuntimeEx is not made available within the SDK. Something along these lines:
Use a cDOM instance to load the manifest file
Call FindNodes("/adtf:manifest/environment/variable") to find the environment-variables that need to be set and set them using "cSystem::SetEnvVariable"
Call FindNodes("/adtf:manifest/dependencies/platform") to find library dependencies and use cDynamicLinkage::Load to load the libraries that target the current platform (win32/linux)
Call FindNodes("/adtf:manifest/plugins/plugin") to find the services to be loaded using _runtime->RegisterPlugin (you may also handle "optional" attribute)
Call FindNodes("/adtf:manifest/services/service") to find the services that need to be created using _runtime->CreateInstance and _runtime->RegisterObject (you may also handle "optional" attribute)
And, finally, call FindNodes("/adtf:manifest/manifests/manifest") to (recursively) load child-manifests (you may also handle "optional" attribute)
The only thing you need to do is start the adtf launcher with the meta files (manifest. This works for adtf 2 as well as for adtf 3. It can be done (console) application. If you also want to do a little bit more in adtf 3, you can use adtf control instead of adtf launcher with its scripting interface (see the scripts under examples)

VBScript can't find object in .NET dll [duplicate]

I wrote a DLL in .NET and I want to access it in VBScript. I don't want to add it to the assembly directory.
Is there a way to point too the DLL and create an instance of it?
I just had to do this myself, my findings were:
Making types visible to COM:
Ensure your class is public, non-static and has a public default constructor i.e. not arguments.
Ensure your method is public, non-static.
Ensure you have the following set on your assembly - typically in AssemblyInfo.cs
[assembly: ComVisible(true)]
After building your DLL, from SDK command line run:
regasm yourdll.dll
This should respond:
Types registered successfully
If you get
RegAsm: warning RA0000: No types were registered
then you need to set ComVisible or have no public, non-static types.
From PowerShell
$a = New-Object -comobject Your.Utils.Logging
$a.WriteError2("Application", "hello",1,1)
From vbs
Set logger = CreateObject("Your.Utils.Logging")
logger.WriteError2 "Application", "hello from vbs",1,1
huseyint's answer was on the money, however, I wanted to add a little to it. Here is some sample code I used for this very issue, perhaps it can speed you along...
// bind a variabe to WScript.Shell
Set WshShell = CreateObject("WScript.Shell")
// define the path to the regasm.exe file
RegAsmPath = "c:\Windows\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe"
// register the dll
WshShell.run "cmd /c " & RegAsmPath & " c:\temp\cbsecurity.dll /codebase /nologo /s", 0, True
// bind a variable to the dll
Set cbUtil = CreateObject("CBSecurity.Utilities")
I had included an IsAlive method in the dll...
Public Function IsAlive() As Boolean
Return True
End Function
...and could check that it registered correctly using the syntax:
//check if dll is available to your code
msgbox "cbUtil is alive: " & cbUtil.IsAlive
Hope this helps someone...
You can register that .NET dll with regasm utility by specifying /codebase parameter. This parameter is not encouraged to use with unsigned assemblies but it works when you can not put your assembly into GAC.
regasm your.dll /codebase
Please note that you should not change your .dll's path after this operation since it inserts this path into the Windows registry.
In case someone needs to debug/step-into the .Net dll that's called from VBScript only:
On the .Net dll project debug setup screen, set the "start external program" by browsing to the wscript.exe program (located in C:\WINDOWS\system32\wscript.exe).
On the "Command Line Arguments", set the file name and path location of the VBScript file (C:\Test\myTest.vbs). Make sure the vbs file and dll file are in the same location.
Finally, in the .Net project DLL source code just set the break point and hit the "start debug"
Not directly. You'll need a COM Callable Wrapper to any .NET library you'll calling from COM (and hence, VBScript). Therefore, you should either directly create a CCW to the DLL or you can create a CCW for a proxy DLL which provides generic methods to load a .NET DLL and provide methods for you that call the actual methods on the component and return the result. It's really not clean at all. So, in general, the answer is no.

How to access a specific resw resource file

For a Windows 8 application in C#/XAML I need to access a specific ressource file. In WP7 I used resx file and now it seems that we need to use resw file. It's not a language resource file.
My file is called ConfigResources.resw, it just contains one key : "ConfigFile" and a value : a string.
How can I access it from my code? I tried this without any luck:
var storedConfigFile = Application.Current.Resources["ConfigResources"];
Then how can I edit the value of the key inside from my code?
Thank you
I created a project on CodePlex recently called ResW File Code Generator that simplifies using localized resources in code in windows store app project. It's a custom tool that automatically generates and updates a helper class similar to what ResX files used in the full version of .NET
According to here, you need to use the Windows.ApplicationModel.Resources.ResourceLoader and the Windows.ApplicationModel.Resources.Core namespace provide interaction with resw files.
It should look something like this:
var loader = new Windows.ApplicationModel.Resources.ResourceLoader();
var text = loader.GetString("Farewell");
Alternately, if you're creating a cross-platform library you could also do it using the System.Resources.ResourceManager:
Although the System.Resources.ResourceManager class is included in the
.NET for Windows Store apps, we do not recommend its use. Use
ResourceManager only in libraries that are developed as Portable Class
Library projects and that target multiple platforms.
Like this from here:
ResourceManager rm = new ResourceManager("Strings", typeof(Example).Assembly);
string timeString = rm.GetString("TimeHeader");
There is a sample that shows the different ways to read the resources in WinRT apps (i.e. from resw files).

Visual Studio Custom Tool: File wrapper

What I want is typed access to the contents of a file within a VS.NET solution.
I think a custom tool with corresponding custom tool namespace would be the easiest to do (do correct me if there is a simpler way of accomplishing the same thing!)
This would generate code like so:
Namespace CustomToolNamespaceInPropertiesComesHere
Public Module SomeName
Public Function GetFile() As IO.Stream
Return System.Reflection.Assembly.GetExecutingAssembly() _
.GetManifestResourceStream("RootNamespace.FileName.xml")
End Function
End Module
End Namespace
Basically it creates typed access to a file (An XML file with Build Action: Embedded Resource) within the "Custom Tool Namespace" as specified in the properties of the file.
I do not want to use a ResX as I want each XML file to appear seperately in the solution and have the XMLEditor as default editor (So XSD validation can be added if time permits writing one).
Unfortunately little information can be found about these custom tool namespaces. Every example so far also seems to refer to BaseCodeGeneratorWithSite of which the original URL has gone dead.
I'm also asking this in hopes of someone providing something easier to use/implement rather than the overkill of a new custom tool...

Embed Dictionary into VB.NET application

I want to embed a dictionary.txt which my program uses a streamreader object to parse. I tried to add it to resources but then the streamreader had an error. How can it be properly done?
Thanks
First you need to embed the file in your assembly (add to project and goto Properties for the file, and set Build Action to "Embedded Resource").
Then you need to access and read it's contents using GetManifestResourceStream():
Getting an embedded resource file out of an assembly
This article might be of interest: Microsoft .NET Framework Resource Basics