cancel
Showing results for 
Search instead for 
Did you mean: 

C# BI Query issue

0 Kudos

Hello,

I'm trying to write a function in C# that would return a query size.

Using:

  • Visual Studio 2015 Community Edition ( ver 14.0.25431.01 Update 3 )
  • Microsoft .NET Framework 4.6.01590

Below is just a simple function that should return the number of instances in "Running" state, that are running for more than one hour.

Assembly used:

  • BusinessObjects.Enterprise.Sdk - Version 14.0.2000.0
  • BusinessObjects.Foundation.Logging - Version 14.0.2000.0
using BusinessObjects.Enterprise.Framework; 
using BusinessObjects.Enterprise.Infostore

static void checkBOv2()
{
string username = "Administrator";
string password = "password";
string cmsname = "CMSNODE1:6400";
string authType = "secEnterprise";
string now = DateTime.Now.ToString("yyyy.MM.dd.HH:mm:ss");
string then = DateTime.Now.AddHours(-1).ToString("yyyy.MM.dd.HH:mm:ss");
String query = "SELECT SI_PID FROM CI_INFOOBJECTS WHERE SI_INSTANCE=1 and SI_SCHEDULE_STATUS=3 and SI_STARTTIME BETWEEN'" + then + "' AND'" + now + "'";

IEnterpriseSession ceSession = null;
ceSession = CrystalEnterprise.GetSessionMgr().Logon(username, password, cmsname, authType);

try
{
IInfoStore iStore = (IInfoStore)(ceSession.GetService("InfoStore"));
IInfoObjects queryResult = iStore.Query(query);
int querySize = queryResult.ResultSize;
Console.WriteLine(querySize);
}
catch (Exception e)
{
ceSession.Logoff();
Console.WriteLine(e);
}
finally
{
if (ceSession != null) ceSession.Logoff();
}
}

At the moment I receive two errors:

log4net:ERROR XmlHierarchyConfigurator: 
Could not create Appender [A1] of type [BusinessObjects.Foundation.Logging.Log4net.RollingFileAppender, BusinessObjects.Foundation.Logging, Version=12.0.0.0, Culture=neutral, PublicKeyToken=692fbea5521e1304]. 
Reported error follows. 
System.IO.FileLoadException: Could not load file or assembly 'BusinessObjects.Foundation.Logging, Version=12.0.0.0, Culture=neutral, PublicKeyToken=692fbea5521e1304' or one of its dependencies. 
The located assembly's manifest definition does not match the assembly reference. 
(Exception from HRESULT: 0x80131040) File name: 'BusinessObjects.Foundation.Logging, Version=12.0.0.0, Culture=neutral, PublicKeyToken=692fbea5521e1304'

Managed to resolve the above error with the below config info added into App.config:

<dependentAssembly>
<assemblyIdentity name="BusinessObjects.Foundation.Logging" publicKeyToken="692fbea5521e1304" culture="neutral"/>
<bindingRedirect oldVersion="12.0.0.0" newVersion="14.0.2000.0"/>
</dependentAssembly>

Second error that I can't resolve, even if the file is in the bin folder:

Unhandled Exception: System.TypeInitializationException: The type initializer for 'BusinessObjects.Enterprise.Security.Internal._LogonEx3Proxy' threw an exception. ---> System.IO.FileLoadException: Cou
ld not load file or assembly 'BusinessObjects.Enterprise.Sdk.Ssl.netmodule' or one of its dependencies. A dynamic link library (DLL) initialization routine failed. (Exception from HRESULT: 0x8007045A)
   at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMarkHandle stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromP
artialName, ObjectHandleOnStack type)
   at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartia
lName)
   at System.RuntimeType.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark)
   at System.Type.GetType(String typeName)
   at BusinessObjects.Enterprise.Security.Internal._LogonEx3Proxy..cctor()
   --- End of inner exception stack trace ---
   at BusinessObjects.Enterprise.Security.Internal._LogonEx3Proxy..ctor(IProxyHandler handler)
   at BusinessObjects.Enterprise.Security.Internal.LogonService.ensureServiceStub()
   at BusinessObjects.Enterprise.Security.Internal.LogonService.userLogon(String user, String pwd, String auth)
   at BusinessObjects.Enterprise.Security.Internal.SecurityMgr.userLogon(String user, String pwd, String aps, String socksURI, String cluster, String auth)
   at BusinessObjects.Enterprise.Framework.Internal.SessionMgr.Logon(String user, String password, String cmsName, String auth)

I have this working as .asp in tomcat web apps and is running successfully but uses different libraries. ( I use the wrong libraries in C# ? )

<%@ page import="com.crystaldecisions.sdk.framework.CrystalEnterprise"%>
<%@ page import="com.crystaldecisions.sdk.framework.IEnterpriseSession"%>
<%@ page import="com.crystaldecisions.sdk.occa.infostore.IInfoObject"%>
<%@ page import="com.crystaldecisions.sdk.occa.infostore.IInfoObjects"%>
<%@ page import="com.crystaldecisions.sdk.occa.infostore.IInfoStore"%>
<%@ page import="com.crystaldecisions.enterprise.ocaframework.*"%>

Accepted Solutions (1)

Accepted Solutions (1)

DellSC
Active Contributor

I see what the issue is - you need to be referencing CrystalDecisions.Enterprise.Framework and CrystalDecisions.Enterprise.InfoStore in your application. Then, in your code you'll just need "using CrystalDecisions.Enterprise;" to be able to work with both of them.

When you add these to the References section of your project, be sure to go to the properties for each and set "Embed Interop Types" to false.

In terms of best practices, I would rewrite your code to this:

using CrystalDecisions.Enterprise; 

static void checkBOv2()
{
  string username = "Administrator";
  string password = "password";
  string cmsname = "CMSNODE1:6400";
  string authType = "secEnterprise";
  string now = DateTime.Now.ToString("yyyy.MM.dd.HH:mm:ss");
  string then = DateTime.Now.AddHours(-1).ToString("yyyy.MM.dd.HH:mm:ss");
  String query = "SELECT SI_PID FROM CI_INFOOBJECTS WHERE SI_INSTANCE=1 and SI_SCHEDULE_STATUS=3 and SI_STARTTIME BETWEEN'"   + then + "' AND'" + now + "'";

  IEnterpriseSession ceSession = null;
  try
  {
    ceSession = CrystalEnterprise.GetSessionMgr().Logon(username, password, cmsname, authType);
    IInfoStore iStore = (IInfoStore)(ceSession.GetService("InfoStore"));
    using (IInfoObjects queryResult = iStore.Query(query)){
      int querySize = queryResult.ResultSize;
      Console.WriteLine(querySize);
    }
} catch (Exception e) { Console.WriteLine(e); } finally { if (iStore != null) iStore.Dispose(); if (ceSession != null) { try { ceSession.Logoff(); ceSession.Dispose(); } catch { //Eat the error. This is needed to prevent errors when debugging. In a //"normal" run, these errors are ignored. } } } }

Much of the .NET SDK is based on COM objects, which .NET doesn't necessarily memory manage well. Best practice is to do one of two things:

1. Create objects in a "using" clause so that to program automatically calls .Dispose() on them when the pass out of scope.

2. Explicitly call .Dispose() on the object when you're finished with it.

I've use both techniques in the code above.

-Dell

daniel_paulsen
Active Contributor

in addition to using the CrystalDecisions assemblies that Dell pointed out, you should make every effort to ensure that you are using the correct version (14.x) of the assemblies. These should match the same version that the back end is running (minor version + support package version). An assembly redirect is a simple workaround but may not work in all cases. The correct ".netmodule" binary is most likely not found (there's 32 bit and 64bit versions), but another thing to consider is the version of BOE that you are connecting to. Compilers were updated starting with BI4.1 SP10 and BI4.2 SP4. If you are using one of these versions or higher you will need to ensure you are using the .NET Framework 3.5 or higher and all runtime is updated

Dan

DellSC
Active Contributor

Also, the security libraries were all updated with 4.2 SP4. In the past, you could connect using an different version of the SDK than the platform version on the server (NOT recommended, but it could be done...) However, if you're on 4.2 SP4 or newer, you'll have to have the same version of the SDK in order to log in to the CMS server.

-Dell

Answers (1)

Answers (1)

0 Kudos

Hello,

Thank you for your feedback on this issue.

Changing only the CrystalDecisions.Enterprise.Framework and CrystalDecisions.Enterprise.InfoStore references didn't resolve the issue.

I've found some examples here:

https://archive.sap.com/documents/docs/DOC-50603#jive_content_id_C#_Managed_BOE_/_BI_sample_applicat...

http://www.sdn.sap.com/irj/scn/index?rid=/library/uuid/e0cde7b2-05e2-2e10-cab0-86ee7ca46e62

I've had to update the code if I wanted to make this work, based on the above example:

            using CrystalDecisions.Enterprise;

....

string username = "Administrator";
string password = "password";
string cmsname = "CMSNODE1:6400";
string authType = "secEnterprise";
string now = DateTime.Now.ToString("yyyy.MM.dd.HH:mm:ss");
string then = DateTime.Now.AddHours(-1).ToString("yyyy.MM.dd.HH:mm:ss");
String query = "SELECT SI_PID FROM CI_INFOOBJECTS WHERE SI_INSTANCE=1 and SI_SCHEDULE_STATUS=3 and SI_STARTTIME BETWEEN'" + then + "' AND'" + now + "'";

EnterpriseSession boEnterpriseSession = null;
EnterpriseService boEnterpriseService;
SessionMgr boSessionMgr = null;
InfoStore boInfoStore = null;
InfoObjects boInfoObjects = null;

boSessionMgr = new CrystalDecisions.Enterprise.SessionMgr();
boEnterpriseSession = boSessionMgr.Logon(userName, password, cmsName, authentication);
try
{
boEnterpriseService = boEnterpriseSession.GetService("", "InfoStore");
boInfoStore = new InfoStore(boEnterpriseService);
boInfoObjects = boInfoStore.Query(queryString);
int querySize = boInfoObjects.ResultCount;
Console.WriteLine(querySize);
}
...

but I get the following error:

System.Runtime.InteropServices.COMException (0x80045701): Internal error.
   at CrystalDecisions.Enterprise.Internal.SessionMgrClass.Logon(String UserName, String Password, String CMSName, String Authentication)
   at CrystalDecisions.Enterprise.SessionMgr.Logon(String userName, String password, String cMSName, String authentication)

  • This is complied as 32 bits as I use the 32 libraries for Crystal Enterprise
  • Embeded Interop Types is set to false on all the Crystal references

Compared my local assembly dll's with the server and they are the same versions ( only difference is that the server is running on 64 bits )

Any ideeas ?

0 Kudos

I've removed all the SDK's that I had installed and remained with the BI Client libraries.

The app now works using the 32 bits build.