I have some old VB code to send mails using Lotus Notes that works, I have re-written it into C#, but it behaves differently:
VB:
NotesSession = CreateObject("Notes.Notessession")
NotesDb = NotesSession.GetDatabase("", "")
C#:
_notesSession = new NotesSession();
_notesSession.Initialize(passwordString);
_notesDatabase = _notesSession.GetDatabase( "", "");
First of in C# I need to Initialize the NotesSession with a password, and secondly it will not accept empty string parameters at runtime. Exception is thrown: "A database name must be provided".
In both VB and C# I refer to the same COM : Lotus Domino Objects
I need to be able to call the GetDatabase without specifying the server and database file.
Thanks in advance.
Solution (Thanks guys):
dynamic _notesSession = Activator.CreateInstance(Type.GetTypeFromProgID("Notes.NotesSession"));
_notesDatabase = _notesSession.GetDatabase("", "");
This way you have no intellisense but all properties and methods can be found here
When you create a new instance of the NoteSession type in C# using the new keyword, it will use the COM-interop dll that was referenced by the project at build-time. That is not exactly the same thing as calling CreateObject, which requires no interop dll. The closer equivalent in C# would be:
Type t = Type.GetTypeFromProgID("Notes.Notessession");
_notesSession = Activator.CreateInstance(t);
Or, if you really need to do the exact same thing, you could always add a reference to the Microsoft.VisualBasic.dll library and then call the Microsoft.VisualBasic.Interaction.CreateObject method from C#.
As Richard pointed out in the comments below, the likely reason why you are seeing a difference in behavior is because you are creating two different types of objects. Presumably, when you call new NotesSession in C#, it is using the NotesSession class from the Lotus namespace, rather than the one in the Notes namespace.
Related
Is it possible to create a new PayPal.Payments.DataObjects.TransactionResponse?
I'm currently working on upgrading (our old ERP system) to TLS 1.2, and I need to override a function that returns a PayPal.Payments.DataObjects.TransactionResponse, but PayPal.Payments.Communication.PayflowNETAPI.SubmitTransaction returns a string. Trying to simply create a new PayPal.Payments.DataObjects.TransactionResponse hasn't worked - I'm told in the VB code that:
'PayPal.Payments.DataObjects.TransactionResponse.Private Sub New()' is not accessible in this context because it is 'private'.
Trying in the C# code yields a less descriptive error:
'TransactionResponse' does not contain a constructor that takes 0 arguments
(replacing the 0 with any number of arguments that you put in -- I tried up to 8 or 9)
I am open to solutions in either VisualBasic or C#. Although the function in question is in VB, we opted to send our transactions to an internal processing server, which will return the string (written in C#), so I can do this from either side.
Basically, I just need to take the response (currently in string format), probably parse it (although a straight string conversion would be fine too), and put the info into a PayPal.Payments.DataObjects.TransactionResponse.
You have source code here.
You can check which parameter send to the constructor.
From a quick read of the Paypal SDK code mentioned by Ygalbel, it looks like there is no new() function. Rather, you would declare your var of type PayPal.Payments.DataObjects.TransactionResponse and then use the set and get accessors to set/get data in the class.
I’m trying to pass a COM object from C# code to Perl.
At the moment I’m wrapping my Perl code with PerlNET (PDK 9.4; ActiveState) and I have defined a simple subroutine (+ required pod declaration) in Perl to pass objects from C# to the wrapped Perl module.
It seems that the objects I pass are not recognized correctly as COM objects.
An example:
In C# (.NET 4.0), the ScriptControl is used to load a simple class from a file written in VBScript.
var host = new ScriptControl();
host.Language = "VBScript";
var text = File.ReadAllText("TestScript.vbs");
host.AddCode(text);
dynamic obj = host.Run("GetTestClass");
What I get (obj) is of type System.__ComObject. When I pass it to my Perl/PerlNET assembly and try to call method Xyz() in Perl I get the following (runtime) exception:
Can't locate public method Xyz() for System.__ComObject
If, however, I do more or less the same thing in Perl, it works. (In the following case, passing only the contents of my .vbs file as parameter.)
I can even use the script control :
sub UseScriptControl {
my ($self, $text) = #_;
my $script = Win32::OLE->new('ScriptControl');
$script->{Language} = 'VBScript';
$script->AddCode($text);
my $obj = $script->Run('GetTestClass');
$obj->Xyz();
}
Now, calling Xyz() on obj works fine (using Win32::OLE).
In both cases I use:
use strict;
use Win32;
use Win32::OLE::Variant;
Another approach:
I can invoke methods by using InvokeMember of class System.Type if I specify exactly which overload I want to use and which types I’m passing:
use PerlNET qw(typeof);
typeof($obj)->InvokeMember("Xyz",
PerlNET::enum("System.Reflection.BindingFlags.InvokeMethod"),
PerlNET::null("System.Reflection.Binder"),
$obj,
"System.Object[]"->new());
Using this approach would mean rewriting the whole wrapped Perl module. And using this syntax..
Now I am wondering if I am losing both the advantages of the dynamic keyword in .NET 4.0 and the dynamic characteristics of Perl (with Win32::OLE) by using PerlNET with COM objects.
It seems like my preferred solution boils down to some way of mimicking the behaviour of the dynamic keyword in C#/.NET 4.0.
Or, better, finding some way of converting the passed COM object to something that will be recognized as compatible with Win32::OLE. Maybe extract some information of the __ComObject for it to be identified correctly as COM object.
I have to add that I posted to the PDK discussion site too (but didn’t get any response yet): http://community.activestate.com/node/18247
I also posted it to PerlMonks - as I'm not quite sure if this is more a Perl or C#/.NET question:
http://www.perlmonks.org/?node_id=1146244
I would greatly appreciate any help - or advise on where to look further.
I am writing a scripting engine for my game using the LuaInterface library. I am getting an error when attempting to instantiate the class in Lua. The error is:
"./Scripts/sv_worldgen.lua:2: attempt to call global 'Campfire' (a string value)"
Where sv_worldgen.lua is (in entirety):
function GenerateChunk(worldChunk, chunkGridPosition)
tf = Campfire()
tf:SetPosition(chunkGridPosition)
end
Campfire is a class in C#, and appears to be exposed to lua as per the CLRPackage example and of course the LuaInterface Reference. I cannot seem to get around this error, and I have done due diligence of searching. The only other behavior of the script I can manage throws a similar error, but where it is "(a table value)". What am I doing wrong? Thank you in advance!
I tried explicitly doing Campfire._ctor(), but _ctor() is a string value.
This was resolved by using CLRPackage and using it to first load the assembly.
//Lua
JASG = CLRPackage("JASG", "JASG")
Then and only then can you link the classname to the actual C# class using (this must be done before trying to access it in Lua):
//Lua
Campfire=JASG.Campfire;
and then normal instantiation can occur by
//Lua
cf = Campfire()
I am converting some code from VB.NET to C#. In VB.NET, I have this code:
Dim ind As Foo.Index
Dim ed As Foo.Edit
ind = New Foo.Index
ed = ind.InFunction()
That works. So in C# my code will look like this:
Foo.Index ind;
Foo.Edit ed;
ind = New Foo.Index();
ed = ind.InFunction();
But this doesn't work. I am sure that I did not forget to import namespaces. And now I've been wondering, is there any difference between those two?
EDIT:
And I finally add
ed = New Foo.Edit();
into my C# code, but it also doesn't work. IMHO, I think there is a feature in VB.NET that allows auto initializing in variables (like the comment from Bex below suggests). Is it true?
FINAL:
Seems I do need to show all the code. But I need to talk directly to you as well (or you just install the software of mine). It makes me really confused. Thank you all. Sorry for this kind of newbie question.
C-like languages (like C#) require you follow the pattern of [type] [variable name] at a minimum. C#, using the simplest form of initialization, requires you to use the new keyword.
A simple C# class definition:
class Foo
{
public Foo()
{
}
}
Then, to initialize an instance:
Foo myFooIsStrong = new Foo();
//instantiation
IndexServer.ClientInfo ci = new IndexServer.ClientInfo();
IndexServer.IXServicePortC konst = new IndexServer.IXServicePortC();
IndexServer.IndexServer ix = new IndexServer.IndexServer();
IndexServer.EditInfo ed = new IndexServer.EditInfo();
I don't quite understand what you are asking but this may help.
VB auto initializes a lot of variables and c# doesn't.
So in c# you should initialize your variables.
The problem is that vb.net let's you import namespace roots, while C# requires you to import the full namespace. Your VB code has a statement like this at the top:
Imports MyLibrary
This puts the MyLibrary namespace sort of "in scope", such that you can use the type MyLibrary.Foo.Index either through the full name or by simply saying Foo.Index. C# does not allow this. You must either also import MyLibrary.Foo or reference the entire name in your code.
C# is case sensitive. So the
ed = New Foo.Edit();
should be
ed = new Foo.Edit();
Here's an example
using IndexServer;
...
IndexServer ix = new IndexServer();
ClientInfo ci = new ClientInfo();
EditInfo ed = ix.checkoutSord(ci, Konstanta.EDIT_INFO.mbSord, Konstanta.LOCK.NO);
Without knowing what those classes look like, hard to tell you more. But instantiation is basically the same, just need to change some syntax for declaring variable.
From Visual Studio I imported a WSDL via the Service References tool. From the methodsin the WSDL I need to call a method GetSessionID. The method is part of an Interface IdoSession. When I try to reference it in C# the compiler keeps telling me I am doing it wrong. What would be the correct syntax to call the GetSessionID method?
If I use this code
SSISSoapTester.IdoSession.IdoSession getID;
idResponse = getID.GetSessionID(idRequest);
The compiler tells me "Use of unassigned local varible 'getID'
If I use this code
SSISSoapTester.IdoSession.IdoSession getID;
getID = new SSISSoapTester.IdoSession.IdoSession();
idResponse = getID.GetSessionID(idRequest);
The compiler tells me "Cannot create an instance of the abstract calls or interface"
Granted this error makes sense to me because an interface is not a class.
It is hard to tell based on what you posted (please post actual code in the future), but I am guess ing that IdoSessionClient implements the IdoSession interface, which is what you have selected in your screenshot. In that case, you probably want to do something similar to:
GetSessionIdRequest request = new GetSessionIdRequest();
IdoSession client = new IdoSessionClient();
client.GetSessionId(request);