VB.NET Visual Studio Outlook 2013 Addin项目 - 事件似乎没有被触发

时间:2015-08-13 17:25:57

标签: vb.net events outlook-addin

感谢您抽出宝贵时间查看我的第一篇文章。

我正在开发一个Outlook Addin(使用Visual Studio社区2013),以便用户可以轻松地为我们的客户服务部门填充电子邮件模板。 插件运行良好但我需要添加一些功能,以便在实际发送电子邮件后将一些数据(跟踪KPI)记录到数据库。

经过一些研究,我为Applications itemSend事件实现了一个类级事件处理程序。

这在开发机器上完美运行,但是当我在客户端上发布和安装应用程序时,事件似乎不会被触发,因为不会调用将数据记录到数据库的代码。

由于我无法正常工作,我尝试了一个解决方案,然后将其更改为使用已发送文件夹的.ItemAdd事件。 (代码是从Pranav借来的:https://easyvsto.wordpress.com/2010/07/27/how-to-save-mail-content-when-a-mail-is-sent-from-outlook/

这也适用于开发机器,但同样,一旦在客户端macine上安装了插件,事件似乎无法触发。

正如我现在看到两种不同方法的相同行为,它让我觉得有一些显而易见的事情。我错过了什么或没有考虑到某些因素吗?

代码示例如下:

Imports Microsoft.Office.Tools.Ribbon
Imports System.Runtime.InteropServices
Imports System.IO
Imports MySql.Data.MySqlClient
Imports System.Diagnostics

Public Class ThisAddIn
Public WithEvents oSentFolder As Outlook.Folder
Public WithEvents oSentItems As Outlook.Items

Private Sub ThisAddIn_Startup() Handles Me.Startup
    oSentFolder = Globals.ThisAddIn.Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail)
    oSentItems = oSentFolder.Items
End Sub

Private Sub InsertSurveyTimestamp() Handles oSentItems.ItemAdd
    System.Windows.Forms.MessageBox.Show("oSentItems.ItemAdd Event")
End Sub
Private Sub Application_ItemSend(ByVal oItem As Object, ByRef Cancel As Boolean) Handles Application.ItemSend
    System.Windows.Forms.MessageBox.Show("Application.ItemSend Event")
    log.WriteToErrorLog("Application ItemSend Reached", "", "Event")
    If TypeOf oItem Is Outlook.MailItem Then Call SentMailTimestamp(oItem)
    System.Windows.Forms.MessageBox.Show("end of Itemsend Event")
End Sub

Private Sub SentMailTimestamp(oitem As Outlook.MailItem)
    log.WriteToErrorLog("SentMailTimestamp Sub Reached", "", "Subroutine Flag")
    Try
        'Dim oitem As Outlook.MailItem = oSentItems.Item(oSentItems.Count) 'for use with oSentItems.ItemAdd event
        'Check the CSOSurvey property exists to make sure its a CSO Survey email, exit if not a CSOSurvey Email
        Dim o = oitem.ItemProperties("CSOSurvey")
        If (o IsNot Nothing) AndAlso (o.Value IsNot Nothing) Then
            System.Diagnostics.Debug.WriteLine("CSOsurvey email: " & o.Value.ToString)
            log.WriteToErrorLog("Email was CSO Survey", "Value: " & o.Value.ToString, "Email Property")
        Else
            System.Diagnostics.Debug.WriteLine("CSOsurvey email: Null")
            log.WriteToErrorLog("Email was NOT CSO Survey", "", "Email Property")
            oitem = Nothing
            o = Nothing
            Exit Sub
        End If
    Catch ex As Exception
        MsgBox(ex.Message)
    End Try
    'Save the timedatestamp of the email template being sent
    Using sqlCommand As New MySqlCommand
        Dim querystr As String = "INSERT INTO cs_survey_emaillog (SRID,exec,datetimestamp) values(@srid,@exec,@datetimestamp)"
        Dim mysqlconn As MySqlConnection
        Try
            mysqlconn = New MySqlConnection(GlobalVariables.connstr)
            mysqlConn.Open()
        Catch ex As MySqlException
            System.Windows.Forms.MessageBox.Show("Unable to write to Log. Please contact bst.uk@chep.com" & vbCrLf & ex.Message)
            log.WriteToErrorLog(ex.Message, ex.StackTrace, "MySQL Error")
            Exit Sub
        End Try
        If mysqlconn.State = Data.ConnectionState.Open Then
            Try
                With sqlCommand
                    .Connection = mysqlconn
                    .CommandText = querystr
                    .CommandType = Data.CommandType.Text
                    .Parameters.AddWithValue("@srid", ThisAddIn.templateSRID)
                    .Parameters.AddWithValue("@exec", ThisAddIn.GetUserName())
                    .Parameters.AddWithValue("@datetimestamp", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))
                    Dim numrec As Integer = .ExecuteNonQuery()
                    If ThisAddIn.GetUserName = "mclachd" Then System.Windows.Forms.MessageBox.Show("Query executed. " + numrec.ToString + " Records sent")
                End With
            Catch ex As MySqlException
                log.WriteToErrorLog(ex.Message, ex.StackTrace, "MySQL Error")
            Finally
                mysqlconn.Close()
                mysqlconn.Dispose()
            End Try
        Else
            log.WriteToErrorLog("Could not open db connection", "", "MySQL Error")
            mysqlconn.Dispose()
        End If
    End Using
End Sub

在这种情况下,从未到达SentMailTimeStamp例程。

如果我删除了该呼叫,则两个消息框都将作为两个事件的结果显示。

如果您需要更多细节,请告诉我。

亲切的问候,

大卫

更新 根据Cadogi评论修改了代码。谢谢。

UPDATE2 已将调用包装在Try Catch中的SentMailtimeStamp路由中,我确实在客户端中出错。

Private Sub Application_ItemSend(ByVal oItem As Object, ByRef Cancel As Boolean) Handles Application.ItemSend
    System.Windows.Forms.MessageBox.Show("Application.ItemSend Event")
    log.WriteToErrorLog("Application ItemSend Reached", "", "Event")
    Try
        If TypeOf oItem Is Outlook.MailItem Then Call SentMailTimestamp(oItem)
    Catch ex As Exception
        System.Windows.Forms.MessageBox.Show(ex.Message)
    End Try
    System.Windows.Forms.MessageBox.Show("end of Itemsend Event")
End Sub

错误消息是:

无法加载文件或程序集'MySQL.Data,version = 6.8.5.0,Culture = neutral,PublicKeyToken = c5687fc88969c44d'或其依赖项之一。系统无法处理指定的文件

太棒了,如果感觉有进展的话。我假设已发布的项目将包含所有必需的内容。

更新3 我已经解决了这个问题,感谢汉斯向我指出了一些非常简单的调试课程 - 这是一个很难吸取的教训,因为这需要我几个星期才能解决。

汉斯绝对认真。

  

有一些明显的缺失,Office程序则没有   容纳行为不端的插件。默认情况下任何异常   他们扔进一个“尴尬”的地方被吞没而没有诊断。   告诉这件事的唯一方法就是你认为应该的代码   有副作用就是没有做好自己的工作。

Addin在开发机器而非客户端上运行的原因是MySQL.Data引用需要将Copy Local属性设置为True。

对于那些最终与我处于类似位置的人来说,解决方法是转到您的项目属性 - >参考。突出显示MySQL.Data并将Copy Local属性更改为True

谢谢大家的贡献,这对我的学习有所帮助,并帮助缩小了问题范围。

3 个答案:

答案 0 :(得分:3)

有一些明显的缺失,Office程序,适用于行为不端的加载项。默认情况下,他们在"尴尬"中抛出的任何异常在没有诊断的情况下吞下地方。说出这种情况的唯一方法是你认为应该产生副作用的代码就是不能正常工作。

您对此做了什么,谷歌" VSTO异常处理"。一个这样的点击是this MSDN article,我将复制粘贴相关部分:

  

Visual Studio Tools for Office可以将启动期间发生的所有错误写入日志文件或在消息框中显示每个错误。默认情况下,应用程序级项目的这些选项处于关闭状态。您可以通过添加和设置环境变量来打开选项。要在消息框中显示每个错误,请将VSTO_SUPPRESSDISPLAYALERTS变量设置为0(零)。您可以通过将变量设置为1(一)来抑制消息。要将错误写入日志文件,请将VSTO_LOGALERTS变量设置为1(一)。 Visual Studio Tools for Office在包含应用程序清单的文件夹中创建日志文件。默认名称为.manifest.log。要停止记录错误,请将变量设置为0(零)

答案 1 :(得分:1)

是否在最终用户PC上启用了加载项?

当大量项目一次添加到文件夹(超过16个)时,不会触发Items类的ItemAdd事件。这是Outlook中的一个已知问题。

答案 2 :(得分:1)

抱歉,没有足够的积分发表评论......

您的SentMailTimestamp()例程是否可能在最终用户无法访问的网络的一部分上保存KPI的信息?我看到应用程序因为这个而没有警告或错误就失败了。

要检查的另一件事是SentMailTimestamp()是否应该使用“Call”关键字,因为它可能会干扰您的结果。 e.g。

Private Sub Application_ItemSend(ByVal oItem As Object, ByRef Cancel As Boolean) Handles Application.ItemSend
MsgBox("Application.ItemSend Event")
SentMailTimestamp()
End Sub

基于此: https://msdn.microsoft.com/en-us/library/dz1z94ha.aspx

From Above Link:“您可以在调用Sub过程时使用Call关键字,但不建议在大多数情况下使用该关键字。有关详细信息,请参阅调用语句(Visual Basic)。”

这是指向它的链接:https://msdn.microsoft.com/en-us/library/sxz296wz.aspx