AutoRunUtils.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. //using IWshRuntimeLibrary;
  2. using Microsoft.Win32;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Diagnostics;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Reflection;
  9. using System.Security.Principal;
  10. using System.Text;
  11. using System.Threading.Tasks;
  12. namespace Ips.Library.Basic
  13. {
  14. /// <summary>
  15. /// windows环境下专用,先不编译
  16. /// </summary>
  17. public class ToolAutoRun
  18. {
  19. #region 快捷方式自启
  20. /// <summary>
  21. /// 自动获取系统自动启动目录
  22. /// </summary>
  23. private static string systemStartPath { get { return Environment.GetFolderPath(Environment.SpecialFolder.Startup); } }
  24. /// <summary>
  25. /// 自动获取程序完整路径
  26. /// </summary>
  27. private static string appAllPath { get { return Process.GetCurrentProcess().MainModule.FileName; } }
  28. /// <summary>
  29. /// 自动获取桌面目录
  30. /// </summary>
  31. private static string desktopPath { get { return Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); } }
  32. /// <summary>
  33. /// 设置开机自动启动-只需要调用改方法就可以了参数里面的bool变量是控制开机启动的开关的,默认为开启自启启动
  34. /// </summary>
  35. /// <param name="onOff">自启开关</param>
  36. public static void SetAutoStartByQuick(bool onOff = true)
  37. {
  38. if (onOff)//开机启动
  39. {
  40. //获取启动路径应用程序快捷方式的路径集合
  41. List<string> shortcutPaths = GetQuickFromFolder(systemStartPath, appAllPath);
  42. //存在2个以快捷方式则保留一个快捷方式-避免重复多于
  43. if (shortcutPaths.Count >= 2)
  44. {
  45. for (int i = 1; i < shortcutPaths.Count; i++)
  46. {
  47. DeleteFile(shortcutPaths[i]);
  48. }
  49. }
  50. else if (shortcutPaths.Count < 1)//不存在则创建快捷方式
  51. {
  52. CreateShortcut(systemStartPath, Path.GetFileNameWithoutExtension(appAllPath), appAllPath, "");
  53. }
  54. }
  55. else//开机不启动
  56. {
  57. //获取启动路径应用程序快捷方式的路径集合
  58. List<string> shortcutPaths = GetQuickFromFolder(systemStartPath, appAllPath);
  59. //存在快捷方式则遍历全部删除
  60. if (shortcutPaths.Count > 0)
  61. {
  62. for (int i = 0; i < shortcutPaths.Count; i++)
  63. {
  64. DeleteFile(shortcutPaths[i]);
  65. }
  66. }
  67. }
  68. //创建桌面快捷方式-如果需要可以取消注释
  69. //CreateDesktopQuick(desktopPath, QuickName, appAllPath);
  70. }
  71. /// <summary>
  72. /// 获取指定文件夹下指定应用程序的快捷方式路径集合
  73. /// </summary>
  74. /// <param name="directory">文件夹</param>
  75. /// <param name="targetPath">目标应用程序路径</param>
  76. /// <returns>目标应用程序的快捷方式</returns>
  77. private static List<string> GetQuickFromFolder(string directory, string targetPath)
  78. {
  79. List<string> tempStrs = new List<string>();
  80. tempStrs.Clear();
  81. string tempStr = null;
  82. string[] files = Directory.GetFiles(directory, "*.lnk");
  83. if (files == null || files.Length < 1)
  84. {
  85. return tempStrs;
  86. }
  87. for (int i = 0; i < files.Length; i++)
  88. {
  89. //files[i] = string.Format("{0}\\{1}", directory, files[i]);
  90. tempStr = GetAppPathFromQuick(files[i]);
  91. if (tempStr == targetPath)
  92. {
  93. tempStrs.Add(files[i]);
  94. }
  95. }
  96. return tempStrs;
  97. }
  98. /// <summary>
  99. /// 获取快捷方式的目标文件路径-用于判断是否已经开启了自动启动
  100. /// </summary>
  101. /// <param name="shortcutPath"></param>
  102. /// <returns></returns>
  103. private static string GetAppPathFromQuick(string shortcutPath)
  104. {
  105. //快捷方式文件的路径 = @"d:\Test.lnk";
  106. if (System.IO.File.Exists(shortcutPath))
  107. {
  108. //WshShell shell = new WshShell();
  109. //IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(shortcutPath);
  110. var shellType = Type.GetTypeFromProgID("WScript.Shell");
  111. dynamic shell = Activator.CreateInstance(shellType);
  112. var shortcut = shell.CreateShortcut(shortcutPath);
  113. //快捷方式文件指向的路径.Text = 当前快捷方式文件IWshShortcut类.TargetPath;
  114. //快捷方式文件指向的目标目录.Text = 当前快捷方式文件IWshShortcut类.WorkingDirectory;
  115. return shortcut.TargetPath;
  116. }
  117. else
  118. {
  119. return "";
  120. }
  121. }
  122. /// <summary>
  123. /// 根据路径删除文件-用于取消自启时从计算机自启目录删除程序的快捷方式
  124. /// </summary>
  125. /// <param name="path">路径</param>
  126. private static void DeleteFile(string path)
  127. {
  128. FileAttributes attr = System.IO.File.GetAttributes(path);
  129. if (attr == FileAttributes.Directory)
  130. {
  131. Directory.Delete(path, true);
  132. }
  133. else
  134. {
  135. System.IO.File.Delete(path);
  136. }
  137. }
  138. /// <summary>
  139. /// 在桌面上创建快捷方式-如果需要可以调用
  140. /// </summary>
  141. /// <param name="desktopPath">桌面地址</param>
  142. /// <param name="appPath">应用路径</param>
  143. public static void CreateDesktopQuick(string desktopPath = "", string quickName = "", string appPath = "")
  144. {
  145. List<string> shortcutPaths = GetQuickFromFolder(desktopPath, appPath);
  146. //如果没有则创建
  147. if (shortcutPaths.Count < 1)
  148. {
  149. CreateShortcut(desktopPath, quickName, appPath, "软件描述");
  150. }
  151. }
  152. /// <summary>
  153. /// 为当前正在运行的程序创建一个快捷方式。
  154. /// </summary>
  155. /// <param name="lnkFilePath">快捷方式的完全限定路径。</param>
  156. /// <param name="args">快捷方式启动程序时需要使用的参数。</param>
  157. private static void CreateShortcut(string lnkFilePath, string args = "")
  158. {
  159. var shellType = Type.GetTypeFromProgID("WScript.Shell");
  160. dynamic shell = Activator.CreateInstance(shellType);
  161. var shortcut = shell.CreateShortcut(lnkFilePath);
  162. shortcut.TargetPath = Assembly.GetEntryAssembly().Location;
  163. shortcut.Arguments = args;
  164. shortcut.WorkingDirectory = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
  165. shortcut.Save();
  166. }
  167. /// <summary>
  168. /// 向目标路径创建指定文件的快捷方式
  169. /// </summary>
  170. /// <param name="directory">目标目录</param>
  171. /// <param name="shortcutName">快捷方式名字</param>
  172. /// <param name="targetPath">文件完全路径</param>
  173. /// <param name="description">描述</param>
  174. /// <param name="iconLocation">图标地址</param>
  175. /// <returns>成功或失败</returns>
  176. private static bool CreateShortcut(string directory, string shortcutName, string targetPath, string description = null, string iconLocation = null)
  177. {
  178. try
  179. {
  180. if (!Directory.Exists(directory)) Directory.CreateDirectory(directory); //目录不存在则创建
  181. //添加引用 Com 中搜索 Windows Script Host Object Model
  182. string shortcutPath = Path.Combine(directory, string.Format("{0}.lnk", shortcutName)); //合成路径
  183. //WshShell shell = new IWshRuntimeLibrary.WshShell();
  184. //IWshShortcut shortcut = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(shortcutPath); //创建快捷方式对象
  185. var shellType = Type.GetTypeFromProgID("WScript.Shell");
  186. dynamic shell = Activator.CreateInstance(shellType);
  187. var shortcut = shell.CreateShortcut(shortcutPath);
  188. shortcut.TargetPath = targetPath; //指定目标路径
  189. shortcut.WorkingDirectory = Path.GetDirectoryName(targetPath); //设置起始位置
  190. shortcut.WindowStyle = 1; //设置运行方式,默认为常规窗口
  191. shortcut.Description = description; //设置备注
  192. shortcut.IconLocation = string.IsNullOrWhiteSpace(iconLocation) ? targetPath : iconLocation; //设置图标路径
  193. shortcut.Save(); //保存快捷方式
  194. return true;
  195. }
  196. catch (Exception ex)
  197. {
  198. string temp = ex.Message;
  199. temp = "";
  200. }
  201. return false;
  202. }
  203. #endregion
  204. #region 注册表方式自启,需要管理员权限
  205. /// <summary>
  206. /// 将本程序设为开启自启
  207. /// </summary>
  208. /// <param name="onOff">自启开关</param>
  209. /// <returns></returns>
  210. public static bool SetAutoStartByReg(bool onOff)
  211. {
  212. bool isOk = false;
  213. string appName = Process.GetCurrentProcess().MainModule.ModuleName;
  214. string appPath = Process.GetCurrentProcess().MainModule.FileName;
  215. isOk = SetAutoStartByReg(onOff, appName, appPath);
  216. return isOk;
  217. }
  218. /// <summary>
  219. /// 将应用程序设为或不设为开机启动
  220. /// </summary>
  221. /// <param name="onOff">自启开关</param>
  222. /// <param name="appName">应用程序名</param>
  223. /// <param name="appPath">应用程序完全路径</param>
  224. public static bool SetAutoStartByReg(bool onOff, string appName, string appPath)
  225. {
  226. bool isOk = true;
  227. //如果从没有设为开机启动设置到要设为开机启动
  228. if (!IsExistKey(appName) && onOff)
  229. {
  230. isOk = SelfRunning(onOff, appName, @appPath);
  231. }
  232. //如果从设为开机启动设置到不要设为开机启动
  233. else if (IsExistKey(appName) && !onOff)
  234. {
  235. isOk = SelfRunning(onOff, appName, @appPath);
  236. }
  237. return isOk;
  238. }
  239. /// <summary>
  240. /// 判断注册键值对是否存在,即是否处于开机启动状态
  241. /// </summary>
  242. /// <param name="keyName">键值名</param>
  243. /// <returns></returns>
  244. private static bool IsExistKey(string keyName)
  245. {
  246. try
  247. {
  248. bool _exist = false;
  249. RegistryKey local = Registry.LocalMachine;
  250. RegistryKey runs = local.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);
  251. if (runs == null)
  252. {
  253. RegistryKey key2 = local.CreateSubKey("SOFTWARE");
  254. RegistryKey key3 = key2.CreateSubKey("Microsoft");
  255. RegistryKey key4 = key3.CreateSubKey("Windows");
  256. RegistryKey key5 = key4.CreateSubKey("CurrentVersion");
  257. RegistryKey key6 = key5.CreateSubKey("Run");
  258. runs = key6;
  259. }
  260. string[] runsName = runs.GetValueNames();
  261. foreach (string strName in runsName)
  262. {
  263. if (strName.ToUpper() == keyName.ToUpper())
  264. {
  265. _exist = true;
  266. return _exist;
  267. }
  268. }
  269. return _exist;
  270. }
  271. catch
  272. {
  273. return false;
  274. }
  275. }
  276. /// <summary>
  277. /// 写入或删除注册表键值对,即设为开机启动或开机不启动
  278. /// </summary>
  279. /// <param name="isStart">是否开机启动</param>
  280. /// <param name="exeName">应用程序名</param>
  281. /// <param name="path">应用程序路径带程序名</param>
  282. /// <returns></returns>
  283. private static bool SelfRunning(bool isStart, string exeName, string path)
  284. {
  285. RegistryKey local = Registry.LocalMachine;
  286. RegistryKey key = local.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);
  287. if (key == null)
  288. {
  289. local.CreateSubKey("SOFTWARE//Microsoft//Windows//CurrentVersion//Run");
  290. }
  291. //若开机自启动则添加键值对
  292. if (isStart)
  293. {
  294. key.SetValue(exeName, path);
  295. key.Close();
  296. }
  297. else//否则删除键值对
  298. {
  299. string[] keyNames = key.GetValueNames();
  300. foreach (string keyName in keyNames)
  301. {
  302. if (keyName.ToUpper() == exeName.ToUpper())
  303. {
  304. key.DeleteValue(exeName);
  305. key.Close();
  306. }
  307. }
  308. }
  309. return true;
  310. }
  311. #endregion
  312. #region 是否管理员、以管理员启动
  313. public static bool IsAdministrator()
  314. {
  315. bool result;
  316. try
  317. {
  318. WindowsIdentity identity = WindowsIdentity.GetCurrent();
  319. WindowsPrincipal principal = new WindowsPrincipal(identity);
  320. result = principal.IsInRole(WindowsBuiltInRole.Administrator);
  321. }
  322. catch
  323. {
  324. result = false;
  325. }
  326. return result;
  327. }
  328. public static void StartWithAdministrator(Form mainForm)
  329. {
  330. /**
  331. * 当前用户是管理员的时候,直接启动应用程序
  332. * 如果不是管理员,则使用启动对象启动程序,以确保使用管理员身份运行
  333. */
  334. //获得当前登录的Windows用户标示
  335. WindowsIdentity identity = WindowsIdentity.GetCurrent();
  336. WindowsPrincipal principal = new WindowsPrincipal(identity);
  337. //判断当前登录用户是否为管理员
  338. if (principal.IsInRole(WindowsBuiltInRole.Administrator))
  339. {
  340. //如果是管理员,则直接运行
  341. Application.Run(mainForm);
  342. }
  343. else
  344. {
  345. //创建启动对象
  346. ProcessStartInfo startInfo = new ProcessStartInfo();
  347. startInfo.UseShellExecute = true;
  348. startInfo.WorkingDirectory = Environment.CurrentDirectory;
  349. startInfo.FileName = Application.ExecutablePath;
  350. //设置启动动作,确保以管理员身份运行
  351. startInfo.Verb = "runas";
  352. try
  353. {
  354. Process.Start(startInfo);
  355. }
  356. catch
  357. {
  358. return;
  359. }
  360. //退出
  361. Application.Exit();
  362. }
  363. //以下是通过配置文件的方式
  364. //在 项目 上 添加新项 选择“应用程序清单文件” 然后单击 添加 按钮
  365. //添加后,默认打开app.manifest文件,将:
  366. //< requestedExecutionLevel level = "asInvoker" uiAccess = "false" />
  367. // 修改为:
  368. //< requestedExecutionLevel level = "requireAdministrator" uiAccess = "false" />
  369. //然后打开 项目属性 ,将 应用程序 标签页中的 资源 中的 清单 修改为新建的 app.manifest。
  370. //重新生成项目,再次打开程序时就会提示 需要以管理员权限运行。
  371. }
  372. #endregion
  373. }
  374. }