Có vẻ như trên các phiên bản Windows muộn hơn Windows 7 (chưa được xác minh, nhưng theo kinh nghiệm mới nhất với Windows Server 2012 R2), Trình quản lý điều khiển dịch vụ (SCM) nghiêm ngặt hơn.
Mặc dù trên Windows 7, nó chỉ sinh ra một quy trình khác, nhưng hiện tại nó đang kiểm tra xem liệu quy trình dịch vụ có còn hay không và có thể trả về ERROR_SERVICE_MARKED_FOR_DELETE (1072) cho bất kỳ cuộc gọi tiếp theo nào tới CreatService / DeleteService ngay cả khi dịch vụ dường như bị dừng.
Tôi đang nói về mã API Windows ở đây, nhưng tôi muốn phác thảo rõ ràng những gì đang xảy ra, vì vậy trình tự này có thể dẫn đến lỗi được đề cập:
SC_HANDLE hScm = OpenSCManager(nullptr, nullptr, SC_MANAGER_ALL_ACCESS);
SC_HANDLE hSvc = OpenService(hScm, L"Stub service", SERVICE_STOP | SERVICE_QUERY_STATUS | DELETE);
SERVICE_STATUS ss;
ControlService(hSvc, SERVICE_CONTROL_STOP, &ss);
// ... wait for service to report its SERVICE_STOPPED state
DeleteService(hSvc);
CloseServiceHandle(hSvc);
hSvc = nullptr;
// any further calls to CreateService/DeleteService will fail
// if service process is still around
Lý do một quy trình dịch vụ vẫn còn tồn tại sau khi nó đã báo cáo trạng thái SERVICE_STOPPED của nó không gây ngạc nhiên. Đó là một quy trình thông thường, có luồng chính bị 'kẹt' trong lệnh gọi StartServiceCtrlDispatcher
API, do đó trước tiên nó phản ứng với hành động kiểm soát dừng, nhưng sau đó phải thực hiện chuỗi mã còn lại.
Thật không may, SCM / OS không xử lý việc này đúng với chúng tôi. Một giải pháp lập trình khá đơn giản và chính xác: có được xử lý quy trình thực thi dịch vụ trước khi dừng dịch vụ, sau đó đợi xử lý này được báo hiệu.
Nếu tiếp cận vấn đề từ góc độ quản trị hệ thống, giải pháp cũng là chờ quá trình dịch vụ biến mất hoàn toàn.