WebService调用C++dll在XP下IIS5.1发布问题

环境:windowsxp sp3+IIS5.1+Arcgis server10


问题描述:WebService调用C++dll在XP下IIS5.1发布后始终没有返回值,但是在调试状态下一切正常。在网上泡了3天,总算解决了。


由于WebGis项目需求, 项目采取vs2010开发,语言采用C#及silverlight, GIS发布采用arcgis server10 , 通过arcgis silverlight api访问地图。

WebGis地图上的电力开关实时状态需要从另一套系统(配网监控系统,C++开发的)中获取,所有就用了webservice来实现,具体就是在配网监控系统中写了个webgis_service进程(守护的)和一个librealdata.dll(这两都是基于C/C++的),

其中在librealdata.dll提供了通过传入参数获取某些电力开关实时状态的接口,如下:

int  LIBREALDATA_API __stdcall GetKgRealData(char *comenames, char** retval);


而webservice中调用如下(GisRealData.asmx.cs中):


 #region 实时数据获取类

 public class GisRealData : System.Web.Services.WebService
    {


        [WebMethod]
        public string HelloWorld()
        {
            return "Hello World";
        }


        [WebMethod]
        public byte[] GetKG_RealData(byte[] comenames)
        {
            IntPtr retptr;


            int retval = 0;
            try
            {
                retval = GetKgRealData(comenames, out retptr);
            }
            catch (Exception ex)
            {
                string str = ex.Message;
                throw new Exception("获取数据失败!");
            }


            if (retval <= 0)
            {
                return null;
            }


            byte[] retdata = new byte[retval];


            for (int i = 0; i < retval; i++) retdata[i] = Marshal.ReadByte(retptr, i);


            FreeRealDataMem(retptr);


            return retdata;
            //return Convert.ToBase64String(retdata);
        }

  [DllImport("C:\\xxxx\\dll\\librealdata.dll", CharSet = CharSet.Ansi, EntryPoint = "GetKgRealData", ExactSpelling = false)]
        public static extern int GetKgRealData(byte[] comenames, out IntPtr retval);
        [DllImport("C:\\xxxx\\dll\\librealdata.dll", CharSet = CharSet.Ansi, EntryPoint = "FreeRealDataMem", ExactSpelling = false)]
        public static extern void FreeRealDataMem(IntPtr retval);
    }
    #endregion
}


在silverlight中添加服务引用



在silverlight中调用(MainPage.xaml.cs)

MainPage函数中如下:

.....

        public GisRealDataSoapClient    m_soapclient;

  //EndpointAddress real_address = new EndpointAddress(new Uri(Application.Current.Host.Source, "/GisRealData.asmx"));        //VS2010调试用
        EndpointAddress real_address = new EndpointAddress(new Uri(Application.Current.Host.Source, "/WebGis/GisRealData.asmx"));   //IIS发布用


        BasicHttpBinding real_BasicHttpBinding = new BasicHttpBinding();
        real_BasicHttpBinding.MaxBufferSize = 2147483647;
        real_BasicHttpBinding.MaxReceivedMessageSize = 2147483647;
        real_BasicHttpBinding.OpenTimeout = new TimeSpan(0, 1, 0);
        real_BasicHttpBinding.CloseTimeout = new TimeSpan(0, 1, 0);
#if DEBUG
        real_BasicHttpBinding.SendTimeout = new TimeSpan(18, 10, 00);
        real_BasicHttpBinding.ReceiveTimeout = new TimeSpan(18, 10, 00);
#else
        real_BasicHttpBinding.SendTimeout = new TimeSpan(0, 5, 00);
        real_BasicHttpBinding.ReceiveTimeout = new TimeSpan(0, 5, 00);
#endif
        m_soapclient = new GisRealDataSoapClient(real_BasicHttpBinding, real_address);
        m_soapclient.GetKG_RealDataCompleted += new EventHandler<GetKG_RealDataCompletedEventArgs>(GetKG_RealDataCompleted);

        m_soapclient.HelloWorldCompleted += new EventHandler<HelloWorldCompletedEventArgs>(HelloWorldCompleted);
        m_soapclient.HelloWorldAsync();

.....

}


//获取开关、刀闸实时数据,此函数在一个线程中调用
        public void GetKgRealData()
        {
            if (m_soapclient == null || m_kgparabyte == null) return;
            m_soapclient.GetKG_RealDataAsync(m_kgparabyte);
        }


 //WEB SERVICE测试
        public void HelloWorldCompleted(object sender, HelloWorldCompletedEventArgs e)
        {
            try
            {
                if (e.Result != null)
                {
                    HtmlPage.Window.Alert(e.Result.ToString());
                }
            }
            catch (Exception error)
            {
                string errmsg = error.ToString();
            }
        }


        //取得开关实时数据响应函数
        public void GetKG_RealDataCompleted(object sender, GetKG_RealDataCompletedEventArgs e)
        {
            try
            {
                if (e.Result != null)
                {
                    byte[] resultbyte = e.Result;


                    WEBGIS_RETKGPARAM retkgdata = null;


                    MyConvert.Byte2KGStruct(resultbyte, 0, out retkgdata);


                     //线程异步的委托更新UI用此种写法,不更新就不用了
                    this.Dispatcher.BeginInvoke(() =>
                    {
                        RenderPDKGSymbols(retkgdata);
                    });
                }
            }
            catch (Exception error)
            {
                string errmsg = error.ToString();
            }
        }


web.config配置如下:

<?xml version="1.0"?>

<!--

  有关如何配置 ASP.NET 应用程序的详细消息,请访问

  http://go.microsoft.com/fwlink/?LinkId=169433

  -->

<configuration>

  <system.web>

    <compilation debug="true" targetFramework="4.0">

    </compilation>

    <httpRuntime maxRequestLength="65535" executionTimeout="36000" useFullyQualifiedRedirectUrl="false" />

    <webServices >

      <protocols >

        <add name="HttpSoap"/>

        <add name="HttpPost"/>

        <add name="HttpGet"/>

        <add name="Documentation"/>

      </protocols>

    </webServices>

  </system.web>

  <appSettings>

    <add key="SDE_SQLServerConnString" value="Data Source=10.1.1.57;UID=sa;PWD=xxxx;DATABASE=Esri_SDE "/>

    <add key="SQLServerConnString" value="Data Source=10.1.1.57;UID=sa;PWD=xxxx;DATABASE=WebGIS "/>

    <add key="MapServiceURL" value="http://10.1.1.57/ArcGIS/rest/services/webGIS_jx/MapServer"/>

    <add key="MapFullExtent" value="113.764813|38.266093|114.404081|37.662598"/>

    <add key="FeatureServiceURL" value="http://10.1.1.57/ArcGIS/rest/services/webGIS_layer"/>

  </appSettings>

  <system.serviceModel>

    <behaviors>

      <serviceBehaviors>

        <behavior name="mybehavior">

          <serviceMetadata httpGetEnabled="true"/>

          <serviceDebug includeExceptionDetailInFaults="false"/>

          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>

        </behavior>

      </serviceBehaviors>

    </behaviors>

    <bindings>

      <basicHttpBinding>

        <binding name="BasicHttpBinding_SymbolTableService" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"

                 receiveTimeout="00:10:00" sendTimeout="00:10:00" openTimeout="00:10:00" closeTimeout="00:10:00">

          <readerQuotas maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxDepth="2147483647" maxNameTableCharCount="2147483647" maxStringContentLength="2147483647"/>

        </binding>

      </basicHttpBinding>

    </bindings>

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>

    <services>

      <service name="WebGIS.Web.SymbolTableService" behaviorConfiguration="mybehavior">

        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_SymbolTableService" contract="WebGIS.Web.SymbolTableService" />

        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>

      </service>

    </services>

  </system.serviceModel>

</configuration>


ServiceReferences.ClientConfig配置如下:

<configuration>

    <system.serviceModel>

        <bindings>

            <basicHttpBinding>

                <binding name="GisRealDataSoap" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">

                    <security mode="None" />

                </binding>

                <binding name="BasicHttpBinding_SymbolTableService" maxBufferSize="2147483647"

                    maxReceivedMessageSize="2147483647">

                    <security mode="None" />

                </binding>

            </basicHttpBinding>

        </bindings>

        <client>

            <endpoint address="http://10.1.1.57/WebGis/GisRealData.asmx" binding="basicHttpBinding"

                bindingConfiguration="GisRealDataSoap" contract="GisRealDataRef.GisRealDataSoap"

                name="GisRealDataSoap" />

            <endpoint address="http://10.1.1.57/WebGis/SymbolTableService.svc"

                binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_SymbolTableService"

                contract="SymbolTableRef.SymbolTableService" name="BasicHttpBinding_SymbolTableService" />

        </client>

    </system.serviceModel>

</configuration>


这样在IIS5.1下发布后,  m_soapclient.GetKG_RealDataAsync(m_kgparabyte)始终没有返回值(没进GetKG_RealDataCompleted函数),但是调用 m_soapclient.HelloWorldAsync()一切正常,有返回值,直接访问webserivce也能看到,如下:




后来在网上查了好几天,网上有一篇文章《webservice发布问题,部署iis后调用不成功》

有这么一句话“对应的应用池,设置默认设置-->进程模型-->标识-->设置localsystem”

还有《C#的WebService调用VC++的DLL,VS2005程序运行DEBUG可行,但是其他机器访问就不行》中的“你可以在web.config里启用模拟,或者在iis6的应用程序池里的对应的网站的池的标识采用本地系统,或者将dll本身的安全性添加匿名账户访问权限”


最后试了半天,给dll目录添加匿名账户访问权限不行,IIS5.1没有应用程序池设置。

最后在web.config里启用模拟,问题解决了。

即在<system.web>中加上这句<identity impersonate="true" />。




N天后做别的测试,上传文件不行,于是然后设置了下虚拟目录属性为:写入等(全打上勾);



还有就是inetinfo.exe也报错。



莫名其妙的实时数据又取不到了(调试下没问题,上边提到的indentify也是true)。

后来在所调用的dll文件夹(上边提到的c:\xxxx\)属性中添加上匿名访问的用户,突然又可以了,如下:





真是无语了!



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值