मैंने हाल ही में एक छोटी सी कक्षा लिखी है ताकि मुझे विंडोज़ सेवा पर वसूली विकल्पों को बदलने में मदद मिल सके (अधिकांश कोड मुझे कहीं ऑनलाइन मिले)। कोड पहले, दूसरे, और बाद की विफलताओं के लिए एक विफलता क्रिया बनाता है। प्रत्येक विफलता ऑब्जेक्ट में एक प्रकार (कोई नहीं, पुनरारंभ, रीबूट, रनकॉमैंड), और मिलीसेकंड में विलंब (int) होता है। इन वस्तुओं को एक संरचना के अंदर पैक किया जाता है और ChangeServiceConfig2 (WinAPI पी/Invoke) में पारित किया जाता है। हालांकि, जब मैं वास्तव में कंसोल पर किसी सेवा पर राइट-क्लिक करता हूं और रिकवरी टैब पर जाता हूं, तो आप सभी असफलताओं (पहले, दूसरे और बाद वाले) के लिए देरी ("फ़ील्ड के बाद सर्वर को पुनरारंभ करें) सेट कर सकते हैं। जब मैं इसे प्रोग्रामेटिक रूप से सेट करता हूं, तो यह पहली विफलता से देरी लेता है और अन्य सभी को अनदेखा करता है। क्या किसी को पता है कि यह मामला क्यों है? हमें केवल विफलता ऑब्जेक्ट ऑब्जेक्ट्स के लिए देरी मूल्य में क्यों गुजरना पड़ता है जब केवल पहला उपयोग किया जाता है? क्या मैं कुछ गलत समझ रहा हूँ?विंडोज सेवाओं पर रिकवरी विकल्प सेट करना
इसके अलावा, dwResetPeriod/"रीसेट विफल गिनती" को कोई प्रभाव नहीं लग रहा है।
कोड:
public class ServiceConfigurator
{
private const int SERVICE_ALL_ACCESS = 0xF01FF;
private const int SC_MANAGER_ALL_ACCESS = 0xF003F;
private const int SERVICE_CONFIG_DESCRIPTION = 0x1;
private const int SERVICE_CONFIG_FAILURE_ACTIONS = 0x2;
private const int SERVICE_NO_CHANGE = -1;
private const int ERROR_ACCESS_DENIED = 5;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct SERVICE_FAILURE_ACTIONS
{
public int dwResetPeriod;
[MarshalAs(UnmanagedType.LPWStr)]
public string lpRebootMsg;
[MarshalAs(UnmanagedType.LPWStr)]
public string lpCommand;
public int cActions;
public IntPtr lpsaActions;
}
[DllImport("advapi32.dll", EntryPoint = "ChangeServiceConfig2")]
private static extern bool ChangeServiceFailureActions(IntPtr hService, int dwInfoLevel, [MarshalAs(UnmanagedType.Struct)] ref SERVICE_FAILURE_ACTIONS lpInfo);
[DllImport("advapi32.dll", EntryPoint = "ChangeServiceConfig2")]
private static extern bool ChangeServiceDescription(IntPtr hService, int dwInfoLevel, [MarshalAs(UnmanagedType.Struct)] ref SERVICE_DESCRIPTION lpInfo);
[DllImport("kernel32.dll")]
private static extern int GetLastError();
private IntPtr _ServiceHandle;
public IntPtr ServiceHandle { get { return _ServiceHandle; } }
public ServiceConfigurator(ServiceController svcController)
{
this._ServiceHandle = svcController.ServiceHandle.DangerousGetHandle();
}
public void SetRecoveryOptions(FailureAction pFirstFailure, FailureAction pSecondFailure, FailureAction pSubsequentFailures, int pDaysToResetFailureCount = 0)
{
int NUM_ACTIONS = 3;
int[] arrActions = new int[NUM_ACTIONS * 2];
int index = 0;
arrActions[index++] = (int)pFirstFailure.Type;
arrActions[index++] = pFirstFailure.Delay;
arrActions[index++] = (int)pSecondFailure.Type;
arrActions[index++] = pSecondFailure.Delay;
arrActions[index++] = (int)pSubsequentFailures.Type;
arrActions[index++] = pSubsequentFailures.Delay;
IntPtr tmpBuff = Marshal.AllocHGlobal(NUM_ACTIONS * 8);
try
{
Marshal.Copy(arrActions, 0, tmpBuff, NUM_ACTIONS * 2);
SERVICE_FAILURE_ACTIONS sfa = new SERVICE_FAILURE_ACTIONS();
sfa.cActions = 3;
sfa.dwResetPeriod = pDaysToResetFailureCount;
sfa.lpCommand = null;
sfa.lpRebootMsg = null;
sfa.lpsaActions = new IntPtr(tmpBuff.ToInt32());
bool success = ChangeServiceFailureActions(_ServiceHandle, SERVICE_CONFIG_FAILURE_ACTIONS, ref sfa);
if(!success)
{
if(GetLastError() == ERROR_ACCESS_DENIED)
throw new Exception("Access denied while setting failure actions.");
else
throw new Exception("Unknown error while setting failure actions.");
}
}
finally
{
Marshal.FreeHGlobal(tmpBuff);
tmpBuff = IntPtr.Zero;
}
}
}
ट्रेवर
कारण है कि यह केवल मैं यह सोचते कर रहा हूँ कि माइक्रोसॉफ्ट प्रत्येक विफलता कार्रवाई के लिए एक अंतर देरी लागू नहीं किया लेता है केवल पहले पर अपने प्रश्न के लिए।केवल पहले इस्तेमाल किए जाने के बावजूद प्रत्येक विफलता के लिए एक संरचना प्रकार का उपयोग करना संभव था। साथ ही, सेवा प्रबंधक विंडो में रिकवरी टैब में केवल "बाद में सेवा पुनरारंभ करें" के लिए एक प्रविष्टि है, इसलिए ऐसा लगता है कि विंडोज़ वर्तमान में केवल पहले पर ध्यान देना चाहता है। एचटीएच – Jose
@ थ्रेड, इस कोड में FailureAction – user626528
@ user626528 की परिभाषा गुम है: मुझे डर है कि अब मुझे कोड तक पहुंच नहीं है (अब मैं एक अलग कंपनी के साथ हूं)। लेकिन जहां तक मुझे याद है, 'विफलता' वर्ग अनिवार्य रूप से आप उदाहरण कोड में देखते हैं, एक वर्ग जिसमें दो गुण होते हैं: 'टाइप' और' देरी '। – Trevor