Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用TAPI3 C接听和挂断电话#_C#_Tapi - Fatal编程技术网

C# 使用TAPI3 C接听和挂断电话#

C# 使用TAPI3 C接听和挂断电话#,c#,tapi,C#,Tapi,我陷入了TAPI编程。我创建了一个程序来监控电话的活动。一切正常,但现在我想实现一个直接接受和拒绝来自web的呼叫的功能 我所做的工作如下: namespace Shared { public partial class Site : System.Web.UI.MasterPage { public static ITAddress ln; static int index = -1; static int line;

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

我所做的工作如下:

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
    }
}

我总是让它BasicCallControl2 bc为空,当我按下“接受”按钮时,什么也不会发生。

好的,所以要成功接听电话,首先要做的是向用户权限注册您的线路

tobj.RegisterCallNotifications(ln, true, true, TapiConstants.TAPIMEDIATYPE_AUDIO, 2);
之后,您可以使用EnumerateCalls()迭代每个调用,或者可以实现ITTAPIEventNotification接口,以便在callstate发生更改时获得通知(例如)。 无论如何,在某个时刻,你已经找到了你想要接听的电话。现在,您需要确保呼叫处于警报状态(CS_为入站呼叫提供),然后才能最终调用应答方法

        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状态,则该方法将抛出一个错误代码为0x800040010的COMException

有关ITTAPIEventNotification接口的更多信息,请参阅

编辑:

如果您想检测新的来电,我建议使用TE_CALLNOTIFICATION-Event,因为每次新来电只触发一次。 每次CALLSTATE更改时都会触发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();
        }
    }

我已经用我添加的代码测试了你的代码,效果很好。如果您在回答问题或初始化过程中遇到任何异常,请告诉我

好吧,要想成功接听电话,你首先要做的就是向用户注册电话

tobj.RegisterCallNotifications(ln, true, true, TapiConstants.TAPIMEDIATYPE_AUDIO, 2);
之后,您可以使用EnumerateCalls()迭代每个调用,或者可以实现ITTAPIEventNotification接口,以便在callstate发生更改时获得通知(例如)。 无论如何,在某个时刻,你已经找到了你想要接听的电话。现在,您需要确保呼叫处于警报状态(CS_为入站呼叫提供),然后才能最终调用应答方法

        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状态,则该方法将抛出一个错误代码为0x800040010的COMException

有关ITTAPIEventNotification接口的更多信息,请参阅

编辑:

如果您想检测新的来电,我建议使用TE_CALLNOTIFICATION-Event,因为每次新来电只触发一次。 每次CALLSTATE更改时都会触发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.\u ComObject”类型的COM对象强制转换为接口类型“TAPI3Lib.ITBasicCallControl”。此操作失败,因为对IID为“{B1EFC389-9355-11D0-835C-00AA003CCABD}”的接口的COM组件的QueryInterface调用由于以下错误而失败:不支持此类接口(HRESULT:0x80004002(E_NOINTERFACE)的异常)。“请帮帮我。嗨@AsifGhanchi,在你尝试接听电话之前,你是否注册了电话,你想接听电话?当该行未注册所有者权限时,最有可能引发此异常。如果您没有线路的所有者权限,则无法将ITCallControl强制转换为ITBasicCallControl,因为您不允许操纵呼叫。您好@Oerk,我已更新了我的最新代码,请您检查一下,在进行任何操作之前,我已注册线路。请帮帮我。提前谢谢。嗨@AsifGhanchi,当我运行你的代码时,它似乎工作得很好。如果您想检测来电,我只建议使用TE_CALLNOTIFICATION-Event而不是TE_CALLSTATE-Event。我已经为你更新了我的帖子,所以可以理解我的意思。Hi@Oerk,它在打开visual studio(以管理员身份运行)后工作,但在bc.Answer()执行后,电话仍在响,当我挂断电话时,它会给我一个错误,如ici.ReleaseUserInfo()上的“此实现不考虑建议错误”;你能帮我解释一下为什么电话在没有错误的情况下也没有应答,以及为什么这个错误是因为断开了电话?提前谢谢。您好@Oerk,谢谢您的回复,我已经做了与您在回复中添加的相同的操作,但是当我调试代码时,我在“ITBasicCallControl2 bc=(TAPI3Lib.ITBasicCallControl2)ici”处收到一个错误,错误是无法将“System.\u ComObject”类型的COM对象强制转换为接口类型“TAPI3Lib.ITBasicCallControl”。此操作失败,因为对IID为“{B1EFC389-9355-11D0-835C-00AA003CCABD}”的接口的COM组件的QueryInterface调用由于以下错误而失败:不支持此类接口(HRESULT:0x80004002(E_NOINTERFACE)的异常)。“请帮帮我。嗨@AsifGhanchi,在你尝试接听电话之前,你是否注册了电话,你想接听电话?当该行未注册所有者权限时,最有可能引发此异常。如果您没有线路的所有者权限