差異處
這裏顯示兩個版本的差異處。
Both sides previous revision 前次修改 下次修改 | 前次修改 | ||
cpp:sc:queryservicelockstatus [2016/04/19 11:35] tony [Introduction] |
cpp:sc:queryservicelockstatus [2023/06/25 09:48] (目前版本) |
||
---|---|---|---|
行 1: | 行 1: | ||
- | {{tag>cpp Windows}} | + | {{tag>cpp Windows SCM}} |
====== QueryServiceLockStatus ====== | ====== QueryServiceLockStatus ====== | ||
===== Introduction ===== | ===== Introduction ===== | ||
某些third-party api會在runtime去新增service,以減少使用者在安裝上的負擔。然而在系統重新啟動時,SCM會lock service database,如果新增service將會造成block。此源自: [[https://msdn.microsoft.com/zh-tw/library/windows/desktop/ms686321(v=vs.85).aspx|link]] | 某些third-party api會在runtime去新增service,以減少使用者在安裝上的負擔。然而在系統重新啟動時,SCM會lock service database,如果新增service將會造成block。此源自: [[https://msdn.microsoft.com/zh-tw/library/windows/desktop/ms686321(v=vs.85).aspx|link]] | ||
<code> | <code> | ||
- | A service cannot call StartService during initialization. The reason is that the SCM locks the service control database during initialization, so a call to StartService will block. After the service reports to the SCM that it has successfully started, it can call StartService. | + | A service cannot call StartService during initialization. The reason is that the SCM locks the' |
+ | service control database during initialization, so a call to StartService will block. After the | ||
+ | service reports to the SCM that it has successfully started, it can call StartService. | ||
</code> | </code> | ||
+ | 因此,我們可以先檢查SCM database是否lock,再決定我們接下來該怎麼做。 | ||
===== How to? ===== | ===== How to? ===== | ||
+ | 要解決這問題,可以使用: | ||
+ | * API: QueryServiceLockStatus。 | ||
+ | * Command line: sc querylock。 | ||
+ | 首先來看看QueryServiceLockStatus: | ||
+ | <code cpp> | ||
+ | BOOL IsSCMRelease(){ | ||
+ | SC_HANDLE hSCManager; | ||
+ | LPQUERY_SERVICE_LOCK_STATUS hStatus; | ||
+ | DWORD dwBytesNeeded; | ||
+ | BOOL ret; | ||
+ | |||
+ | hSCManager=OpenSCManager(NULL, NULL, SC_MANAGER_QUERY_LOCK_STATUS); | ||
+ | |||
+ | if (hSCManager) { | ||
+ | hStatus = (LPQUERY_SERVICE_LOCK_STATUS) LocalAlloc(LPTR, sizeof(QUERY_SERVICE_LOCK_STATUS)+256); | ||
+ | if( hStatus == NULL ) { | ||
+ | clog << "LocalAlloc failed. Error: " << GetLastError() << endl; | ||
+ | return FALSE; | ||
+ | } | ||
+ | |||
+ | if( !QueryServiceLockStatus( hSCManager, hStatus, sizeof(QUERY_SERVICE_LOCK_STATUS)+256, &dwBytesNeeded)){ | ||
+ | clog << "Can't query lock status. Error: " << GetLastError() << endl; | ||
+ | ret = FALSE; | ||
+ | } else { | ||
+ | ret = hStatus->fIsLocked == 0; | ||
+ | } | ||
+ | |||
+ | CloseServiceHandle(hSCManager); | ||
+ | LocalFree(hStatus); | ||
+ | return ret; | ||
+ | } | ||
+ | |||
+ | clog << "Can't open SCManager." << endl; | ||
+ | |||
+ | return FALSE; | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | 若透過command line: | ||
+ | <code bash> | ||
+ | C:\Users\tonylin>chcp 437 & sc querylock | ||
+ | Active code page: 437 | ||
+ | [SC] QueryServiceLockStatus SUCCESS | ||
+ | IsLocked : FALSE | ||
+ | LockOwner : | ||
+ | LockDuration : 0 (seconds since acquired) | ||
+ | </code> | ||
===== Reference ===== | ===== Reference ===== | ||
* [[https://msdn.microsoft.com/zh-tw/library/windows/desktop/ms684938(v=vs.85).aspx|MSDN - QueryServiceLockStatus]] | * [[https://msdn.microsoft.com/zh-tw/library/windows/desktop/ms684938(v=vs.85).aspx|MSDN - QueryServiceLockStatus]] | ||
* [[https://msdn.microsoft.com/zh-tw/library/windows/desktop/ms686321(v=vs.85).aspx|MSDN - StartService]] | * [[https://msdn.microsoft.com/zh-tw/library/windows/desktop/ms686321(v=vs.85).aspx|MSDN - StartService]] | ||
* [[https://msdn.microsoft.com/zh-tw/library/windows/desktop/ms685104(v=vs.85).aspx|MSDN - SCM Handles]] | * [[https://msdn.microsoft.com/zh-tw/library/windows/desktop/ms685104(v=vs.85).aspx|MSDN - SCM Handles]] | ||
+ | * [[http://www.tenouk.com/cpluscodesnippet/changewindowserviceconfig.html|sample code]] | ||
+ | * [[https://technet.microsoft.com/zh-tw/sqlserver/ms684953|QUERY_SERVICE_LOCK_STATUS structure]] | ||
===== ===== | ===== ===== | ||
---- | ---- | ||
\\ | \\ | ||
~~DISQUS~~ | ~~DISQUS~~ |