我的Office Outlook插件开发之旅(二)

  • 我的Office Outlook插件开发之旅(二)已关闭评论
  • 36 次浏览
  • A+
所属分类:.NET技术
摘要

下面将完成的展示,使用MAPI接口操作Outlook完成通讯录更新。
updater.bat 更新用的

下面将完成的展示,使用MAPI接口操作Outlook完成通讯录更新。
我的Office Outlook插件开发之旅(二)

using Microsoft.Office.Interop.Outlook; using Microsoft.VisualBasic; using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Diagnostics; using System.IO; using System.Linq; using System.Net.NetworkInformation; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms;  namespace AddressBookTool2 {     class Program     {         static void Main(string[] args)         {             Process current = Process.GetCurrentProcess();             Process[] processes = Process.GetProcessesByName(current.ProcessName);              bool isAlreadyRunning = false;             foreach (Process process in processes)             {                 if (process.Id != current.Id)                 {                     // 检查路径以确保是同一个可执行文件的另一个实例                     if (process.MainModule.FileName == current.MainModule.FileName)                     {                         isAlreadyRunning = true;                         break;                     }                 }             }              if (isAlreadyRunning)             {              }             else             {                 while (true)                 {                     Action();                     Thread.Sleep(1000 * 60 * 15);                 }             }         }         const string conn = "Server=192.168.100.99;Database=帆软报表;uid=sa;pwd=dsc";          /// <summary>         /// 动作         /// </summary>         public static void Action()         {             string ipAddress = "192.168.100.99";             Ping ping = new Ping();             PingReply pingReply = ping.Send(ipAddress);             if (pingReply.Status != IPStatus.Success) return;             UpdateClient();             const string sql = "SELECT Guid,应用名称,版本,备注 FROM 帆软报表.dbo.版本控制 WHERE 应用名称 = N'集团通讯录'";             List<Dictionary<string, object>> list = SelectList(sql, conn);             if (list.Count > 0)             {                 string version = list[0]["版本"].ToString();                 if (string.IsNullOrEmpty(version)) return;                 string path = $"{Environment.CurrentDirectory}\Version.conf";                 if (!File.Exists(path))                 {                     UpdateAddressBook();                     File.WriteAllText(path, version.Trim());                 }                 else                 {                     string content = "";                     foreach (string item in File.ReadLines(path))                     {                         content += item;                     }                     if (content.Trim() != version.Trim())                     {                         UpdateAddressBook();                         File.WriteAllText(path, version.Trim());                     }                 }             }         }          /// <summary>         /// 更新客户端         /// </summary>         public static void UpdateClient()         {             string ipAddress = "192.168.100.18";             Ping ping = new Ping();             PingReply pingReply = ping.Send(ipAddress);             if (pingReply.Status != IPStatus.Success) return;              const string sql = "SELECT Guid,应用名称,版本,备注 FROM 帆软报表.dbo.版本控制 WHERE 应用名称 = N'集团通讯录客户端'";             List<Dictionary<string, object>> list = SelectList(sql, conn);             if (list.Count > 0)             {                 string version = list[0]["版本"].ToString();                 string path = $"{Environment.CurrentDirectory}\ClientVersion.conf";                 if (!File.Exists(path))                 {                     File.WriteAllText(path, version.Trim());                     UpdateClientAction();                     Environment.Exit(0);                 }                 else                 {                     string content = "";                     foreach (string item in File.ReadLines(path))                     {                         content += item;                     }                     if (content.Trim() != version.Trim())                     {                         File.WriteAllText(path, version.Trim());                         UpdateClientAction();                         Environment.Exit(0);                     }                 }             }         }          /// <summary>         /// 更新客户端行动         /// </summary>         public static void UpdateClientAction()         {             string batPath = $"{Environment.CurrentDirectory}\temp.bat";             string cmdText = $"@echo off{Environment.NewLine}timeout /t 3 /nobreak >nul{Environment.NewLine}start {Environment.CurrentDirectory}\updater.bat "{Environment.CurrentDirectory}" "{Environment.CurrentDirectory}\AddressBookTool2.exe"{Environment.NewLine}eixt";             File.WriteAllText(batPath, cmdText, Encoding.UTF8);             ProcessStartInfo psi = new ProcessStartInfo()             {                 FileName = batPath,                 CreateNoWindow = true,                 RedirectStandardError = true,                 UseShellExecute = false             };             using (Process process = new Process())             {                 process.StartInfo = psi;                 process.Start();             }         }          /// <summary>         /// 更新通讯录         /// </summary>         public static void UpdateAddressBook()         {             const string sql = "SELECT 邮箱地址 AS 'emailAddress',姓氏 AS 'firstName',姓名 AS 'lastName', 群组 AS 'group' FROM [帆软报表].[dbo].[集团邮箱通讯录] WHERE 邮箱地址 IS NOT NULL AND (姓氏 IS NOT NULL OR 姓名 IS NOT NULL)";             List<Dictionary<string, object>> list = SelectList(sql, conn);             List<Contact> contacts = new List<Contact>();             list.ForEach(it =>             {                 string firstName = it["firstName"].ToString()?.Trim();                 string lastName = it["lastName"].ToString()?.Trim();                 string emailAddress = it["emailAddress"].ToString()?.Trim();                 string group = it["group"].ToString()?.Trim();                 int index = group.IndexOf(",");                 if (index >= 0)                 {                     string[] groupList = group.Split(',');                     groupList.ToList().ForEach(g =>                     {                         Contact contact = new Contact()                         {                             FirstName = firstName,                             LastName = lastName,                             EmailAddress = emailAddress,                             Group = g                         };                         contacts.Add(contact);                     });                 }                 else                 {                     Contact contact = new Contact()                     {                         FirstName = firstName,                         LastName = lastName,                         EmailAddress = emailAddress,                         Group = group                     };                     contacts.Add(contact);                 }             });              if (contacts.Count == 0) return;             GeneractionStroe(contacts, false, "通讯录", true, "汤石集团通讯录");             GeneractionStroe(contacts, false, "通讯录", false, "湯石集團通訊錄");         }            public static void GeneractionStroe(List<Contact> contacts, bool order, string fileName, bool CH_zh, string addressBookName)         {             // 繁简转换             contacts = ContactsLang(contacts, CH_zh);              // 创建Store,也就是PST档             Microsoft.Office.Interop.Outlook.Application outlookApp = new Microsoft.Office.Interop.Outlook.Application();             NameSpace session = outlookApp.GetNamespace("MAPI");             string path = $"{Environment.CurrentDirectory}\{fileName}.pst";             Store store = GetStore(session, path, 5);              MAPIFolder contactFolder = GetAddressBookFolder(store, addressBookName);             // 移除就的联系人             int count = contactFolder.Items.Count;             for (int i = 0; i < count; i++)             {                 contactFolder.Items.Remove(1);             }             MAPIFolder deteledItems = store.GetDefaultFolder(OlDefaultFolders.olFolderDeletedItems);             count = deteledItems.Items.Count;             for (int i = 0; i < count; i++)             {                 deteledItems.Items.Remove(1);             }              // 新增联系人             contacts.Distinct(new ContactEqualityComparer()).ToList().ForEach(contact =>             {                 if (!string.IsNullOrEmpty(contact.FirstName) && !string.IsNullOrEmpty(contact.LastName))                 {                     ContactItem newContact = contactFolder.Items.Add(OlItemType.olContactItem);                     OrderContactItem(contact.FirstName, contact.LastName, order, newContact);                     newContact.Email1Address = contact.EmailAddress;                     newContact.Save();                     System.Runtime.InteropServices.Marshal.ReleaseComObject(newContact);                     newContact = null;                 }             });              // 新增群组             contacts.GroupBy(it => it.Group).Select(it => new             ContactGroup()             {                 Group = it.Key,                 Contacts = it.ToList()             }).ToList().ForEach(it =>             {                 if (!string.IsNullOrEmpty(it.Group))                 {                     DistListItem dist = contactFolder.Items.Add(OlItemType.olDistributionListItem);                     it.Contacts.ForEach(contact =>                     {                         Recipient recipient = outlookApp.Session.CreateRecipient(contact.FirstName + contact.LastName + "(" + contact.EmailAddress + ")");                         if (recipient.Resolve())                         {                             dist.AddMember(recipient);                         }                     });                     dist.DLName = it.Group;                     dist.Save();                     // 确保所有项已从新创建的PST中释放                     System.Runtime.InteropServices.Marshal.ReleaseComObject(dist);                     dist = null;                 }             });              // 清理Outlook对象,避免内存泄漏             System.Runtime.InteropServices.Marshal.ReleaseComObject(session);             System.Runtime.InteropServices.Marshal.ReleaseComObject(outlookApp);             outlookApp = null;             session = null;         }           /// <summary>         /// 获取Store         /// </summary>         /// <param name="session">命名控件</param>         /// <param name="target">目标pst档</param>         /// <param name="count">最大递归次数</param>         /// <returns></returns>         public static Store GetStore(NameSpace session, string target, int count)         {             Store store = null;             foreach (Store it in session.Stores)             {                 if (it.FilePath == target)                 {                     store = it;                     break;                 }             }             if (store == null && count > 0)             {                 session.AddStore(target);                 return GetStore(session, target, count--);             }             return store;         }          /// <summary>         /// 获取联系人文件夹         /// </summary>         /// <param name="store">Store实例</param>         /// <param name="name">文件夹名称</param>         /// <returns></returns>         public static MAPIFolder GetAddressBookFolder(Store store, string name)         {             MAPIFolder folder = null;             Folders folders = store.GetDefaultFolder(OlDefaultFolders.olFolderContacts).Folders;             foreach (MAPIFolder item in folders)             {                 if (item.Name == name)                 {                     folder = item;                     break;                 }             }             if (folder == null)             {                 folder = store.GetDefaultFolder(OlDefaultFolders.olFolderContacts).Folders.Add(name);                 folder.ShowAsOutlookAB = true;// 设置成联系人             }             return folder;         }          /// <summary>         /// 转换语言,简体转繁体         /// </summary>         /// <param name="contacts">联系人信息集合</param>         /// <param name="lang">是否转繁体</param>         /// <returns></returns>         public static List<Contact> ContactsLang(List<Contact> contacts, bool lang)         {             List<Contact> result = new List<Contact>();             if (lang)             {                 return contacts;             }             else             {                 contacts.ForEach(it =>                 {                     it.FirstName = Strings.StrConv(it.FirstName, VbStrConv.TraditionalChinese);                     it.LastName = Strings.StrConv(it.LastName, VbStrConv.TraditionalChinese);                     it.Group = Strings.StrConv(it.Group, VbStrConv.TraditionalChinese);                     result.Add(it);                 });             }              return result;         }          /// <summary>         /// 转换联系人的姓与名位置         /// </summary>         /// <param name="firstName">姓氏</param>         /// <param name="lastName">名字</param>         /// <param name="order">顺序</param>         /// <param name="contact">联系人实例</param>         public static void OrderContactItem(string firstName, string lastName, bool order, ContactItem contact)         {             if (order)             {                 contact.FirstName = firstName;                 contact.LastName = lastName;             }             else             {                 contact.LastName = firstName;                 contact.FirstName = lastName;             }         }          public struct Contact         {             public string FirstName;             public string LastName;             public string EmailAddress;             public string Group;         }          public struct ContactGroup         {             public string Group;             public List<Contact> Contacts;         }          public class ContactEqualityComparer : IEqualityComparer<Contact>         {             public bool Equals(Contact x, Contact y)             {                 return x.FirstName == y.FirstName && x.LastName == y.LastName && x.EmailAddress == y.EmailAddress;             }              public int GetHashCode(Contact obj)             {                 return obj.FirstName.GetHashCode() ^ obj.LastName.GetHashCode() ^ obj.EmailAddress.GetHashCode();             }         }          /// <summary>         /// 执行select语句         /// </summary>         /// <param name="sql">select语句</param>         /// <param name="connection">数据库链接语句</param>         /// <returns>List的结果</returns>         /// <exception cref="System.Exception"></exception>         public static List<Dictionary<string, object>> SelectList(string sql, string connection)         {             if (sql == null || connection == null || sql == "" || connection == "")                 throw new System.Exception("未传入SQL语句或者Connection链接语句");             List<Dictionary<string, object>> list = new List<Dictionary<string, object>>();             SqlConnection conn = new SqlConnection(connection);             SqlCommand cmd = new SqlCommand(sql, conn);             try             {                 conn.Open();                 SqlDataReader sqlDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection);                 while (sqlDataReader.Read())                 {                     int count = sqlDataReader.FieldCount;                     if (count <= 0) continue;                     Dictionary<string, object> map = new Dictionary<string, object>();                     for (int i = 0; i < count; i++)                     {                         string name = sqlDataReader.GetName(i);                         object value = sqlDataReader.GetValue(i);                         map.Add(name, value);                     }                     list.Add(map);                 }                 conn.Close();                 return list;             }             catch (System.Exception)             {                 conn.Close();                 return null;             }         }     } } 

updater.bat 更新用的

@echo off set "source=\192.168.100.18mis21.email-pluginAddressBookTool"  :: 使用Robocopy复制除了version.conf之外的所有文件和目录 robocopy "%source%" "%1%" /E /XD Version.conf ClientVersion.conf  :: 检查并有条件地复制version.conf if not exist "%1%Version.conf" (     copy /Y "%source%Version.conf" "%1%" )  :: 启动程序 cd /d "%1%" start "" "%2%"  exit 

setup.bat 安装用

@echo off set "REG_PATH=HKEY_CURRENT_USERSOFTWAREMicrosoftWindowsCurrentVersionRunAddressBookTool" set "client_bat=C:TONSAddressBookToolstart.bat" set "folder=C:TONSAddressBookTool" set "source=\192.168.100.18mis21.email-pluginAddressBookTool"  :: 使用Robocopy复制除了version.conf之外的所有文件和目录 robocopy "%source%" "%folder%" /E /XD version.conf  :: 检查并有条件地复制version.conf if not exist "%folder%version.conf" (     copy /Y "%source%version.conf" "%folder%" )  :: 配置环境变量 reg query %REG_PATH% >nul 2>nul&&goto A||goto B :B reg add "HKEY_CURRENT_USERSOFTWAREMicrosoftWindowsCurrentVersionRun" /v AddressBookTool /t REG_SZ /d %client_bat% /f :A start %client_bat% exit 

start.bat 启动用

@echo off set "environment=C:TONSAddressBookTool" set "client=C:TONSAddressBookToolAddressBookTool2.exe"  :: 启动程序 cd /d "%environment%" start "" "%client%" exit