博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
window service 恢复选项卡设置
阅读量:7224 次
发布时间:2019-06-29

本文共 11964 字,大约阅读时间需要 39 分钟。

1 class 设置服务恢复选项  2     {  3         public static void Main(string[] args)  4         {
6 ServiceRecovery.UpdateServiceConfig("DEMO"); 7 Console.WriteLine("ok"); 8 } 9 } 10 11 class ServiceRecovery 12 { 13 #region NativeMethod 14 15 [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)] 16 [return: MarshalAs(UnmanagedType.Bool)] 17 public static extern bool ChangeServiceConfig2(IntPtr hService, int dwInfoLevel, IntPtr lpInfo); 18 19 [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)] 20 public static extern IntPtr OpenSCManager(string MachineName, string DatabaseName, uint DesiredAcces); 21 22 [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)] 23 public static extern IntPtr OpenService(IntPtr scHandle, string serviceName, int DesiredAccess); 24 25 [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)] 26 public static extern bool CloseServiceHandle(IntPtr hSCObject); 27 28 [DllImport("advapi32.dll")] 29 public static extern IntPtr LockServiceDatabase(IntPtr hSCManager); 30 31 [DllImport("advapi32.dll")] 32 public static extern bool UnlockServiceDatabase(IntPtr hSCManager); 33 34 [DllImport("kernel32.dll")] 35 public static extern int GetLastError(); 36 37 [DllImport("advapi32.dll", EntryPoint = "ChangeServiceConfig2")] 38 public static extern bool ChangeServiceFailureActions(IntPtr hService, int dwInfoLevel, [MarshalAs(UnmanagedType.Struct)] ref SERVICE_FAILURE_ACTIONS lpInfo); 39 40 [DllImport("advapi32.dll")] 41 public static extern bool AdjustTokenPrivileges(IntPtr TokenHandle, bool DisableAllPrivileges, [MarshalAs(UnmanagedType.Struct)] ref TOKEN_PRIVILEGES NewState, int BufferLength, IntPtr PreviousState, ref int ReturnLength); 42 43 [DllImport("advapi32.dll")] 44 public static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, ref long lpLuid); 45 46 [DllImport("advapi32.dll")] 47 public static extern bool OpenProcessToken(IntPtr ProcessHandle, int DesiredAccess, ref IntPtr TokenHandle); 48 49 [DllImport("kernel32.dll")] 50 public static extern IntPtr GetCurrentProcess(); 51 52 [DllImport("kernel32.dll")] 53 public static extern bool CloseHandle(IntPtr hndl); 54 55 #endregion 56 57 private const int TOKEN_ADJUST_PRIVILEGES = 32; 58 private const int TOKEN_QUERY = 8; 59 private const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege"; 60 private const int SE_PRIVILEGE_ENABLED = 2; 61 62 [StructLayout(LayoutKind.Sequential, Pack = 1)] 63 public struct TOKEN_PRIVILEGES 64 { 65 public int PrivilegeCount; 66 public LUID_AND_ATTRIBUTES Privileges; 67 } 68 [StructLayout(LayoutKind.Sequential)] 69 public struct LUID_AND_ATTRIBUTES 70 { 71 public long Luid; 72 public int Attributes; 73 } 74 75 [StructLayout(LayoutKind.Sequential)] 76 public struct SERVICE_FAILURE_ACTIONS 77 { 78 /// 79 /// 在此时间之后重置失败计数 80 /// 81 public int dwResetPeriod; 82 public string lpRebootMsg; 83 public string lpCommand; 84 public int cActions; 85 public int lpsaActions; 86 } 87 88 private const int SC_MANAGER_ALL_ACCESS = 0xF003F; 89 private const int SERVICE_ALL_ACCESS = 0xF01FF; 90 private const int SERVICE_CONFIG_DESCRIPTION = 0x1; 91 private const int SERVICE_CONFIG_FAILURE_ACTIONS = 0x2; 92 private const int ERROR_ACCESS_DENIED = 5; 93 94 static string logMsgBase = ""; 95 static string ServiceName = ""; 96 97 public static void UpdateServiceConfig(string serviceName) 98 { 99 logMsgBase = "Windows 服务" + ServiceName + ":";100 ServiceName = serviceName;101 var FailureActions = new ArrayList();102 103 //第一次失败104 FailureActions.Add(new FailureAction(RecoverAction.Restart, 0));105 //第二次失败106 FailureActions.Add(new FailureAction(RecoverAction.None, 0));107 //后续失败108 FailureActions.Add(new FailureAction(RecoverAction.Reboot, 0));109 110 int numActions = FailureActions.Count;111 112 IntPtr scmHndl = IntPtr.Zero;113 IntPtr svcHndl = IntPtr.Zero;114 IntPtr tmpBuf = IntPtr.Zero;115 IntPtr svcLock = IntPtr.Zero;116 117 bool rslt = false;118 try119 {120 scmHndl = OpenSCManager(null, null, SC_MANAGER_ALL_ACCESS);121 if (scmHndl.ToInt32() <= 0)122 {123 LogInstallMessage(EventLogEntryType.Error, logMsgBase + "打开服务控制管理器失败");124 return;125 }126 svcLock = LockServiceDatabase(scmHndl);127 if (svcLock.ToInt32() <= 0)128 {129 130 LogInstallMessage(EventLogEntryType.Error, logMsgBase + "无法锁定服务数据库进行写入");131 return;132 }133 svcHndl = OpenService(scmHndl, ServiceName, SERVICE_ALL_ACCESS);134 135 if (svcHndl.ToInt32() <= 0)136 {137 LogInstallMessage(EventLogEntryType.Information, logMsgBase + "无法打开服务");138 return;139 }140 141 int[] actions = new int[numActions * 2];142 int currInd = 0;143 bool needShutdownPrivilege = false;144 foreach (FailureAction fa in FailureActions)145 {146 actions[currInd] = (int)fa.Type;147 actions[++currInd] = fa.Delay;148 currInd++;149 if (fa.Type == RecoverAction.Reboot)150 {151 needShutdownPrivilege = true;152 }153 }154 155 if (needShutdownPrivilege)156 {157 rslt = GrandShutdownPrivilege();158 if (!rslt) return;159 }160 161 tmpBuf = Marshal.AllocHGlobal(numActions * 8);162 Marshal.Copy(actions, 0, tmpBuf, numActions * 2);163 SERVICE_FAILURE_ACTIONS sfa = new SERVICE_FAILURE_ACTIONS();164 165 sfa.cActions = numActions;166 sfa.dwResetPeriod = 0;167 sfa.lpCommand = "";168 sfa.lpRebootMsg = "";169 sfa.lpsaActions = tmpBuf.ToInt32();170 171 rslt = ChangeServiceFailureActions(svcHndl, SERVICE_CONFIG_FAILURE_ACTIONS, ref sfa);172 if (!rslt)173 {174 int err = GetLastError();175 if (err == ERROR_ACCESS_DENIED)176 {177 throw new Exception(logMsgBase + "配置失败时恢复的操作失败");178 }179 }180 Marshal.FreeHGlobal(tmpBuf); tmpBuf = IntPtr.Zero;181 LogInstallMessage(EventLogEntryType.Information, logMsgBase + "已成功配置失败时恢复的操作");182 183 }184 catch (Exception ex)185 {186 LogInstallMessage(EventLogEntryType.Error, ex.Message);187 }188 finally189 {190 if (scmHndl != IntPtr.Zero)191 {192 if (svcLock != IntPtr.Zero)193 {194 UnlockServiceDatabase(svcLock);195 svcLock = IntPtr.Zero;196 }197 CloseServiceHandle(scmHndl);198 scmHndl = IntPtr.Zero;199 }200 if (svcHndl != IntPtr.Zero)201 {202 CloseServiceHandle(svcHndl);203 svcHndl = IntPtr.Zero;204 }205 if (tmpBuf != IntPtr.Zero)206 {207 Marshal.FreeHGlobal(tmpBuf);208 tmpBuf = IntPtr.Zero;209 }210 }211 212 }213 214 static bool GrandShutdownPrivilege()215 {216 bool retRslt = false;217 IntPtr hToken = IntPtr.Zero;218 IntPtr myProc = IntPtr.Zero;219 TOKEN_PRIVILEGES tkp = new TOKEN_PRIVILEGES();220 long Luid = 0;221 int retLen = 0;222 223 try224 {225 226 myProc = GetCurrentProcess();227 bool rslt = OpenProcessToken(myProc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref hToken);228 if (!rslt) return retRslt;229 230 LookupPrivilegeValue(null, SE_SHUTDOWN_NAME, ref Luid);231 232 tkp.PrivilegeCount = 1;233 tkp.Privileges.Luid = Luid;234 tkp.Privileges.Attributes = SE_PRIVILEGE_ENABLED;235 236 rslt = AdjustTokenPrivileges(hToken, false, ref tkp, 0, IntPtr.Zero, ref retLen);237 238 if (GetLastError() != 0)239 {240 throw new Exception("无法授予关机特权");241 }242 retRslt = true;243 }244 catch (Exception ex)245 {246 LogInstallMessage(EventLogEntryType.Error, logMsgBase + ex.Message);247 }248 finally249 {250 if (hToken != IntPtr.Zero)251 {252 CloseHandle(hToken);253 }254 }255 return retRslt;256 }257 258 static void LogInstallMessage(EventLogEntryType logLevel, string msg)259 {260 try261 {262 EventLog.WriteEntry(ServiceName, msg, logLevel);263 }264 catch265 {266 267 }268 }269 270 enum RecoverAction271 {272 /// 273 /// 无操作274 /// 275 None = 0, 276 /// 277 /// 重新启动服务278 /// 279 Restart = 1, 280 /// 281 /// 重启计算机282 /// 283 Reboot = 2, 284 /// 285 /// 运行一个程序286 /// 287 RunCommand = 3288 }289 290 class FailureAction291 {292 private RecoverAction type = RecoverAction.None;293 /// 294 /// 在此时间之后重新启动服务295 /// 296 private int delay = 0;297 public FailureAction()298 {299 300 }301 public FailureAction(RecoverAction actionType, int actionDelay)302 {303 this.type = actionType;304 this.delay = actionDelay;305 }306 307 public RecoverAction Type308 {309 get { return type; }310 set { type = value; }311 }312 /// 313 /// 在此时间之后重新启动服务314 /// 315 public int Delay316 {317 get { return delay; }318 set { delay = value; }319 }320 321 }322 }

 

转载于:https://www.cnblogs.com/94cool/archive/2013/02/25/2931710.html

你可能感兴趣的文章
Gentoo:existing preserved libs问题
查看>>
Linux 常用操作
查看>>
HTTP Request header
查看>>
Android TextView支持的HTML标签
查看>>
tcp CLOSE Wait
查看>>
CentOS 7重置密码
查看>>
NBU对Oracle备份及恢复手册
查看>>
《威胁建模:设计和交付更安全的软件》
查看>>
PopupWindowFragment的使用及项目地址
查看>>
pecan入门
查看>>
数组指针和指针数组的区别
查看>>
[Git] Git整理(四) git rebase 的使用
查看>>
给div添加自定义的属性
查看>>
nGrinder 3.3 is released
查看>>
用于组织,测试和操作对象及类的工具和技术-6 方法调用
查看>>
android之wifi体系架构源码流程分析
查看>>
移动端下拉刷新、上拉加载更多 Jquery插件 dropload
查看>>
11_Dart生成器、call()、隔离器、元数据
查看>>
Perl、PHP、Python、Java和Ruby的比较
查看>>
spring MVC 之 (一)注解总结
查看>>