Connecting to business object with RDS.DataSpace in C# - c#

Is it possible to do this task using C#?
Global Const COMPLUS_SERVER As String = "http://myserver"
Sub Test()
Set objRDS = CreateObject("RDS.Dataspace")
Set objCLS = objRDS.CreateObject("MY_System", COMPLUS_SERVER)
Set ListNames = objCLS.LstOBSReasons("databaseserver", "databasename", 5)
End Sub
I've tried with Activator.CreateInstance(Type.GetTypeFromProgID("")); with no success, besides I would like to know in another way that I can connect to my business object.
Thanks in advance!

It should be possible, first you need to add the Microsoft Remote Data Services Library to your project's references. You will find it under the COM tab. You can then create the RDS.DataSpace class by doing:
DataSpaceClass objRDS = new RDS.DataSpaceClass();
dynamic objCLS = objRDS.CreateObject("MY_System", "http://myserver");
dynamic listNames = objCLS.LstOBSReasons("databaseserver", "databasename", 5);
The only tricky part is you might not be able to call the resulting object through the dynamic invocation (and I assume you are using C#4). If you can't you will need to also import the types for your business object. For example look at something like this for more information on implementing COM interop.

Related

How to get access to built-in language services in VSIX?

I am having trouble with getting access to the default C#-LanguageService in IVsExpansionClient.FormatSpan(IVsTextLines pBuffer, TextSpan[] ts). I need a Source-Instance of the current LanguageService to be able to create an EditArray for the incoming Span.
I was able to receive a COM-Object with the following code:
pBuffer.GetLanguageServiceID(out var languageServiceId);
var provider = Microsoft.VisualStudio.Shell.ServiceProvider.GlobalProvider;
var vssp = provider.GetService(typeof(IOleServiceProvider)) as IOleServiceProvider;
var iunknown = new Guid(VSConstants.IID_IUnknown.ToString());
IntPtr ptr;
if (ErrorHandler.Succeeded(vssp.QueryService(ref languageServiceId, ref iunknown, out ptr)))
{
try
{
service = Marshal.GetObjectForIUnknown(ptr);
lang = (LanguageService)service;
}
finally
{
Marshal.Release(ptr);
}
}
But the cast lang = (LanguageService)service; fails. I have no idea what type that COM-Object behind service is. So my question is, how do I get the current LanguageService of an open editor?
I have taken parts of the code from here:
https://github.com/microsoft/VSSDK-Extensibility-Samples/blob/346f5b0289e5fb8de639ba96fb10703df06cd22d/WPFDesigner_XML/WPFDesigner_XML/ViewModel.cs#L275
Thank you!
The language services implement a number of different interfaces, you'd be then trying to query it for whatever interface you want. You mentioned C#, and in our case we don't actually derive from the package framework LanguageService at all, so that cast would fail.
You may want to clarify in your question what you're trying to achieve, since that's not exactly clear to me.

Clearscript vbscript com ado interaction

I'm using clearscript as a vbscript execution engine.
I have exposed the following C# object (I appreciate it doesn't actually execute a query, I'm just testing for now):
public class SCB
{
public ADODB.Recordset executeQuery(string q)
{
ADODB.Recordset _recordset = new ADODB.Recordset();
_recordset.Fields.Append("Id", ADODB.DataTypeEnum.adInteger);
_recordset.Fields.Append("Name", ADODB.DataTypeEnum.adVarChar, 20);
_recordset.Open(System.Reflection.Missing.Value
, System.Reflection.Missing.Value
, ADODB.CursorTypeEnum.adOpenStatic
, ADODB.LockTypeEnum.adLockOptimistic, 0);
_recordset.AddNew(Type.Missing, Type.Missing);
_recordset.Fields["Name"].Value = "Test";
return _recordset;
}
}
}
I have created a vbscript host using:
_engine = new VBScriptEngine(WindowsScriptEngineFlags.EnableDebugging);
And added the class as an object with this line:
_engine.AddHostObject("SCB", HostItemFlags.GlobalMembers, new SCB());
If I run some vbscript code via the following call I receive an error (described below):
_engine.ExecuteCommand(code);
The code I am executing is the following:
Function GetUniversalMessage
dim lRS, sMessage, sColour,sTimeout
Set Lrs = SCB. executeQuery ("SELECT MESSAGE, TIMEOUT, COLOUR, ENABLED FROM U_SCROLLER WHERE SCROLLER_ID=1 AND ENABLED='Y' AND (DISABLE_TIME IS NULL OR DISABLE_TIME>GETDATE())")
if not lRS.EOF then
End If
End Function
I receive an exception that lrs.eof is not a valid field ... but it is valid for an ado com object, and if I check the object created in executeQuery before it returns to the script engine, the EOF field is present.
When I debug by attaching the debugger and calling the stop command, I can see that the lrs object in vbscript does not contain EOF, or most of the valid Recordset fields.
Can someone assist me in explaining what clearscript is doing to the object before it is inserted into the vbscript engine?
Thanks,
Rob
Check whether you're using embedded Interop types. That feature is problematic for scripting because the embedded types are stripped of any members you don't use in managed code.
For example, if you don't use EOF in managed code, the metadata for the EOF property will be left out of the embedded version of Recordset.
In Visual Studio, try setting the Embed Interop Types property of your ADODB reference to False.
Another thing to try would be to change the executeQuery return type to object, or add the attribute [ScriptMember(ScriptMemberFlags.ExposeRuntimeType)].

JINT - Unable to "console.log"

I am new to JINT, and trying to just do some basic tests to kind of learn the ropes. My first attempt was to just store some javascript in my database, load it, and execute it in a unit test. So that looks essentially like this....
[Fact]
public void can_use_jint_engine() {
using (var database = DocumentStore()) {
using (var session = database.OpenSession()) {
var source = session.Load<Statistic>("statistics/1");
// join the list of strings into a single script
var script = String.Join("\n", source.Scripting);
// this will create the script
// console.log("this is a test from jint.");
//
var engine = new Jint.Engine();
// attempt to execute the script
engine.Execute(script);
}
}
}
And it doesn't work, I get this error, which makes absolutely no sense to me, and I cannot find any documentation on.
Jint.Runtime.JavaScriptExceptionconsole is not defined at
Jint.Engine.Execute(Program program) at
Jint.Engine.Execute(String source) at
SampleProject.Installers.Instanced.__testing_installer.can_use_jint_engine()
in _testing_installer.cs: line 318
Can anyone assist in shedding some light on this? I'm pretty confused at this point.
With JavaScript there are three entities - we care about. The host (browser, your application etc), the engine (JINT in this case) and the script ("console.log(...)") in this case.
JavaScript defines a bunch of functions and object as part of the language, but console is not one of them. By convention, browsers define a console object that can be used in the manner you describe. However, since your app is not a browser (and JINT does not do this by itself), there's no console object defined in your namespace (globals).
What you need to do is add a console object that will be accessible in JINT. You can find how to do this in the docs, but here's a simple example of how to add a log function to the engine so it can be used from the JS code (example taken from github).
var engine = new Engine()
.SetValue("log", new Action<object>(Console.WriteLine))
;
engine.Execute(#"
function hello() {
log('Hello World');
};
hello();
");

How to CreateObject in C#?

I want to translate the following VB6 code into C#
If optHost(0).Value Then
Set m_oScpiAccess = New IcSCPIActiveX.IcSCPIAccess
Else
sHost = txtHost.Text
Set m_oScpiAccess = CreateObject("Exfo.IcSCPIActiveX.IcSCPIAccess", sHost)
End If
I used TlbImp.exe to create wrappers for the COM classes, and I tried:
if (string.IsNullOrEmpty(host))
{
// this works
IcSCPIAccess = new IcSCPIAccess();
}
else
{
// throws MissingMethodException
IcSCPIAccess = (IcSCPIAccess)Activator.CreateInstance(
typeof(IcSCPIAccessClass),
host);
}
But there is no constructor which accepts the host parameter
It is not a constructor call. The sHost variable contains the name of a machine, the one that provides the out-of-process COM server. The equivalent functionality is provided by Type.GetTypeFromProgId(), using the overload that allows specifying the server name:
var t = Type.GetTypeFromProgID("Exfo.IcSCPIActiveX.IcSCPIAccess", sHost, true);
obj = (IcSCPIAccess)Activator.CreateInstance(t);
I named it "obj", do avoid giving variables the same name as the interface type. A gazillion things can still go wrong, having the COM server properly registered both on the client and server machine and setting the DCOM security correctly is essential to make this code work. Don't try this until you are sure that the original code works properly.

How do I look up a Corba service with C# and IIOP.NET?

I am writing a C# client for a Corba server and I am using IIOP.NET, going by the example on the following page: http://iiop-net.sourceforge.net/rmiAdderDNClient.html
I have gotten this far without errors:
// Register channel
IiopClientChannel channel = new IiopClientChannel();
ChannelServices.RegisterChannel(channel, false);
// Access COS naming context
CorbaInit init = CorbaInit.GetInit();
NamingContext context = init.GetNameService(host, port);
The variable "host" is a string with the computer name of the server and "port" is an int representing the port number. The values for these are currently used by other systems to connect to the server so I can confirm that they are correct.
However, trying to connect to the trader service yields an exception in runtime. Here is the code I use to do that:
// Looking up VB Trader
NameComponent[] names = new NameComponent[] { new NameComponent("TraderInterface") };
object obj = context.resolve(names);
And here is the error message I'm getting:
"CORBA system exception : omg.org.CORBA.INV_OBJREF, completed: Completed_No minor: 10102."
This seems to suggest an invalid object reference, but what does that mean? Is the string I am passing to the resolve method incorrectly formatted? I have tried many different names for this service as used in other systems, but I always get the same error, which makes me wonder whether I am even interpreting it correctly.
Incidentally, in my desperation, I have also attempted to obtain an object reference from the IOR, but this again throws a different exception (namely omg.org.CORBA.ORB_package.InvalidName).
OrbServices orb = OrbServices.GetSingleton();
object obj = orb.resolve_initial_references(traderIOR);
Any advice is welcome.
I was never able to reach my server with any of the above methods, however the following code is what finally got the communication working:
Hashtable props = new Hashtable();
props[IiopChannel.BIDIR_KEY] = true;
props[IiopServerChannel.PORT_KEY] = port;
// register corba services
IiopChannel channel = new IiopChannel(props);
ChannelServices.RegisterChannel(channel, false);
MyInterface obj = (MyInterface)RemotingServices.Connect(typeof(MyInterface), ior);
I'm not entirely sure why I had to use this (seemingly) unconventional way. Perhaps it is due to the lack of a naming service running on the server. Whatever the cause, I hope this helps somebody out there.

Categories