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多用戶的情況下,每一個用戶都可以啓動一個進程,所以要保持整天計算機只啓動一個進程,應改爲如下:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章