Lync二次开发关于Lync启动退出问题

以前使用C++开发的version.dll文件,由于各个用户环境的不同,造成某些用户加载不了我们开发的插件,并且写version.dll的同事还没找到好的解决办法,所以得换一种思路去解决这个问题,就是Lync启动时加载我们的插件。

因此写了一个winform程序来监控进程的变化,这个程序还要设置为开机启动。下面是主要代码:

 1 static class Program
 2     {
 3         public static System.Threading.Mutex _run;
 4         /// <summary>
 5         /// 应用程序的主入口点。
 6         /// </summary>
 7         [STAThread]
 8         static void Main()
 9         {
10             bool noRun = false;
11             _run = new System.Threading.Mutex(true, "ICOLyncWindow", out noRun);
12             if (noRun)
13             {
14                 _run.ReleaseMutex();
15                 try
16                 {
17                     //处理未捕获的异常   
18                     Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
19                     //处理UI线程异常   
20                     Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
21                     //处理非UI线程异常   
22                     AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
23 
24                     Application.EnableVisualStyles();
25                     Application.SetCompatibleTextRenderingDefault(false);
26                     Application.Run(new IcoLyncForm());
27                 }
28                 catch (Exception ex)
29                 {
30                     Logger.Error(ex);
31                 }
32             }
33         }
34 
35         static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
36         {
37             Logger.Error(e.Exception);
38         }
39 
40         static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
41         {
42             Logger.Error(e.ExceptionObject as Exception);
43         }
44     }
View Code
 1 public partial class IcoLyncForm : Form
 2     {
 3         [DllImport("user32.dll", EntryPoint = "ShowWindow", SetLastError = true)]
 4         static extern bool ShowWindow(IntPtr hWnd, uint nCmdShow);
 5         [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
 6         public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
 7 
 8         public IcoLyncForm()
 9         {
10             InitializeComponent();
11             this.Load += new EventHandler(Form1_Load);
12         }
13 
14         void Form1_Load(object sender, EventArgs e)
15         {
16             Process[] p = Process.GetProcessesByName("lync");
17             if (p.Length > 0)
18             {
19                 lyncnet.clsLyncNet cls = new lyncnet.clsLyncNet();
20                 this.Invoke(new Action(() => { cls.NetMain(); }));
21             }
22 
23             //创建WQL事件查询,用于实例创建
24             var qCreate = new WqlEventQuery("__InstanceCreationEvent",
25                 TimeSpan.FromSeconds(1),  //WHTHIN = 1
26                 "TargetInstance ISA 'Win32_Process'");
27             //创建WQL事件查询,用于实例删除
28             var qDelete = new WqlEventQuery("__InstanceDeletionEvent",
29                 TimeSpan.FromSeconds(1),  //WHTHIN = 1
30                 "TargetInstance ISA 'Win32_Process'");
31 
32             //创建事件查询的侦听器(ManagementEventWatcher)
33             var wCreate = new ManagementEventWatcher(qCreate);
34             var wDelete = new ManagementEventWatcher(qDelete);
35 
36             wCreate.EventArrived += new EventArrivedEventHandler(wCreate_EventArrived);
37             wDelete.EventArrived += new EventArrivedEventHandler(wDelete_EventArrived);
38 
39             //异步开始侦听
40             wCreate.Start();
41             wDelete.Start();
42            
43             IntPtr intptr;
44             try
45             {
46                 do
47                 {
48                     intptr = FindWindow(null, "ICOLync");
49                     if (intptr != IntPtr.Zero)
50                     {
51                         ShowWindow(intptr, 0);
52                     }
53                 }
54                 while (intptr == IntPtr.Zero);
55                 IcoLync.Util.RegistryHelper.RunWhenStart(true, "ICOLync", AppDomain.CurrentDomain.BaseDirectory + "ICOLync.exe");
56             }
57             catch (Exception ex)
58             {
59                 Logger.Error(ex);
60             }
61         }
62 
63         //输出事件对应的ManagementBaseObject(本例中的Win32_Process实例)的信息
64         static string GetInfo(ManagementBaseObject mobj)
65         {
66             var instance = (ManagementBaseObject)mobj["TargetInstance"];
67             return instance["Name"].ToString();
68         }
69 
70         void wCreate_EventArrived(object sender, EventArrivedEventArgs e)
71         {
72             if (GetInfo(e.NewEvent).Equals("lync.exe"))
73             {
74                 lyncnet.clsLyncNet cls = new lyncnet.clsLyncNet();
75                 this.Invoke(new Action(() => { cls.NetMain(); }));
76             }
77         }
78 
79         void wDelete_EventArrived(object sender, EventArrivedEventArgs e)
80         {
81             if (GetInfo(e.NewEvent).Equals("lync.exe")) this.RestartMe();
82         }
83 
84         private void RestartMe()
85         {
86             Program._run.Close();
87             Process.Start(Application.ExecutablePath);
88             Process.GetCurrentProcess().Kill();
89         }
90     }
View Code

这个winform程序启动之后调用win32 api隐藏起来。检测到新增Lync.exe进程时,注册ICOLync插件,Lync.exe进程注销后,重启winform程序。开始还考虑把winform程序的进程保护起来,很麻烦,不同的操作系统,出现的状况还不一样,所以取消了。

2013.7.26修改:

使用System.Threading.Mutex互斥体,实现程序只启动单一进程,发现有一个Bug,在windows多用户的情况下,每一个用户都可以启动一个进程,所以要保持整天计算机只启动一个进程,应改为如下:

原文地址:https://www.cnblogs.com/zaodianshuo/p/3166443.html