コード例 #1
0
        /// <summary>
        /// 卸载服务
        /// </summary>
        /// <param name="serviceName">服务名</param>
        public static void Uninstall(string serviceName)
        {
            IntPtr scmHandle = IntPtr.Zero;
            IntPtr service   = IntPtr.Zero;

            try
            {
                service = OpenService(serviceName, out scmHandle);

                StopService(service);                                                           //停止服务。里面会递归停止从属服务

                if (!Win32Class.DeleteService(service) && Marshal.GetLastWin32Error() != 0x430) //忽略已标记为删除的服务。ERROR_SERVICE_MARKED_FOR_DELETE
                {
                    throw new ApplicationException("删除服务失败!");
                }
            }
            catch (ServiceNotExistException) { } //忽略服务不存在的情况
            finally
            {
                if (service != IntPtr.Zero)
                {
                    Win32Class.CloseServiceHandle(service);
                    Win32Class.CloseServiceHandle(scmHandle);//放if里面是因为如果服务打开失败,在OpenService里就已释放SCM
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// 安装服务
        /// </summary>
        /// <param name="serviceName">服务名</param>
        /// <param name="displayName">友好名称</param>
        /// <param name="binaryFilePath">映像文件路径,可带参数</param>
        /// <param name="description">服务描述</param>
        /// <param name="startType">启动类型</param>
        /// <param name="account">启动账户</param>
        /// <param name="dependencies">依赖服务</param>
        public static void Install(string serviceName, string displayName, string binaryFilePath, string description, ServiceStartType startType, ServiceAccount account = ServiceAccount.LocalSystem, string[] dependencies = null)
        {
            IntPtr scm = OpenSCManager();

            IntPtr service = IntPtr.Zero;

            try {
                service = Win32Class.CreateService(scm, serviceName, displayName, Win32Class.SERVICE_ALL_ACCESS, Win32Class.SERVICE_WIN32_OWN_PROCESS, startType, Win32Class.SERVICE_ERROR_NORMAL, binaryFilePath, null, IntPtr.Zero, ProcessDependencies(dependencies), GetServiceAccountName(account), null);

                if (service == IntPtr.Zero)
                {
                    if (Marshal.GetLastWin32Error() == 0x431)//ERROR_SERVICE_EXISTS
                    {
                        throw new ApplicationException("服务已存在!");
                    }

                    throw new ApplicationException("服务安装失败!");
                }

                //设置服务描述
                Win32Class.SERVICE_DESCRIPTION sd = new Win32Class.SERVICE_DESCRIPTION();
                try {
                    sd.description = Marshal.StringToHGlobalUni(description);
                    Win32Class.ChangeServiceConfig2(service, 1, ref sd);
                } finally {
                    Marshal.FreeHGlobal(sd.description); //释放
                }
            } finally {
                if (service != IntPtr.Zero)
                {
                    Win32Class.CloseServiceHandle(service);
                }
                Win32Class.CloseServiceHandle(scm);
            }
        }
コード例 #3
0
        /// <summary>
        /// 停止服务
        /// </summary>
        private static void StopService(IntPtr service)
        {
            ServiceState currState = GetServiceStatus(service);

            if (currState == ServiceState.Stopped)
            {
                return;
            }

            if (currState != ServiceState.StopPending)
            {
                //递归停止从属服务
                string[] childSvs = EnumDependentServices(service, EnumServiceState.Active);
                if (childSvs.Length != 0)
                {
                    IntPtr scm = OpenSCManager();
                    try {
                        foreach (string childSv in childSvs)
                        {
                            StopService(Win32Class.OpenService(scm, childSv, Win32Class.SERVICE_STOP));
                        }
                    } finally {
                        Win32Class.CloseServiceHandle(scm);
                    }
                }

                Win32Class.SERVICE_STATUS status = new Win32Class.SERVICE_STATUS();
                Win32Class.ControlService(service, Win32Class.SERVICE_CONTROL_STOP, ref status); //发送停止指令
            }

            if (!WaitForStatus(service, ServiceState.Stopped, new TimeSpan(0, 0, 30)))
            {
                throw new ApplicationException("停止服务失败!");
            }
        }
コード例 #4
0
        private static bool ExistService(string serviceName)
        {
            IntPtr scmHandle = IntPtr.Zero;
            IntPtr handle    = IntPtr.Zero;

            try
            {
                handle = OpenService(serviceName, out scmHandle);
                if (handle == IntPtr.Zero)
                {
                    int errCode = Marshal.GetLastWin32Error();
                    if (errCode == 0x424)
                    {
                        return(false);
                    }
                }
            }
            catch (ServiceNotExistException e) { return(false); }
            finally
            {
                Win32Class.CloseServiceHandle(scmHandle); //关闭SCM
                Win32Class.CloseServiceHandle(handle);    //关闭服务
            }
            return(true);
        }
コード例 #5
0
        /// <summary>
        /// 获取服务状态
        /// </summary>
        private static ServiceState GetServiceStatus(IntPtr service)
        {
            Win32Class.SERVICE_STATUS status = new Win32Class.SERVICE_STATUS();

            if (!Win32Class.QueryServiceStatus(service, ref status))
            {
                throw new ApplicationException("获取服务状态出错!");
            }

            return(status.currentState);
        }
コード例 #6
0
        /// <summary>
        /// 打开服务管理器
        /// </summary>
        private static IntPtr OpenSCManager()
        {
            IntPtr scm = Win32Class.OpenSCManager(null, null, Win32Class.SC_MANAGER_ALL_ACCESS);

            if (scm == IntPtr.Zero)
            {
                throw new ApplicationException("打开服务管理器失败!");
            }

            return(scm);
        }
コード例 #7
0
        /// <summary>
        /// 遍历从属服务
        /// </summary>
        /// <param name="serviceHandle"></param>
        /// <param name="state">选择性遍历(活动、非活动、全部)</param>
        private static string[] EnumDependentServices(IntPtr serviceHandle, EnumServiceState state)
        {
            int bytesNeeded   = 0; //存放从属服务的空间大小,由API返回
            int numEnumerated = 0; //从属服务数,由API返回

            //先尝试以空结构获取,如获取成功说明从属服务为空,否则拿到上述俩值
            if (Win32Class.EnumDependentServices(serviceHandle, state, IntPtr.Zero, 0, ref bytesNeeded, ref numEnumerated))
            {
                return(new string[0]);
            }
            if (Marshal.GetLastWin32Error() != 0xEA) //仅当错误值不是大小不够(ERROR_MORE_DATA)时才抛异常
            {
                throw new Win32Exception();
            }

            //在非托管区域创建指针
            IntPtr structsStart = Marshal.AllocHGlobal(new IntPtr(bytesNeeded));

            try
            {
                //往上述指针处塞存放从属服务的结构组,每个从属服务是一个结构
                if (!Win32Class.EnumDependentServices(serviceHandle, state, structsStart, bytesNeeded, ref bytesNeeded, ref numEnumerated))
                {
                    throw new Win32Exception();
                }

                string[] dependentServices   = new string[numEnumerated];
                int      sizeOfStruct        = Marshal.SizeOf(typeof(Win32Class.ENUM_SERVICE_STATUS)); //每个结构的大小
                long     structsStartAsInt64 = structsStart.ToInt64();
                for (int i = 0; i < numEnumerated; i++)
                {
                    Win32Class.ENUM_SERVICE_STATUS structure = new Win32Class.ENUM_SERVICE_STATUS();
                    IntPtr ptr = new IntPtr(structsStartAsInt64 + i * sizeOfStruct); //根据起始指针、结构次序和结构大小推算各结构起始指针
                    Marshal.PtrToStructure(ptr, structure);                          //根据指针拿到结构
                    dependentServices[i] = structure.serviceName;                    //从结构中拿到服务名
                }

                return(dependentServices);
            }
            finally
            {
                Marshal.FreeHGlobal(structsStart);
            }
        }
コード例 #8
0
        /// <summary>
        /// 打开服务
        /// </summary>
        /// <param name="serviceName">服务名称</param>
        /// <param name="scmHandle">服务管理器句柄。供调用者释放</param>
        private static IntPtr OpenService(string serviceName, out IntPtr scmHandle)
        {
            scmHandle = OpenSCManager();

            IntPtr service = Win32Class.OpenService(scmHandle, serviceName, Win32Class.SERVICE_ALL_ACCESS);

            if (service == IntPtr.Zero)
            {
                int errCode = Marshal.GetLastWin32Error();

                Win32Class.CloseServiceHandle(scmHandle); //关闭SCM

                if (errCode == 0x424)                     //ERROR_SERVICE_DOES_NOT_EXIST
                {
                    throw new ServiceNotExistException();
                }

                throw new Win32Exception();
            }

            return(service);
        }