CommonHelper.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  1. using ComPDFKit.PDFDocument;
  2. using PDF_Master.Model.PageEdit;
  3. using PDF_Master.ViewModels.Dialog.BOTA;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Diagnostics;
  7. using System.Diagnostics.Eventing.Reader;
  8. using System.Globalization;
  9. using System.IO;
  10. using System.Linq;
  11. using System.Reflection;
  12. using System.Runtime.InteropServices;
  13. using System.Runtime.Serialization.Formatters.Binary;
  14. using System.Text;
  15. using System.Text.RegularExpressions;
  16. using System.Threading.Tasks;
  17. using System.Windows;
  18. using System.Windows.Media;
  19. namespace PDF_Master.Helper
  20. {
  21. public class Compare<T, C> : IEqualityComparer<T>
  22. {
  23. private Func<T, C> _getField;
  24. public Compare(Func<T, C> getfield)
  25. {
  26. this._getField = getfield;
  27. }
  28. public bool Equals(T x, T y)
  29. {
  30. return EqualityComparer<C>.Default.Equals(_getField(x), _getField(y));
  31. }
  32. public int GetHashCode(T obj)
  33. {
  34. return EqualityComparer<C>.Default.GetHashCode(this._getField(obj));
  35. }
  36. }
  37. public enum FileExtension
  38. {
  39. JPG = 255216,
  40. GIF = 7173,
  41. PNG = 13780,
  42. SWF = 6787,
  43. RAR = 8297,
  44. ZIP = 8075,
  45. _7Z = 55122,
  46. VALIDFILE = 9999999
  47. }
  48. /// <summary>
  49. /// 1 FindVisualParent 查找目标类型的父类控件
  50. /// 2 FindVisualChild 查找目标类型的子类控件
  51. /// 3 GetPageParmFromList 从页码集合获取页码字符串,如1,2,3 转换成1-3
  52. /// 4 GetPagesInRange 校验PageRange 输入是否合法,且可返回List<int> Pages 存放的索引值
  53. /// 5.ShowFileBrowser 显示系统文件浏览器,可以根据传入的路径参数,自动选中对应的文件
  54. /// 6.CreateFilePath 检查对应路径是否有重名,有重名的情况追加尾号
  55. /// 7.CreateFolder 检查对应文件夹是否有重名,有重名的情况追加尾号
  56. /// 8.GetUnitsFromPageSize 将PDF页面宽高转换成对应的单位
  57. /// 9.GetDpi() 返回当前设备DPI
  58. /// 10.GetFileSize() 获取文件大小
  59. /// </summary>
  60. public static class CommonHelper
  61. {
  62. [DllImport("user32.dll")]
  63. private static extern IntPtr SetCapture(long hWnd);
  64. [DllImport("user32.dll")]
  65. private static extern long ReleaseCapture();
  66. /// <summary>
  67. /// 打开路径并定位文件...对于@"h:\Bleacher Report - Hardaway with the safe call ??.mp4"这样的,explorer.exe /select,d:xxx不认,用API整它
  68. /// </summary>
  69. /// <param name="filePath">文件绝对路径</param>
  70. [DllImport("shell32.dll", ExactSpelling = true)]
  71. private static extern void ILFree(IntPtr pidlList);
  72. [DllImport("shell32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
  73. private static extern IntPtr ILCreateFromPathW(string pszPath);
  74. [DllImport("shell32.dll", ExactSpelling = true)]
  75. private static extern int SHOpenFolderAndSelectItems(IntPtr pidlList, uint cild, IntPtr children, uint dwFlags);
  76. /// <summary>
  77. /// 打开文件夹浏览,并选中一个文件(对于文件名称比较不规范的,可以用这个)
  78. /// </summary>
  79. /// <param name="filePath"></param>
  80. public static void ExplorerFile(string filePath)
  81. {
  82. try
  83. {
  84. if (!File.Exists(filePath) && !Directory.Exists(filePath))
  85. return;
  86. if (Directory.Exists(filePath))
  87. Process.Start(@"explorer.exe", "/select,\"" + filePath + "\"");
  88. else
  89. {
  90. IntPtr pidlList = ILCreateFromPathW(filePath);
  91. if (pidlList != IntPtr.Zero)
  92. {
  93. try
  94. {
  95. Marshal.ThrowExceptionForHR(SHOpenFolderAndSelectItems(pidlList, 0, IntPtr.Zero, 0));
  96. }
  97. finally
  98. {
  99. ILFree(pidlList);
  100. }
  101. }
  102. }
  103. }
  104. catch { }
  105. }
  106. /// <summary>
  107. /// 自定义Distinct扩展方法
  108. /// </summary>
  109. /// <typeparam name="T">要去重的对象类</typeparam>
  110. /// <typeparam name="C">自定义去重的字段类型</typeparam>
  111. /// <param name="source">要去重的对象</param>
  112. /// <param name="getfield">获取自定义去重字段的委托</param>
  113. /// <returns></returns>
  114. public static IEnumerable<T> DistinctHelper<T, C>(this IEnumerable<T> source, Func<T, C> getfield)
  115. {
  116. return source.Distinct(new Compare<T, C>(getfield));
  117. }
  118. /// <summary>
  119. /// 查找对象目标类型的父类控件
  120. /// </summary>
  121. /// <typeparam name="T"></typeparam>
  122. /// <param name="obj"></param>
  123. /// <returns></returns>
  124. public static T FindVisualParent<T>(DependencyObject obj) where T : class
  125. {
  126. try
  127. {
  128. while (obj != null)
  129. {
  130. if (obj is T)
  131. return obj as T;
  132. obj = VisualTreeHelper.GetParent(obj);
  133. }
  134. return null;
  135. }
  136. catch { return null; }
  137. }
  138. /// <summary>
  139. /// 根据对象查找目标类型的子类
  140. /// </summary>
  141. /// <typeparam name="childItem"></typeparam>
  142. /// <param name="obj"></param>
  143. /// <returns></returns>
  144. public static childItem FindVisualChild<childItem>(DependencyObject obj)
  145. where childItem : DependencyObject
  146. {
  147. try
  148. {
  149. for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
  150. {
  151. DependencyObject child = VisualTreeHelper.GetChild(obj, i);
  152. if (child != null && child is childItem)
  153. return (childItem)child;
  154. else
  155. {
  156. childItem childOfChild = FindVisualChild<childItem>(child);
  157. if (childOfChild != null)
  158. return childOfChild;
  159. }
  160. }
  161. return null;
  162. }
  163. catch { return null; }
  164. }
  165. public static T FindVisualChildByName<T>(DependencyObject parent, string name) where T : DependencyObject
  166. {
  167. for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
  168. {
  169. var child = VisualTreeHelper.GetChild(parent, i);
  170. string controlName = child.GetValue(System.Windows.Controls.Control.NameProperty) as string;
  171. if (controlName == name)
  172. {
  173. return child as T;
  174. }
  175. else
  176. {
  177. T result = FindVisualChildByName<T>(child, name);
  178. if (result != null)
  179. return result;
  180. }
  181. }
  182. return null;
  183. }
  184. /// <summary>
  185. /// 从页码集合获取页码字符串,如1,2,3 转换成1-3
  186. /// </summary>
  187. /// <param name="pagesList"></param>
  188. /// <returns></returns>
  189. public static string GetPageParmFromList(List<int> pagesList)
  190. {
  191. string pageParam = "";
  192. if (pagesList.Count != 0)
  193. {
  194. pagesList.Sort();//先对页码排序
  195. for (int i = 0; i < pagesList.Count; i++)
  196. {
  197. if (i == 0)
  198. {
  199. pageParam += pagesList[0].ToString();
  200. }
  201. else
  202. {
  203. if (pagesList[i] == pagesList[i - 1] + 1)//页码连续
  204. {
  205. if (i >= 2)
  206. {
  207. if (pagesList[i - 1] != pagesList[i - 2] + 1)
  208. pageParam += "-";
  209. }
  210. else
  211. pageParam += "-";
  212. if (i == pagesList.Count - 1)
  213. {
  214. pageParam += pagesList[i].ToString();
  215. }
  216. }
  217. else//页码不连续时
  218. {
  219. if (i >= 2)
  220. {
  221. if (pagesList[i - 1] == pagesList[i - 2] + 1)
  222. pageParam += pagesList[i - 1].ToString();
  223. }
  224. pageParam += "," + pagesList[i].ToString();
  225. }
  226. }
  227. }
  228. }
  229. return pageParam;
  230. }
  231. /// <summary>
  232. /// 校验PageRange 输入是否合法,且可返回List<int> Pages 存放的索引值
  233. /// </summary>
  234. /// <param name="pageIndexList">返回的页面索引集合</param>
  235. /// <param name="pageRange">需要判断的文本</param>
  236. /// <param name="count">页面总数</param>
  237. /// <param name="enumerationSeparator">例 new char[] { ',' }</param>
  238. /// <param name="rangeSeparator">例 new char[] { '-' }</param>
  239. /// <param name="inittag"></param>
  240. /// <returns></returns>
  241. public static bool GetPagesInRange(ref List<int> pageIndexList, string pageRange, int count, char[] enumerationSeparator, char[] rangeSeparator, bool inittag = false)
  242. {
  243. string[] rangeSplit = pageRange.Split(enumerationSeparator);//根据分隔符 拆分字符串
  244. pageIndexList.Clear();
  245. foreach (string range in rangeSplit)
  246. {
  247. int starttag = 1;
  248. if (inittag)
  249. {
  250. starttag = 0;
  251. }
  252. if (range.Contains("-"))//连续页
  253. {
  254. try
  255. {
  256. string[] limits = range.Split(rangeSeparator);//对子字符串再根据”-“ 拆分
  257. if (limits.Length >= 2 && !string.IsNullOrWhiteSpace(limits[0]) && !string.IsNullOrWhiteSpace(limits[1]))
  258. {
  259. int start = int.Parse(limits[0]);
  260. int end = int.Parse(limits[1]);
  261. if ((start < starttag) || (end > count) || (start > end))
  262. {
  263. return false;
  264. }
  265. for (int i = start; i <= end; ++i)
  266. {
  267. if (pageIndexList.Contains(i))
  268. {
  269. return false;
  270. }
  271. pageIndexList.Add(i - 1);
  272. }
  273. continue;
  274. }
  275. }
  276. catch
  277. {
  278. return false;
  279. }
  280. }
  281. int pageNr;
  282. try
  283. {
  284. // Single page
  285. pageNr = int.Parse(range);//单页
  286. }
  287. catch//格式不正确时
  288. {
  289. return false;
  290. }
  291. if (pageNr < starttag || pageNr > count)
  292. {
  293. return false;
  294. }
  295. if (pageIndexList.Contains(pageNr))
  296. {
  297. return false;
  298. }
  299. pageIndexList.Add(pageNr - 1);
  300. }
  301. return true;
  302. }
  303. /// <summary>
  304. /// 显示系统文件浏览器
  305. /// </summary>
  306. /// <param name="selectedFile">要选中的文件路径</param>
  307. public static void ShowFileBrowser(string selectedFile = null)
  308. {
  309. if (string.IsNullOrEmpty(selectedFile))
  310. {
  311. Process.Start(@"explorer.exe");
  312. }
  313. else
  314. {
  315. //if (File.Exists(selectedFile)){
  316. Process.Start(@"explorer.exe", "/select,\"" + selectedFile + "\"");
  317. //}
  318. }
  319. }
  320. /// <summary>
  321. /// 检测文件是否重复 追加尾号
  322. /// </summary>
  323. /// <param name="path"></param>
  324. /// <returns></returns>
  325. public static string CreateFilePath(string path)
  326. {
  327. int i = 1;
  328. string oldDestName = path;
  329. do
  330. {
  331. if (File.Exists(path))
  332. {
  333. int lastDot = oldDestName.LastIndexOf('.');
  334. string fileExtension = string.Empty;
  335. string fileName = oldDestName;
  336. if (lastDot > 0)
  337. {
  338. fileExtension = fileName.Substring(lastDot);
  339. fileName = fileName.Substring(0, lastDot);
  340. }
  341. path = fileName + string.Format(@"({0})", i) + fileExtension;
  342. }
  343. ++i;
  344. } while (File.Exists(path));
  345. return path;
  346. }
  347. /// <summary>
  348. /// 检查文件夹是否重复 追加尾号
  349. /// </summary>
  350. /// <param name="path"></param>
  351. /// <returns></returns>
  352. public static string CreateFolder(string folder)
  353. {
  354. int i = 1;
  355. string oldDestName = folder;
  356. DirectoryInfo info = new DirectoryInfo(folder);
  357. do
  358. {
  359. info = new DirectoryInfo(folder);
  360. if (info.Exists)
  361. {
  362. string fileName = oldDestName;
  363. folder = fileName + string.Format(@"({0})", i);
  364. }
  365. ++i;
  366. } while (info.Exists);
  367. info.Create();
  368. return folder;
  369. }
  370. /// <summary>
  371. /// 将Document 返回的PageSize 转换成对应单位
  372. /// </summary>
  373. /// <param name="size"></param>
  374. /// <param name="unit"></param>
  375. /// <returns></returns>
  376. public static double GetUnitsFromPageSize(double size, PageItemUnits unit = PageItemUnits.MM)
  377. {
  378. double sizeWithUnit = 0;
  379. switch (unit)
  380. {
  381. case PageItemUnits.MM:
  382. sizeWithUnit = size / 72 * 25.4;
  383. break;
  384. case PageItemUnits.CM:
  385. sizeWithUnit = size / 72 * 25.4 / 10.0;
  386. break;
  387. case PageItemUnits.IN:
  388. sizeWithUnit = size / 72;
  389. break;
  390. default:
  391. break;
  392. }
  393. return sizeWithUnit;
  394. }
  395. /// <summary>
  396. /// 将mm单位转换成pdf文件尺寸
  397. /// </summary>
  398. /// <param name="size"></param>
  399. /// <returns></returns>
  400. public static double GetPageSizeFomrUnit(double size)
  401. {
  402. double pagesize = 0;
  403. pagesize = size / 25.4 * 72.0;
  404. return pagesize;
  405. }
  406. /// <summary>
  407. /// 返回设备DPI
  408. /// </summary>
  409. /// <returns></returns>
  410. public static double GetDpi()
  411. {
  412. BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.NonPublic;
  413. PropertyInfo property = typeof(SystemParameters).GetProperty("Dpi", bindingAttr);
  414. return (int)property.GetValue(null, null);
  415. }
  416. /// <summary>
  417. /// 根据路径计算文件大小
  418. /// </summary>
  419. /// <param name="path"></param>
  420. /// <returns></returns>
  421. public static string GetFileSize(string path)
  422. {
  423. System.IO.FileInfo fileInfo = null;
  424. try
  425. {
  426. fileInfo = new System.IO.FileInfo(path);
  427. }
  428. catch
  429. {
  430. return "0KB";
  431. }
  432. if (fileInfo != null && fileInfo.Exists)
  433. {
  434. var size = Math.Round(fileInfo.Length / 1024.0, 0);
  435. if (size > 1024)
  436. {
  437. var sizeDouble = Math.Round(size / 1024.0, 2);
  438. if (sizeDouble > 1024)
  439. {
  440. sizeDouble = Math.Round(sizeDouble / 1024.0, 2);
  441. return sizeDouble + "G";
  442. }
  443. else
  444. return sizeDouble + "M";
  445. }
  446. else
  447. {
  448. return (int)System.Math.Ceiling(size) + "KB";
  449. }
  450. }
  451. else
  452. {
  453. return "0KB";
  454. }
  455. }
  456. /// <summary>
  457. /// 将sdk里的日期转化为标准日期格式
  458. /// </summary>
  459. /// <param name="sdkDate"></param>
  460. /// <returns></returns>
  461. public static string GetDate(string sdkDate)
  462. {
  463. try
  464. {
  465. if (sdkDate == null || string.IsNullOrEmpty(sdkDate))
  466. {
  467. return "";
  468. }
  469. string dateStr = Regex.Match(sdkDate, "(?<=D\\:)[0-9]+(?=[\\+\\-])").Value;
  470. if (string.IsNullOrEmpty(dateStr))
  471. {
  472. return "";
  473. }
  474. string text = dateStr.Substring(0, 4) + "-" + dateStr.Substring(4, 2) + "-" + dateStr.Substring(6, 2) + " " + dateStr.Substring(8, 2) + ":" + dateStr.Substring(10, 2) + ":" + dateStr.Substring(12, 2);
  475. return text;
  476. }
  477. catch { return ""; }
  478. }
  479. /// <summary>
  480. /// 深拷贝方法(针对数据结构类型)
  481. /// </summary>
  482. /// <typeparam name="T"></typeparam>
  483. /// <param name="obj"></param>
  484. /// <returns></returns>
  485. public static T DeepClone<T>(T obj)
  486. {
  487. if (obj == null)
  488. {
  489. return default(T);
  490. }
  491. var objType = obj.GetType();
  492. if (objType.IsValueType || objType == typeof(string))
  493. {
  494. return obj;
  495. }
  496. // 创建新实例
  497. T newObj = (T)Activator.CreateInstance(objType);
  498. // 递归复制属性
  499. PropertyInfo[] properties = objType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
  500. foreach (PropertyInfo property in properties)
  501. {
  502. if (!property.CanWrite || !property.CanRead)
  503. {
  504. continue;
  505. }
  506. // 如果属性是引用类型,继续拷贝
  507. var propertyType = property.PropertyType;
  508. if (propertyType.IsClass && propertyType != typeof(string))
  509. {
  510. var propertyValue = property.GetValue(obj, null);
  511. var propertyValueClone = DeepClone(propertyValue);
  512. property.SetValue(newObj, propertyValueClone, null);
  513. }
  514. // 否则直接赋值
  515. else
  516. {
  517. var propertyValue = property.GetValue(obj, null);
  518. property.SetValue(newObj, propertyValue, null);
  519. }
  520. }
  521. return newObj;
  522. }
  523. /// <summary>
  524. /// 逆序int类型集合
  525. /// </summary>
  526. public static void Reverseorder(ref List<int> Numbers)
  527. {
  528. Numbers = Numbers.OrderBy(a => a).ToList();
  529. Numbers.Reverse();
  530. }
  531. /// <summary>
  532. /// 获取系统语言列表
  533. /// </summary>
  534. /// <returns></returns>
  535. public static CultureInfo[] cultureInfos()
  536. {
  537. return CultureInfo.GetCultures(CultureTypes.AllCultures);
  538. }
  539. /// <summary>
  540. /// 语言缩写获取语言全称
  541. /// </summary>
  542. /// <param name="languageCode"></param>
  543. /// <returns></returns>
  544. public static string LanguageFullName(string languageCode = "en")
  545. {
  546. CultureInfo[] cultures = cultureInfos();
  547. CultureInfo matchingCulture = cultures.FirstOrDefault(c => c.TwoLetterISOLanguageName.Equals(languageCode, StringComparison.InvariantCultureIgnoreCase));
  548. if (matchingCulture != null)
  549. {
  550. string languageFullName = matchingCulture.EnglishName;
  551. return languageFullName;
  552. }
  553. else
  554. {
  555. return languageCode;
  556. }
  557. }
  558. /// <summary>
  559. /// 语言与地区缩写获取语言名字(语言+地区)
  560. /// </summary>
  561. /// <param name="languageAndcountryCode"></param>
  562. /// <returns></returns>
  563. public static string LanguageAndCountryFullName(string languageAndcountryCode = "en-US")
  564. {
  565. try
  566. {
  567. CultureInfo culture = CultureInfo.GetCultureInfo(languageAndcountryCode);
  568. string languageFullName = culture.DisplayName;
  569. return languageFullName;
  570. }
  571. catch (CultureNotFoundException)
  572. {
  573. return languageAndcountryCode;
  574. }
  575. }
  576. /// <summary>
  577. /// 语言与地区缩写获取语言名字(语言+地区)
  578. /// </summary>
  579. /// <param name="languageAndcountryCode"></param>
  580. /// <returns></returns>
  581. public static string LanguageName(string languageAndcountryCode = "en-US")
  582. {
  583. string languageAndcountry = LanguageAndCountryFullName(languageAndcountryCode);
  584. if (languageAndcountry.Contains("Chinese")) {
  585. if (languageAndcountry.Contains("Simplified")) {
  586. return "Chinese";
  587. }
  588. else {
  589. return "ChineseTraditional";
  590. }
  591. }
  592. else if (languageAndcountry.Contains("("))
  593. {
  594. string pattern = @"\([^()]*\)"; // 匹配括号以及其中的内容
  595. string result = Regex.Replace(languageAndcountry, pattern, string.Empty);
  596. return result;
  597. }
  598. else {
  599. return languageAndcountry;
  600. }
  601. }
  602. }
  603. }