Skip to Content

C# BI Query issue

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.*"%>

Add comment
10|10000 characters needed characters exceeded

  • Get RSS Feed

2 Answers

  • Best Answer
    Jul 11, 2018 at 01:55 PM

    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

    Add comment
    10|10000 characters needed characters exceeded

    • 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

  • Jul 16, 2018 at 08:48 AM

    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_applications
    
    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 ?

    Add comment
    10|10000 characters needed characters exceeded