监控 Outlook 启动/关闭

发布于 2024-10-26 09:07:06 字数 3174 浏览 4 评论 0原文

您将在下文中找到一个类的摘录,旨在在 Outlook 启动时在 Outlook 上下文菜单中添加一个按钮。 当 Outlook 未启动时,启动事件观察程序将被激活以检测 Outlook 启动。 Close EventWatcher 还配备了允许在 Outlook 关闭时清理资源的功能。

我在管理模式下运行此代码,但应用程序随机崩溃。如果我禁用 EventWatchers 周围的所有代码,它就会稳定。我找不到这些崩溃的根源,你能帮我吗? (请原谅我文中的法国评论)。

入口点是 tryHook 方法。

public class OutlookIF
{
    // Attributs métiers       
    private Outlook.Application outlook = null;

    // Process watch
    private ManagementEventWatcher startWatch =
        new ManagementEventWatcher(new WqlEventQuery("SELECT * FROM Win32_ProcessStartTrace WHERE ProcessName = 'OUTLOOK.EXE'"));
    private ManagementEventWatcher stopWatch =
        new ManagementEventWatcher(new WqlEventQuery("SELECT * FROM Win32_ProcessStopTrace WHERE ProcessName = 'OUTLOOK.EXE'"));      

    // Gestion du singleton
    private static OutlookIF v_instance = null;
    public static OutlookIF Instance
    {
        get
        {
            if (v_instance == null)
                v_instance = new OutlookIF();

            return v_instance;
        }
    }

    private OutlookIF()
    {
        // Récupération des évènements EventArrived
        startWatch.EventArrived += new EventArrivedEventHandler(startWatch_EventArrived);
        stopWatch.EventArrived += new EventArrivedEventHandler(stopWatch_EventArrived);         
    }

    // Vérification de la présence d'un process Outlook running
    private bool outlookIsLaunched = (Process.GetProcessesByName("outlook").Count() > 0);

    //Tentative de connexion à Outlook
    public void tryHook()
    {
        if (this.outlookIsLaunched)
        {
            this.hookOutlook();
            this.stopWatch.Start();
        }
        else
            this.startWatch.Start();     
    }

    // Ajout du menu contextuel à Outlook
    private void hookOutlook()
    {
        // Création de l'objet application
        if (this.outlookIsLaunched)
            this.outlook = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application;
        else
            this.outlook = new Outlook.ApplicationClass();

        // Création de l'entrée dans le menu contextuel           
        this.outlook.ItemContextMenuDisplay += new Outlook.ApplicationEvents_11_ItemContextMenuDisplayEventHandler(addEntrytoContextMenu);          
    }

    // Nettoyage des objets
    private void clean()
    {
        Marshal.FinalReleaseComObject(this.outlook); 
        this.outlook = null;
    }

    private void startWatch_EventArrived(object sender, EventArrivedEventArgs e)
    {
        // Arrêt de l'écoute de l'ouverture
        this.startWatch.Stop();

        TrayIcon.afficheMessage("ProcessWatch", "Ouverture d'Outlook");           
        this.hookOutlook();

        // Démarrage de l'écoute de la fermeture
        this.stopWatch.Start();
    }

    private void stopWatch_EventArrived(object sender, EventArrivedEventArgs e)
    {
        // Arrêt de l'écoute de la fermeture
        this.stopWatch.Stop();

        TrayIcon.afficheMessage("ProcessWatch", "Fermeture d'Outlook");           
        this.clean();

        // Démarrage de l'écoute de l'ouverture
        this.startWatch.Start();
    }
}

You will find hereafter an extract of a class aiming at adding a button in Outlook context menu if Outlook is launched.
When outlook is not launched, a Start EventWatcher is armed to detect Outlook startup.
A Close EventWatcher is also armed to allow ressources clean-up when Outlook is closed.

I run this code in Admin mode but the application randomly crashes. If I disable all the code around EventWatchers it's stable. I can't find the origin of these crashes, can you help me ? (Forgive me for the french comments in the text).

The entry point is the tryHook method.

public class OutlookIF
{
    // Attributs métiers       
    private Outlook.Application outlook = null;

    // Process watch
    private ManagementEventWatcher startWatch =
        new ManagementEventWatcher(new WqlEventQuery("SELECT * FROM Win32_ProcessStartTrace WHERE ProcessName = 'OUTLOOK.EXE'"));
    private ManagementEventWatcher stopWatch =
        new ManagementEventWatcher(new WqlEventQuery("SELECT * FROM Win32_ProcessStopTrace WHERE ProcessName = 'OUTLOOK.EXE'"));      

    // Gestion du singleton
    private static OutlookIF v_instance = null;
    public static OutlookIF Instance
    {
        get
        {
            if (v_instance == null)
                v_instance = new OutlookIF();

            return v_instance;
        }
    }

    private OutlookIF()
    {
        // Récupération des évènements EventArrived
        startWatch.EventArrived += new EventArrivedEventHandler(startWatch_EventArrived);
        stopWatch.EventArrived += new EventArrivedEventHandler(stopWatch_EventArrived);         
    }

    // Vérification de la présence d'un process Outlook running
    private bool outlookIsLaunched = (Process.GetProcessesByName("outlook").Count() > 0);

    //Tentative de connexion à Outlook
    public void tryHook()
    {
        if (this.outlookIsLaunched)
        {
            this.hookOutlook();
            this.stopWatch.Start();
        }
        else
            this.startWatch.Start();     
    }

    // Ajout du menu contextuel à Outlook
    private void hookOutlook()
    {
        // Création de l'objet application
        if (this.outlookIsLaunched)
            this.outlook = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application;
        else
            this.outlook = new Outlook.ApplicationClass();

        // Création de l'entrée dans le menu contextuel           
        this.outlook.ItemContextMenuDisplay += new Outlook.ApplicationEvents_11_ItemContextMenuDisplayEventHandler(addEntrytoContextMenu);          
    }

    // Nettoyage des objets
    private void clean()
    {
        Marshal.FinalReleaseComObject(this.outlook); 
        this.outlook = null;
    }

    private void startWatch_EventArrived(object sender, EventArrivedEventArgs e)
    {
        // Arrêt de l'écoute de l'ouverture
        this.startWatch.Stop();

        TrayIcon.afficheMessage("ProcessWatch", "Ouverture d'Outlook");           
        this.hookOutlook();

        // Démarrage de l'écoute de la fermeture
        this.stopWatch.Start();
    }

    private void stopWatch_EventArrived(object sender, EventArrivedEventArgs e)
    {
        // Arrêt de l'écoute de la fermeture
        this.stopWatch.Stop();

        TrayIcon.afficheMessage("ProcessWatch", "Fermeture d'Outlook");           
        this.clean();

        // Démarrage de l'écoute de l'ouverture
        this.startWatch.Start();
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

赴月观长安 2024-11-02 09:07:06

我已经简化了代码并将其放入线程中,它似乎可以工作。
然而,有一个巨大的缺点:Oulook 和程序都必须在管理员模式下运行。
我对限制较少的新提议持开放态度。

这是线程的创建:

Thread outlThread = new Thread(new ThreadStart(OutlookIF.Instance.tryHook));
        outlThread.Start();

和新类:

public class OutlookIF
{
    // Attributs métiers       
    private Outlook.Application outlook;
    private String messageIDParam = "http://schemas.microsoft.com/mapi/proptag/0x1035001E";

    // Process watch
    private ManagementEventWatcher startWatch;
    private ManagementEventWatcher stopWatch;

    // Static Initialization Singleton Pattern
    private static readonly OutlookIF v_instance = new OutlookIF();
    public static OutlookIF Instance{get{return v_instance;}}

    private OutlookIF()
    {
        // Création des processWatchers
        startWatch = new ManagementEventWatcher(new WqlEventQuery("SELECT * FROM Win32_ProcessStartTrace WHERE ProcessName = 'OUTLOOK.EXE'"));
        stopWatch = new ManagementEventWatcher(new WqlEventQuery("SELECT * FROM Win32_ProcessStopTrace WHERE ProcessName = 'OUTLOOK.EXE'"));      
    }

    //Tentative de connexion à Outlook
    public void tryHook()
    {
        while(true)
        {
            if (Process.GetProcessesByName("outlook").Length == 0)
                startWatch.WaitForNextEvent();

            try
            {
                this.outlook = new Outlook.ApplicationClass();      
                this.outlook.ItemContextMenuDisplay += new Outlook.ApplicationEvents_11_ItemContextMenuDisplayEventHandler(addEntrytoContextMenu);
            }
            catch(Exception e)
            {
                MessageBox.Show(e.ToString());
            }

            stopWatch.WaitForNextEvent();
            Marshal.FinalReleaseComObject(this.outlook);
            this.outlook = null;
        }  
    }
}

I've simplified the code and put it in a thread and it seems to work.
Nevertheless there is a huge drawback: Oulook and the program shall both run in Admin mode.
I am open to new propositions less restrictive.

Here is the thread creation:

Thread outlThread = new Thread(new ThreadStart(OutlookIF.Instance.tryHook));
        outlThread.Start();

And the new class:

public class OutlookIF
{
    // Attributs métiers       
    private Outlook.Application outlook;
    private String messageIDParam = "http://schemas.microsoft.com/mapi/proptag/0x1035001E";

    // Process watch
    private ManagementEventWatcher startWatch;
    private ManagementEventWatcher stopWatch;

    // Static Initialization Singleton Pattern
    private static readonly OutlookIF v_instance = new OutlookIF();
    public static OutlookIF Instance{get{return v_instance;}}

    private OutlookIF()
    {
        // Création des processWatchers
        startWatch = new ManagementEventWatcher(new WqlEventQuery("SELECT * FROM Win32_ProcessStartTrace WHERE ProcessName = 'OUTLOOK.EXE'"));
        stopWatch = new ManagementEventWatcher(new WqlEventQuery("SELECT * FROM Win32_ProcessStopTrace WHERE ProcessName = 'OUTLOOK.EXE'"));      
    }

    //Tentative de connexion à Outlook
    public void tryHook()
    {
        while(true)
        {
            if (Process.GetProcessesByName("outlook").Length == 0)
                startWatch.WaitForNextEvent();

            try
            {
                this.outlook = new Outlook.ApplicationClass();      
                this.outlook.ItemContextMenuDisplay += new Outlook.ApplicationEvents_11_ItemContextMenuDisplayEventHandler(addEntrytoContextMenu);
            }
            catch(Exception e)
            {
                MessageBox.Show(e.ToString());
            }

            stopWatch.WaitForNextEvent();
            Marshal.FinalReleaseComObject(this.outlook);
            this.outlook = null;
        }  
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文