View Single Post
  #2 (permalink)  
Old 08-22-2006, 11:12 AM
corcoranp corcoranp is offline
Registered User
 
Join Date: Aug 2006
Posts: 0
CMS Howto with C#

madhombre,

There are some basic issues I want to mention before answering this question.

First, what you are wanting to do is use native COM objects, which is unmanaged within the .Net world which is managed code. That being said, .Net usually does a good job handling COM Interop, but in this case I think it’s bombing. Short of writing our own COM Interop for these set of dlls (and exes), I think I have a resolution to your problem.

Before we get into to it, I’d like to take a look at the difference between what’s happening when you call the CreateServer method in VB and in .Net.

The first think to remember is that C# is VERY type specific (or “strongly typed” for all the vocabulary police out there). VB on the other hand is NOT. What does that mean? Well in this example it means that although you have declared the following objects:
1. application (cvsup.cvsApplication or AVSUP.cvsApplicationClass),
2. connection (CVSCN.cvsConnection or AVSCN.cvsConnectionClass),
3. server (CVSSUPSRV.cvsServer or AVSSUPSRV.cvsServer), and
4. report (CVSREP.cvsReport or AVSREP.cvsReportClasss) objects

…there are still 2 more you are missing.

The funny thing about VB is that it doesn’t care about declaring these classes (or using them to cast objects), unfortunately C# cares a great deal.

The other thing and I can only assume you are doing this, you are adding the dlls (or exes) as a reference in .Net, which should be creating a set of Interop dlls. That being the case, when you call the CreateServer method of the cvsApplication objects you are probably seeing 2 processes appear in task manager for cvsSrv.exe…correct?

I think I have answer but it will probably take someone a little more technical than I to fully explain this, but here goes…

The first instance of cvsSrv.exe (or avsSrv.exe in my case (different CMS version but same issues)) is from this line of code:
CVSUPSRV.cvsServer cvsSrv = new CVSUPSRV.cvsServer();

The second instance is from the CreateServer method itself.

For some reason, even though you are passing in a reference object (ref srv) the cvsApplication method does not use the reference but creates a new object in memory (I think it’s Interop related).

I know what you are asking: How does all this relate to your problem and how do we fix it??

Well, if the CreateServer method is creating a NEW object in memory and NOT using the REFERENCE you passed to it, then you don’t have a variable within your scope that points to the created server in memory.

I’ll say that again…

Well, if the CreateServer method is creating a NEW object in memory and NOT using the REFERENCE you passed to it, then you don’t have a variable within your scope that points to the created server in memory.

So that is that, if someone has a better explanations please feel free.



But wait there’s more! The How do we fix it part?

Well here is what I did, which I think is the easy way and avoids having to write your own COM Interop or mixing managed and unmanaged code within C#.

First, because of the issues with C# which creates multiple servers in memory I needed a way to call the cvsApplication object’s CreateServer method and still have a reference to it. Since, the CVS dlls are COM I figured I could write an ActiveX Dll in VB6 and import it into my c# references. Now granted this is still a band-aid approach but it still works!

Here is the VB6 Class I wrote (no error detection/correction, or tracing included):
NOTE: On the project’s properties page, on the “Make” tab, I added “cms” as the application’s title, and on the “General” tab “cms” as the project name.


Dim cmsApplication As AVSUP.cvsApplication
Dim cmsConnection As AVSCN.cvsConnection
Dim cmsServer As AVSUPSRV.cvsServer

Private Sub Class_Initialize()
'
Set cmsApplication = New AVSUP.cvsApplication
Set cmsConnection = New AVSCN.cvsConnection
Set cmsServer = New AVSUPSRV.cvsServer

End Sub

Property Get cmsSrv() As Object
Set cmsSrv = cmsServer
End Property

Public Sub CreateServer(UserName As String, Password As String, Server As String)

If cmsApplication.CreateServer(UserName, "", "", Server, False, "ENU", cmsServer, cmsConnection) Then
If cmsConnection.Login(UserName, Password, Server, "ENU", "", False) Then
End If
End If
End Sub


Of course the with the Dll version you are using, the code would look like this:

Dim cmsApplication As CVSUP.cvsApplication
Dim cmsConnection As CVSCN.cvsConnection
Dim cmsServer As CVSUPSRV.cvsServer

Private Sub Class_Initialize()
'
Set cmsApplication = New CVSUP.cvsApplication
Set cmsConnection = New CVSCN.cvsConnection
Set cmsServer = New CVSUPSRV.cvsServer

End Sub

Property Get cmsSrv() As Object
Set cmsSrv = cmsServer
End Property

Public Sub CreateServer(UserName As String, Password As String, Server As String)

If cmsApplication.CreateServer(UserName, "", "", Server, False, "ENU", cmsServer, cmsConnection) Then
If cmsConnection.Login(UserName, Password, Server, "ENU", "", False) Then
End If
End If
End Sub


Once I created the dll, I added as a reference my c# project. At that point it was as easy as calling my new class and creating a server instance:


(In C#)

cms.ConnectorClass cc = new cms.ConnectorClass();
cc.CreateServer(“userid”, “pass”, “servername”);


This creates a CVS Server object in memory and we can now call it using the property in the VB class:

…cc.cmsSrv.ToString()..

(above code should return type info)


Well, I assume your next set is to populate the server with info so you can run some reports against it. This is where those 2 other objects come into play.

In Visual Studio you need to add a reference to the cvsCTLG.dll (something like: C:\Program Files\Avaya\CMS Supervisor V11\cvsCTLG.dll). And if you haven’t already added avsSrv.exe add it too.

Now to populate the Server so you can run reports you have to populate the server’s Catalog (1 of the new objects) based on your call management system’s ACD, AND depending on the report type you are interested in…

If you need Dictionary reports which are more like system reports, like agent extensions, system definitions, etc.; you will need to populate the Dictionary catalog on the server object

If you need access to your custom Reports or generic reports you will need to populate the Report Catalog on the server object

EXAMPLES:

//My Dictionary Example
((AVSCTLG.cvsCatalogClass)((AVSUPSRV.cvsServerClas s)cc.cmsServer).Dictionary).ACD = 2;

//Your Dictionary Example
((CVSCTLG.cvsCatalogClass)((CVSUPSRV.cvsServerClas s)cc.cmsServer).Dictionary).ACD = 2;


//My Report Example:
((AVSCTLG.cvsCatalogClass)((AVSUPSRV.cvsServerClas s)cc.cmsServer).Report).ACD = 2;

//Your Report Example:
((CVSCTLG.cvsCatalogClass)((CVSUPSRV.cvsServerClas s)cc.cmsServer).Report).ACD = 2;



So what does setting this property do??? It populates the corresponding catalog.

You might be a little confused right now but let me attempt to clear it up…

The Dictionary and Report catalog is a VBA.Collection. This collection houses the 2nd of the new objects I need to introduce the ReportInfo class. The ReportInfo class is used with a CVSREP.cvsReport (AVSREP.cvsReport) class to create a report object.

To see what reports you have access to you can do the following:

//My Example:
foreach(object o in ((AVSCTLG.cvsCatalogClass)((AVSUPSRV.cvsServerClas s)cc.cmsServer).Dictionary).Reports)
{
Console.WriteLine(((AVSCTLG.cvsReportInfoClass)o). Name.ToString());
}

//Your Example:
foreach(object o in ((CVSCTLG.cvsCatalogClass)((CVSUPSRV.cvsServerClas s)cc.cmsServer).Dictionary).Reports)
{
Console.WriteLine(((AVSCTLG.cvsReportInfoClass)o). Name.ToString());
}


These loops will give you the name of every report listed in the Dictionary Catalog.


The remainder of the C# code (creating the report) should be a piece of cake after this. Just remember to cast your objects to the appropriate type and you should be good.

Let me know if you have any questions and I’ll see if I can work them out.

I also rolled the reporting object up into a class if anyone is interested let me know and I’ll post it.


Thanks.
Reply With Quote