【问题标题】:Answer and Hangup a call using TAPI3 C#使用 TAPI3 C# 接听和挂断电话
【发布时间】:2017-05-16 10:00:44
【问题描述】:

我陷入了 TAPI 编程。我创建了一个程序来监控电话活动。一切正常,但现在我想实现一个功能来直接接受和拒绝来自网络的呼叫。

我所做的如下:

namespace Shared
{
    public partial class Site : System.Web.UI.MasterPage
    {
        public static ITAddress ln;
        static int index = -1;
        static int line;
        static ITAddress[] ia;
        protected void Page_Load(object sender, EventArgs e)
        {
            #region TAPI
            TAPIClass tobj;
            int[] registertoken;
            tobj = new TAPI3Lib.TAPIClass();
            tobj.Initialize();

            IEnumAddress ea = tobj.EnumerateAddresses();

            uint lines;


            uint arg3 = 0;
            int TotalLines = 0;
            lines = 0;
            foreach (TAPI3Lib.ITAddress ad in (tobj.Addresses as TAPI3Lib.ITCollection))
            {
                TotalLines++;
            }

            callnotification cn = new callnotification();
            tobj.ITTAPIEventNotification_Event_Event += new TAPI3Lib.ITTAPIEventNotification_EventEventHandler(cn.Event);
            tobj.EventFilter = (int)(TAPI_EVENT.TE_CALLNOTIFICATION |
                TAPI_EVENT.TE_DIGITEVENT |
                TAPI_EVENT.TE_PHONEEVENT |
                TAPI_EVENT.TE_CALLSTATE |
                TAPI_EVENT.TE_GENERATEEVENT |
                TAPI_EVENT.TE_GATHERDIGITS |
                TAPI_EVENT.TE_REQUEST);


            registertoken = new int[TotalLines];
            ia = new TAPI3Lib.ITAddress[TotalLines];
            for (int i = 0; i = 0)
                                    {
                                        ln = ia[line];
                                    }
                                    IEnumCall ec = ln.EnumerateCalls();
                                    uint arg = 0;
                                    ITCallInfo ici;
                                    try
                                    {
                                        ec.Next(1, out ici, ref arg);
                                        ITBasicCallControl2 bc = (TAPI3Lib.ITBasicCallControl2)ici;
                                        if (ici != null && ici.CallState == CALL_STATE.CS_OFFERING)
                                        {
                                            if (bc != null)
                                            {
                                                bc.Answer();
                                            }
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        COMException comEx = ex as COMException;
                                        if (comEx != null)
                                            comEx.ErrorCode.ToString();
                                        else
                                        {
                                            string aa = ex.Message;
                                        }
                                    }

                                    //addtolist("Call Offering from " + callernumber + " to Ext " + viaextension + " via DID " + DIDNumber);
                                    break;
                                case TAPI3Lib.CALL_STATE.CS_IDLE:
                                    //addtolist("Call is created!");
                                    break;
                            }
                            break;
                    }
                }
                catch (Exception ex)
                {
                    //MessageBox.Show(ex.StackTrace.ToString());
                }
            }
        }
        #endregion
    }
}

我总是得到 ITBasicCallControl2 bc NULL,当我按下接受按钮时,没有任何反应。

【问题讨论】:

    标签: c# tapi


    【解决方案1】:

    好的,所以要成功接听电话,您首先要做的就是为您的线路注册所有者权限。

    tobj.RegisterCallNotifications(ln, true, true, TapiConstants.TAPIMEDIATYPE_AUDIO, 2);
    

    之后,您可以使用 EnumerateCalls() 遍历每个调用,也可以实现 ITTAPIEventNotification 接口以在调用状态发生变化时获得通知(例如)。 在某些时候,一种或另一种方式,你找到了你想接听的电话。现在您需要确保呼叫处于警报状态(入站呼叫为 CS_OFFERING),然后才能最终调用 answer 方法。

            try
            {
                ec.Next(1, out ici, ref arg);
                if (ici != null && ici.CallState == CALL_STATE.CS_OFFERING)
                {
                    ITBasicCallControl2 bc = (TAPI3Lib.ITBasicCallControl2)ici;
                    if (bc != null)
                    {
                        bc.Answer();
                    }
                }
            }
            catch (Exception exp)
            {
                COMException comEx = exp as COMException;
                if (comEx != null)
                    MessageBox.Show(comEx.ErrorCode.ToString());
                else
                    MessageBox.Show(exp.Message);
            }
    

    如果您要接听的电话不在callstate CS_CONNECTED,则该方法将抛出COMException,错误代码为0x800040010。

    有关 ITTAPIEventNotification 接口的更多信息,请参阅https://msdn.microsoft.com/en-us/library/windows/desktop/ms732506(v=vs.85).aspx

    编辑:

    如果您想检测新的来电,我建议使用 TE_CALLNOTIFICATION-Event,因为每个新来电只会触发一次。 TE_CALLSTATE-Event 会在每次调用状态改变时触发。

    现在,我更新了 callnotification 类:

        public class callnotification : TAPI3Lib.ITTAPIEventNotification
        {
            public InboundCall OnNewIncomingCall;
    
            public void Event(TAPI_EVENT TapiEvent, object pEvent)
            {
                switch (TapiEvent)
                {
                    case TAPI_EVENT.TE_CALLNOTIFICATION:
                        this.OnCallNotification((ITCallNotificationEvent)pEvent);
                        break;
                }
            }
    
            private void OnCallNotification(ITCallNotificationEvent callNotification)
            {
                ITCallInfo ici = callNotification.Call;
    
                if (ici != null && ici.CallState == CALL_STATE.CS_OFFERING)
                    this.OnNewIncomingCall(ici);
            }
        }
    

    如果有新的入站调用,我还声明了要使用的委托方法:

    public delegate void InboundCall(ITCallInfo ici);
    

    所以您对 callnotification 事件的初始化可能如下所示:

            callnotification cn = new callnotification();
            cn.OnNewIncomingCall += this.OnNewIncomingCall;
    

    最后,在 OnNewIncomingCallMethod 中,您可以接听电话:

        private void OnNewIncomingCall(ITCallInfo ici)
        {
            ITBasicCallControl bcc = (ITBasicCallControl)ici;
            if (bcc != null)
            {
                string caller = ici.get_CallInfoString(CALLINFO_STRING.CIS_CALLERIDNUMBER);
                DialogResult dlg = MessageBox.Show(string.Format("New incoming call from {0}\r\nDo you wish to answer the call now?", caller), "New incoming call", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (dlg == System.Windows.Forms.DialogResult.Yes)
                    bcc.Answer();
            }
        }
    

    我已经用我添加的代码测试了你的代码,它运行良好。如果您在回答或初始化期间有任何异常,请告诉我。

    【讨论】:

    • 嗨@Oerk,感谢您的回复,我所做的与您在回复中添加的相同,但是当我调试我的代码时,我在“ITBasicCallControl2 bc = (TAPI3Lib.ITBasicCallControl2)ici”处遇到错误错误是“无法将‘System.__ComObject’类型的 COM 对象转换为接口类型‘TAPI3Lib.ITBasicCallControl’。此操作失败,因为对具有 IID 的接口的 COM 组件调用 QueryInterface '{B1EFC389-9355-11D0-835C -00AA003CCABD}' 由于以下错误而失败:不支持此类接口(来自 HRESULT 的异常:0x80004002 (E_NOINTERFACE))。”请帮帮我。
    • 嗨@AsifGhanchi,在尝试接听之前,您是否注册了想要接听电话的线路?当线路未注册所有者权限时,最有可能抛出此异常。如果您在线路上没有所有者权限,则不能将 ITCallControl 强制转换为 ITBasicCallControl,因为不允许您操纵呼叫。
    • 嗨@Oerk,我已经更新了我的最新代码,请你看看我在进行任何操作之前已经注册了线路。请帮帮我。提前致谢。
    • 嗨@AsifGhanchi,当我运行你的代码时,它似乎工作得很好。如果您想检测来电,我只建议使用 TE_CALLNOTIFICATION-Event 而不是 TE_CALLSTATE-Event。我已经为你更新了我的帖子,所以可以明白我的意思。
    • 嗨@Oerk,它在打开视觉工作室(以管理员身份运行)后工作,但在 bc.Answer() 执行后电话仍然响铃,当我挂断电话时它给我一个错误,如“此实现不接受 ici.ReleaseUserUserInfo() 处的建议错误”;你能帮我解释一下为什么电话没有接听,即使没有错误,以及为什么这个错误是因为断开电话而出现的?提前致谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多