翼度科技»论坛 编程开发 .net 查看内容

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

6

主题

6

帖子

18

积分

新手上路

Rank: 1

积分
18
下面将完成的展示,使用MAPI接口操作Outlook完成通讯录更新。
  1. using Microsoft.Office.Interop.Outlook;
  2. using Microsoft.VisualBasic;
  3. using System;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using System.Data;
  7. using System.Data.SqlClient;
  8. using System.Diagnostics;
  9. using System.IO;
  10. using System.Linq;
  11. using System.Net.NetworkInformation;
  12. using System.Text;
  13. using System.Threading;
  14. using System.Threading.Tasks;
  15. using System.Windows.Forms;
  16. namespace AddressBookTool2
  17. {
  18.     class Program
  19.     {
  20.         static void Main(string[] args)
  21.         {
  22.             Process current = Process.GetCurrentProcess();
  23.             Process[] processes = Process.GetProcessesByName(current.ProcessName);
  24.             bool isAlreadyRunning = false;
  25.             foreach (Process process in processes)
  26.             {
  27.                 if (process.Id != current.Id)
  28.                 {
  29.                     // 检查路径以确保是同一个可执行文件的另一个实例
  30.                     if (process.MainModule.FileName == current.MainModule.FileName)
  31.                     {
  32.                         isAlreadyRunning = true;
  33.                         break;
  34.                     }
  35.                 }
  36.             }
  37.             if (isAlreadyRunning)
  38.             {
  39.             }
  40.             else
  41.             {
  42.                 while (true)
  43.                 {
  44.                     Action();
  45.                     Thread.Sleep(1000 * 60 * 15);
  46.                 }
  47.             }
  48.         }
  49.         const string conn = "Server=192.168.100.99;Database=帆软报表;uid=sa;pwd=dsc";
  50.         /// <summary>
  51.         /// 动作
  52.         /// </summary>
  53.         public static void Action()
  54.         {
  55.             string ipAddress = "192.168.100.99";
  56.             Ping ping = new Ping();
  57.             PingReply pingReply = ping.Send(ipAddress);
  58.             if (pingReply.Status != IPStatus.Success) return;
  59.             UpdateClient();
  60.             const string sql = "SELECT Guid,应用名称,版本,备注 FROM 帆软报表.dbo.版本控制 WHERE 应用名称 = N'集团通讯录'";
  61.             List<Dictionary<string, object>> list = SelectList(sql, conn);
  62.             if (list.Count > 0)
  63.             {
  64.                 string version = list[0]["版本"].ToString();
  65.                 if (string.IsNullOrEmpty(version)) return;
  66.                 string path = $"{Environment.CurrentDirectory}\\Version.conf";
  67.                 if (!File.Exists(path))
  68.                 {
  69.                     UpdateAddressBook();
  70.                     File.WriteAllText(path, version.Trim());
  71.                 }
  72.                 else
  73.                 {
  74.                     string content = "";
  75.                     foreach (string item in File.ReadLines(path))
  76.                     {
  77.                         content += item;
  78.                     }
  79.                     if (content.Trim() != version.Trim())
  80.                     {
  81.                         UpdateAddressBook();
  82.                         File.WriteAllText(path, version.Trim());
  83.                     }
  84.                 }
  85.             }
  86.         }
  87.         /// <summary>
  88.         /// 更新客户端
  89.         /// </summary>
  90.         public static void UpdateClient()
  91.         {
  92.             string ipAddress = "192.168.100.18";
  93.             Ping ping = new Ping();
  94.             PingReply pingReply = ping.Send(ipAddress);
  95.             if (pingReply.Status != IPStatus.Success) return;
  96.             const string sql = "SELECT Guid,应用名称,版本,备注 FROM 帆软报表.dbo.版本控制 WHERE 应用名称 = N'集团通讯录客户端'";
  97.             List<Dictionary<string, object>> list = SelectList(sql, conn);
  98.             if (list.Count > 0)
  99.             {
  100.                 string version = list[0]["版本"].ToString();
  101.                 string path = $"{Environment.CurrentDirectory}\\ClientVersion.conf";
  102.                 if (!File.Exists(path))
  103.                 {
  104.                     File.WriteAllText(path, version.Trim());
  105.                     UpdateClientAction();
  106.                     Environment.Exit(0);
  107.                 }
  108.                 else
  109.                 {
  110.                     string content = "";
  111.                     foreach (string item in File.ReadLines(path))
  112.                     {
  113.                         content += item;
  114.                     }
  115.                     if (content.Trim() != version.Trim())
  116.                     {
  117.                         File.WriteAllText(path, version.Trim());
  118.                         UpdateClientAction();
  119.                         Environment.Exit(0);
  120.                     }
  121.                 }
  122.             }
  123.         }
  124.         /// <summary>
  125.         /// 更新客户端行动
  126.         /// </summary>
  127.         public static void UpdateClientAction()
  128.         {
  129.             string batPath = $"{Environment.CurrentDirectory}\\temp.bat";
  130.             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";
  131.             File.WriteAllText(batPath, cmdText, Encoding.UTF8);
  132.             ProcessStartInfo psi = new ProcessStartInfo()
  133.             {
  134.                 FileName = batPath,
  135.                 CreateNoWindow = true,
  136.                 RedirectStandardError = true,
  137.                 UseShellExecute = false
  138.             };
  139.             using (Process process = new Process())
  140.             {
  141.                 process.StartInfo = psi;
  142.                 process.Start();
  143.             }
  144.         }
  145.         /// <summary>
  146.         /// 更新通讯录
  147.         /// </summary>
  148.         public static void UpdateAddressBook()
  149.         {
  150.             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)";
  151.             List<Dictionary<string, object>> list = SelectList(sql, conn);
  152.             List<Contact> contacts = new List<Contact>();
  153.             list.ForEach(it =>
  154.             {
  155.                 string firstName = it["firstName"].ToString()?.Trim();
  156.                 string lastName = it["lastName"].ToString()?.Trim();
  157.                 string emailAddress = it["emailAddress"].ToString()?.Trim();
  158.                 string group = it["group"].ToString()?.Trim();
  159.                 int index = group.IndexOf(",");
  160.                 if (index >= 0)
  161.                 {
  162.                     string[] groupList = group.Split(',');
  163.                     groupList.ToList().ForEach(g =>
  164.                     {
  165.                         Contact contact = new Contact()
  166.                         {
  167.                             FirstName = firstName,
  168.                             LastName = lastName,
  169.                             EmailAddress = emailAddress,
  170.                             Group = g
  171.                         };
  172.                         contacts.Add(contact);
  173.                     });
  174.                 }
  175.                 else
  176.                 {
  177.                     Contact contact = new Contact()
  178.                     {
  179.                         FirstName = firstName,
  180.                         LastName = lastName,
  181.                         EmailAddress = emailAddress,
  182.                         Group = group
  183.                     };
  184.                     contacts.Add(contact);
  185.                 }
  186.             });
  187.             if (contacts.Count == 0) return;
  188.             GeneractionStroe(contacts, false, "通讯录", true, "汤石集团通讯录");
  189.             GeneractionStroe(contacts, false, "通讯录", false, "湯石集團通訊錄");
  190.         }
  191.         public static void GeneractionStroe(List<Contact> contacts, bool order, string fileName, bool CH_zh, string addressBookName)
  192.         {
  193.             // 繁简转换
  194.             contacts = ContactsLang(contacts, CH_zh);
  195.             // 创建Store,也就是PST档
  196.             Microsoft.Office.Interop.Outlook.Application outlookApp = new Microsoft.Office.Interop.Outlook.Application();
  197.             NameSpace session = outlookApp.GetNamespace("MAPI");
  198.             string path = $"{Environment.CurrentDirectory}\\{fileName}.pst";
  199.             Store store = GetStore(session, path, 5);
  200.             MAPIFolder contactFolder = GetAddressBookFolder(store, addressBookName);
  201.             // 移除就的联系人
  202.             int count = contactFolder.Items.Count;
  203.             for (int i = 0; i < count; i++)
  204.             {
  205.                 contactFolder.Items.Remove(1);
  206.             }
  207.             MAPIFolder deteledItems = store.GetDefaultFolder(OlDefaultFolders.olFolderDeletedItems);
  208.             count = deteledItems.Items.Count;
  209.             for (int i = 0; i < count; i++)
  210.             {
  211.                 deteledItems.Items.Remove(1);
  212.             }
  213.             // 新增联系人
  214.             contacts.Distinct(new ContactEqualityComparer()).ToList().ForEach(contact =>
  215.             {
  216.                 if (!string.IsNullOrEmpty(contact.FirstName) && !string.IsNullOrEmpty(contact.LastName))
  217.                 {
  218.                     ContactItem newContact = contactFolder.Items.Add(OlItemType.olContactItem);
  219.                     OrderContactItem(contact.FirstName, contact.LastName, order, newContact);
  220.                     newContact.Email1Address = contact.EmailAddress;
  221.                     newContact.Save();
  222.                     System.Runtime.InteropServices.Marshal.ReleaseComObject(newContact);
  223.                     newContact = null;
  224.                 }
  225.             });
  226.             // 新增群组
  227.             contacts.GroupBy(it => it.Group).Select(it => new
  228.             ContactGroup()
  229.             {
  230.                 Group = it.Key,
  231.                 Contacts = it.ToList()
  232.             }).ToList().ForEach(it =>
  233.             {
  234.                 if (!string.IsNullOrEmpty(it.Group))
  235.                 {
  236.                     DistListItem dist = contactFolder.Items.Add(OlItemType.olDistributionListItem);
  237.                     it.Contacts.ForEach(contact =>
  238.                     {
  239.                         Recipient recipient = outlookApp.Session.CreateRecipient(contact.FirstName + contact.LastName + "(" + contact.EmailAddress + ")");
  240.                         if (recipient.Resolve())
  241.                         {
  242.                             dist.AddMember(recipient);
  243.                         }
  244.                     });
  245.                     dist.DLName = it.Group;
  246.                     dist.Save();
  247.                     // 确保所有项已从新创建的PST中释放
  248.                     System.Runtime.InteropServices.Marshal.ReleaseComObject(dist);
  249.                     dist = null;
  250.                 }
  251.             });
  252.             // 清理Outlook对象,避免内存泄漏
  253.             System.Runtime.InteropServices.Marshal.ReleaseComObject(session);
  254.             System.Runtime.InteropServices.Marshal.ReleaseComObject(outlookApp);
  255.             outlookApp = null;
  256.             session = null;
  257.         }
  258.         /// <summary>
  259.         /// 获取Store
  260.         /// </summary>
  261.         /// <param name="session">命名控件</param>
  262.         /// <param name="target">目标pst档</param>
  263.         /// <param name="count">最大递归次数</param>
  264.         /// <returns></returns>
  265.         public static Store GetStore(NameSpace session, string target, int count)
  266.         {
  267.             Store store = null;
  268.             foreach (Store it in session.Stores)
  269.             {
  270.                 if (it.FilePath == target)
  271.                 {
  272.                     store = it;
  273.                     break;
  274.                 }
  275.             }
  276.             if (store == null && count > 0)
  277.             {
  278.                 session.AddStore(target);
  279.                 return GetStore(session, target, count--);
  280.             }
  281.             return store;
  282.         }
  283.         /// <summary>
  284.         /// 获取联系人文件夹
  285.         /// </summary>
  286.         /// <param name="store">Store实例</param>
  287.         /// <param name="name">文件夹名称</param>
  288.         /// <returns></returns>
  289.         public static MAPIFolder GetAddressBookFolder(Store store, string name)
  290.         {
  291.             MAPIFolder folder = null;
  292.             Folders folders = store.GetDefaultFolder(OlDefaultFolders.olFolderContacts).Folders;
  293.             foreach (MAPIFolder item in folders)
  294.             {
  295.                 if (item.Name == name)
  296.                 {
  297.                     folder = item;
  298.                     break;
  299.                 }
  300.             }
  301.             if (folder == null)
  302.             {
  303.                 folder = store.GetDefaultFolder(OlDefaultFolders.olFolderContacts).Folders.Add(name);
  304.                 folder.ShowAsOutlookAB = true;// 设置成联系人
  305.             }
  306.             return folder;
  307.         }
  308.         /// <summary>
  309.         /// 转换语言,简体转繁体
  310.         /// </summary>
  311.         /// <param name="contacts">联系人信息集合</param>
  312.         /// <param name="lang">是否转繁体</param>
  313.         /// <returns></returns>
  314.         public static List<Contact> ContactsLang(List<Contact> contacts, bool lang)
  315.         {
  316.             List<Contact> result = new List<Contact>();
  317.             if (lang)
  318.             {
  319.                 return contacts;
  320.             }
  321.             else
  322.             {
  323.                 contacts.ForEach(it =>
  324.                 {
  325.                     it.FirstName = Strings.StrConv(it.FirstName, VbStrConv.TraditionalChinese);
  326.                     it.LastName = Strings.StrConv(it.LastName, VbStrConv.TraditionalChinese);
  327.                     it.Group = Strings.StrConv(it.Group, VbStrConv.TraditionalChinese);
  328.                     result.Add(it);
  329.                 });
  330.             }
  331.             return result;
  332.         }
  333.         /// <summary>
  334.         /// 转换联系人的姓与名位置
  335.         /// </summary>
  336.         /// <param name="firstName">姓氏</param>
  337.         /// <param name="lastName">名字</param>
  338.         /// <param name="order">顺序</param>
  339.         /// <param name="contact">联系人实例</param>
  340.         public static void OrderContactItem(string firstName, string lastName, bool order, ContactItem contact)
  341.         {
  342.             if (order)
  343.             {
  344.                 contact.FirstName = firstName;
  345.                 contact.LastName = lastName;
  346.             }
  347.             else
  348.             {
  349.                 contact.LastName = firstName;
  350.                 contact.FirstName = lastName;
  351.             }
  352.         }
  353.         public struct Contact
  354.         {
  355.             public string FirstName;
  356.             public string LastName;
  357.             public string EmailAddress;
  358.             public string Group;
  359.         }
  360.         public struct ContactGroup
  361.         {
  362.             public string Group;
  363.             public List<Contact> Contacts;
  364.         }
  365.         public class ContactEqualityComparer : IEqualityComparer<Contact>
  366.         {
  367.             public bool Equals(Contact x, Contact y)
  368.             {
  369.                 return x.FirstName == y.FirstName && x.LastName == y.LastName && x.EmailAddress == y.EmailAddress;
  370.             }
  371.             public int GetHashCode(Contact obj)
  372.             {
  373.                 return obj.FirstName.GetHashCode() ^ obj.LastName.GetHashCode() ^ obj.EmailAddress.GetHashCode();
  374.             }
  375.         }
  376.         /// <summary>
  377.         /// 执行select语句
  378.         /// </summary>
  379.         /// <param name="sql">select语句</param>
  380.         /// <param name="connection">数据库链接语句</param>
  381.         /// <returns>List的结果</returns>
  382.         /// <exception cref="System.Exception"></exception>
  383.         public static List<Dictionary<string, object>> SelectList(string sql, string connection)
  384.         {
  385.             if (sql == null || connection == null || sql == "" || connection == "")
  386.                 throw new System.Exception("未传入SQL语句或者Connection链接语句");
  387.             List<Dictionary<string, object>> list = new List<Dictionary<string, object>>();
  388.             SqlConnection conn = new SqlConnection(connection);
  389.             SqlCommand cmd = new SqlCommand(sql, conn);
  390.             try
  391.             {
  392.                 conn.Open();
  393.                 SqlDataReader sqlDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
  394.                 while (sqlDataReader.Read())
  395.                 {
  396.                     int count = sqlDataReader.FieldCount;
  397.                     if (count <= 0) continue;
  398.                     Dictionary<string, object> map = new Dictionary<string, object>();
  399.                     for (int i = 0; i < count; i++)
  400.                     {
  401.                         string name = sqlDataReader.GetName(i);
  402.                         object value = sqlDataReader.GetValue(i);
  403.                         map.Add(name, value);
  404.                     }
  405.                     list.Add(map);
  406.                 }
  407.                 conn.Close();
  408.                 return list;
  409.             }
  410.             catch (System.Exception)
  411.             {
  412.                 conn.Close();
  413.                 return null;
  414.             }
  415.         }
  416.     }
  417. }
复制代码
start.bat 启动用
  1. @echo off
  2. set "source=\\192.168.100.18\mis\21.email-plugin\AddressBookTool"
  3. :: 使用Robocopy复制除了version.conf之外的所有文件和目录
  4. robocopy "%source%" "%1%" /E /XD Version.conf ClientVersion.conf
  5. :: 检查并有条件地复制version.conf
  6. if not exist "%1%\Version.conf" (
  7.     copy /Y "%source%\Version.conf" "%1%"
  8. )
  9. :: 启动程序
  10. cd /d "%1%"
  11. start "" "%2%"
  12. exit
复制代码
来源:https://www.cnblogs.com/heirem/p/17788638.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具