- A+
所属分类:.NET技术
下面将完成的展示,使用MAPI接口操作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