自定义侦听器

许多 DRDA 服务侦听器可以替换为用于跟踪输出和包绑定输出的自定义侦听器。

自定义跟踪侦听器

DRDA 服务可以跟踪运行时操作,并将信息输出到默认MsDrdaService.log文件和标准 DrdaAsTextListener。 (可选)可以将 DrdaAsTextListener 替换为自定义跟踪侦听器。

DRDA 服务支持跟踪级别,以选择要写入日志文件和跟踪侦听器的信息。 有关详细信息,请参阅《故障排除》一书中的“跟踪”主题。

若要使用跟踪侦听器示例,请执行以下步骤。

  1. 使用 Microsoft Visual Studio 2010 生成示例。 可能需要更改对项目属性中强名称键的引用,以及程序代码中的输出目录路径。

    using System;  
    using System.IO;  
    using Microsoft.HostIntegration.Drda.Common;  
    
    namespace CustomListeners  
    {  
        public class MyTraceListener : BaseDrdaTraceListener  
        {  
            StreamWriter sw = null;  
    
            public bool EnsureWriter()  
            {  
                if (sw == null)  
                {  
                    try  
                    {  
                        System.IO.DirectoryInfo dirInfo = new System.IO.DirectoryInfo(@"c:\temp");  
                        if (!dirInfo.Exists)  
                        {  
                            dirInfo.Create();  
                        }  
                        string fileName = @"c:\temp\MsDrdaService" + DateTime.Now.ToFileTime() + ".log";  
                        sw = new StreamWriter(fileName);  
                        sw.AutoFlush = true;  
                        sw.WriteLine("MsDrdaService custom log. Created on: " + DateTime.Now);  
    
                        return true;  
                    }  
                    catch (Exception ex)  
                    {  
                        System.Console.WriteLine("Failed to create log file. Message:" + ex.Message);  
                        return false;  
                    }  
                }  
                else  
                    return true;  
            }  
    
            #region override IDrdaTraceListener Members  
    
            public override void TraceEvent(System.Diagnostics.TraceEventType type, int id, string msg)  
            {  
                if (EnsureWriter())  
                {  
                    sw.WriteLine(string.Format("[" + type + "][" + id + "]" + msg));  
                }  
            }  
    
            #endregion  
        }  
    }  
    
    

    自定义跟踪侦听器的示例代码。

  2. 使用Microsoft全局程序集缓存工具,将程序集安装到全局程序集缓存中。 在 Visual Studio x64 Win64 命令提示符 (2010) 窗口中,导航到自定义包绑定侦听器组件的 bin\Debugbin\Retail 文件夹,键入 gacutil /i “<path>\<component_name.dll> ”,然后按 Enter。 使用 Microsoft Visual Studio 2010,编辑 DRDA 服务应用程序配置文件。 更新自定义跟踪侦听器的配置。

    C:\Windows\system32>gacutil /i <path>\CustomListeners\bin\Debug\CustomListeners.dll  
    Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.1  
    Copyright (c) Microsoft Corporation.  All rights reserved.  
    Assembly successfully added to the cache  
    

    图 1. 将自定义侦听器组件添加到 GAC 的示例命令。

  3. 使用Microsoft全局程序集缓存工具,从全局程序集缓存中读取程序集信息。 在 Visual Studio x64 Win64 命令提示符 (2010) 窗口中,导航到自定义包绑定侦听器组件的 bin\Debugbin\Retail 文件夹,键入 gacutil /l “<path>\<component_name.dll> ”,然后按 Enter

    C:\TechReady\DRDA_AS\CustomListeners\bin\Debug>gacutil -l CustomListeners  
    Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.1  
    Copyright (c) Microsoft Corporation.  All rights reserved.  
    The Global Assembly Cache contains the following assemblies:  
      CustomListeners, Version=1.0.0.0, Culture=neutral, PublicKeyToken=34013cf74da51d17, processorArchitecture=MSIL  
    Number of items = 2  
    

    图 2. 从 GAC 读取自定义侦听器组件信息的示例命令。

  4. 使用 Microsoft Visual Studio 2010,编辑 DRDA 服务应用程序配置文件。 更新自定义跟踪侦听器的配置。

    <drdaServiceTraceListeners>  
    <drdaServiceTraceListener type="CustomListeners.MyTraceListener, CustomListeners, Version=1.0.0.0, Culture=neutral, PublicKeyToken=34013cf74da51d17, processorArchitecture=MSIL" traceLevel="3"/>  
    </drdaServiceTraceListeners>  
    

    图 3. MsDrdaService.exe.config中的自定义跟踪侦听器的示例值。

自定义包绑定监听器

若要使用自定义包绑定侦听器示例,请执行以下步骤。

  • 使用 Microsoft Visual Studio 2010 生成示例。 可能需要更改对项目属性中强名称键的引用,以及程序代码中的输出目录路径。

    using System;  
    using System.Collections.Generic;  
    using System.Xml;  
    using System.Text;  
    using Microsoft.HostIntegration.Drda.Common;  
    
    namespace CustomListeners  
    {  
        public class MyPackageBindListener: IPackageBindListener  
        {  
            #region IPackageBindListener Members  
    
            /// <summary>  
            /// Notify after package is bound with string representation of the xml.  
            /// </summary>  
            /// <param name="packageXMLString">package XML String</param>  
            public void OnPackageBound(string packageXMLString, string rdbNam, string collid)  
            {  
            }  
    
            /// <summary>  
            /// Notify after package is bound with xml document.  
            /// </summary>  
            /// <param name="xmldoc"></param>  
            public void OnPackageBound(XmlDocument xmldoc, string rdbNam, string collid)  
            {  
                try  
                {  
                    System.IO.DirectoryInfo dirInfo = new System.IO.DirectoryInfo(@"c:\temp");  
                    if (!dirInfo.Exists)  
                    {  
                        dirInfo.Create();  
                    }  
                    string fileName = @"c:\temp\PackageXMLFile" + DateTime.Now.ToFileTime() + ".xml";  
                    xmldoc.Save(fileName);  
    
                    //callback.ReloadPackageProcedureTable(null);  
                }  
                catch (Exception ex)  
                {  
                    System.Console.WriteLine("Failed to save xml file. Message:" + ex.Message);  
                }  
            }  
            /// <summary>  
            /// Notify after package is bound with string representation of the xml.  
            /// </summary>  
            public void OnPackageBound(string packageXMLString, string rdbNam, string collid, out List<string> sqlScripts)  
            {  
                sqlScripts = new List<string>();  
            }  
    
            /// <summary>  
            /// Notify after package is bound with xml document.  
            /// </summary>  
            public void OnPackageBound(XmlDocument xmldoc, string rdbNam, string collid, out List<string> sqlScripts)  
            {  
                sqlScripts = new List<string>();  
                string[] sqlScript1 = {  
                                        "/****** Object:  StoredProcedure [dbo].[DBOAREAS_43484152544F4B31_1]    Script Date: 01/06/2012 13:36:23 ******/",  
                                        "SET ANSI_NULLS ON",  
                                        "GO",  
                                        "SET QUOTED_IDENTIFIER ON",  
                                        "GO",  
                                        "CREATE PROCEDURE [dbo].[DBOAREAS_43484152544F4B31_1]  AS  DECLARE C1 CURSOR GLOBAL FOR SELECT * FROM DBO.AREAS",  
                                        "GO",  
                                      };  
                string[] sqlScript2 = {  
                                        "CREATE PROCEDURE [dbo].[DBOAREAS_43484152544F4B31_2]  AS  SELECT * FROM DBO.AREAS"  
                                      };  
    
                sqlScripts.AddRange(sqlScript1);  
                sqlScripts.AddRange(sqlScript2);  
            }  
    
            #endregion  
    
        }  
    }  
    
    

    自定义包绑定侦听器的示例代码。

  • 使用Microsoft全局程序集缓存工具,将程序集安装到全局程序集缓存中。 在 Visual Studio x64 Win64 命令提示符 (2010) 窗口中,导航到自定义包绑定侦听器组件的 bin\Debugbin\Retail 文件夹,键入 gacutil /i “<path>\<component_name.dll> ”,然后按 Enter

    C:\Windows\system32>gacutil /i <path>\CustomListeners\bin\Debug\CustomListeners.dll  
    Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.1  
    Copyright (c) Microsoft Corporation.  All rights reserved.  
    Assembly successfully added to the cache  
    

    图 4. 将自定义侦听器组件添加到 GAC 的示例命令。

  • 使用Microsoft全局程序集缓存工具,从全局程序集缓存中读取程序集信息。 在 Visual Studio x64 Win64 命令提示符 (2010) 窗口中,导航到自定义包绑定侦听器组件的 bin\Debugbin\Retail 文件夹,键入 gacutil /l “<path>\<component_name.dll> ”,然后按 Enter

    C:\TechReady\DRDA_AS\CustomListeners\bin\Debug>gacutil -l CustomListeners  
    Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.1  
    Copyright (c) Microsoft Corporation.  All rights reserved.  
    The Global Assembly Cache contains the following assemblies:  
      CustomListeners, Version=1.0.0.0, Culture=neutral, PublicKeyToken=34013cf74da51d17, processorArchitecture=MSIL  
    Number of items = 2  
    

    图 5. 从 GAC 读取自定义侦听器组件信息的示例命令。

  • 使用 Microsoft Visual Studio 2010,编辑 DRDA 服务应用程序配置文件。 将默认包绑定侦听器替换为自定义包绑定侦听器。 如果 DRDA 服务未收到对回调接口的有效响应,则当 errorWhenNoCallback= 值为“true”时,DRDA 服务会将 BGNBNDRM(开始绑定错误回复消息)返回到 DRDA AR。

    <packageBindListeners>  
    <packageBindListener type="CustomListeners.MyPackageBindListener, CustomListeners, Version=1.0.0.0, Culture=neutral, PublicKeyToken=34013cf74da51d17, processorArchitecture=MSIL" errorWhenNoCallback="true"/>  
    </packageBindListeners>  
    

    图 6. DRDA 服务应用程序配置文件中自定义包绑定侦听器的示例值。