简体   繁体   中英

start sapgui failed while hosting application in IIS

I am trying to connect to SAP system using SAP Connector 3.0 to read Documents information (through my ASP.Net MVC application). When I run the application through Visual studio 2012 , SAP logon screen launches and my application shows the data after reading from SAP BAPI's . But when I deploy the same application using Visual Studio's Publish option on the same Computer and then run the application I get

 Start 'sapgui' failed.

Below is the code for reading SAP data in ASP.Net application

var documentList =  Global.SAPRepository.CreateFunction("BAPI_DOCUMENT_CHECKOUTVIEW2");
documentList.Invoke(Global.SAPDestination);

documentList.SetValue("DOCUMENTTYPE", "TPK");
documentList.SetValue("DOCUMENTNUMBER", "2000-ABC-T01-TPK");
documentList.SetValue("DOCUMENTPART", "000");
documentList.SetValue("DOCUMENTVERSION", "A0");

var documentData = documentList.GetTable("DOCUMENTFILES");
documentList.Invoke(Global.SAPDestination);//execute query

var docNo = documentData.GetString("DOCUMENTNUMBER");
var type = documentData.GetString("DOCUMENTTYPE");
var version = documentData.GetString("DOCUMENTVERSION");

While here is the code for connecting to SAP Destination.

public RfcConfigParameters GetParameters(string destinationName)
    {
        RfcConfigParameters parms = new RfcConfigParameters();
        if ("Dev".Equals(destinationName))
        {
            parms.Add(RfcConfigParameters.AppServerHost, "192.168.x.xx");
            parms.Add(RfcConfigParameters.SystemNumber, "00");
            parms.Add(RfcConfigParameters.User, "myuserName");
            parms.Add(RfcConfigParameters.Password, myPassword);
            parms.Add(RfcConfigParameters.Client, "900");
            parms.Add(RfcConfigParameters.Language, "EN");
            parms.Add(RfcConfigParameters.PoolSize, "5");
            parms.Add(RfcConfigParameters.UseSAPGui, "1");
            parms.Add(RfcConfigParameters.PeakConnectionsLimit, "10");
            parms.Add(RfcConfigParameters.ConnectionIdleTimeout, "600");
        }
        return parms;
    }

Just set the UseSAPGui configuration parameter to "0". You cannot use the interactive logon dialog (which is a Windows dialog) when running as an ASP.NET application. SAPGui does not open in "unattended mode" - that is, when there will be no user to interact with dialogs.

The other problem, callbacks not supported, is discussed here:
Calling BAPI_DOCUMENT_CHECKOUTVIEW2 using SAP.Net Connector 3.0 returns "RFC Callback server not available"

The solution seems to be to set UseSAPGui to 1 to enable the callback, which you cannot do. So this is a dead end. Recommendation is to use an alternative BAPI that is fully RFC-enabled, or write a custom wrapper (in ABAP) that does not involve the callback.

So basically it turns out that since my application is hosted in IIS and IIS is running as a Windows service and it does not allow to launch other processes that will interact with Desktop. Since BAPI_DOCUMENT_CHECKOUTVIEW2 tries to launch SAPGUI process, therefore it throws error message.

So the solution I implemented is that I wrote a WCF service that I hosted in a Managed Windows Console Application like below (simple Windows Console Application in VS 2012).

Service Interface definition goes here

[ServiceContract]
public interface IMyService
{
    [OperationContract]
    string ViewDocuments();
}

Service implementation class goes here

public class MyService : IMyService
{
    public string ViewDocuments()
    {
        var documentList = Global.SAPRepository.CreateFunction("BAPI_DOCUMENT_CHECKOUTVIEW2");
        documentList.Invoke(Global.SAPDestination);

        documentList.SetValue("DOCUMENTTYPE", "TPK");
        documentList.SetValue("DOCUMENTNUMBER", "2000-Abc-T01-TPK");
        documentList.SetValue("DOCUMENTPART", "000");
        documentList.SetValue("DOCUMENTVERSION", "A0");

        var documentData = documentList.GetTable("DOCUMENTFILES");
        documentList.Invoke(Global.SAPDestination);//execute query

        var docNo= documentData.GetString("DOCUMENTNUMBER");
        var type = documentData.GetString("DOCUMENTTYPE");
        var version = documentData.GetString("DOCUMENTVERSION");
        return docNo;
    }
}

And the Main method of the Console application is

class Program
{
    static void Main(string[] args)
    {
        Uri baseAddress = new Uri("http://localhost:8085/hello");

        // Create the ServiceHost.
        using (ServiceHost host = new ServiceHost(typeof(MyService), baseAddress))
        {
            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            smb.HttpGetEnabled = true;
            smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
            host.Description.Behaviors.Add(smb);
            host.Open();

            Console.WriteLine("The service is ready at {0}", baseAddress);
            Console.WriteLine("Press <Enter> to stop the service.");
            Console.ReadLine();

            // Close the ServiceHost.
            host.Close();
        }
    }
}

I have added reference to System.ServiceModel in the Console Application as well.

Then I consumed this service in my Asp.Net application, every thing worked like a charm!!!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM