Starting a Service

博客介绍了启动服务的方法,通过打开已安装数据库的句柄,在调用StartService函数时指定该句柄来启动服务。启动后,程序利用QueryServiceStatusEx函数返回的SERVICE_STATUS_PROCESS结构成员跟踪服务进度,该函数需服务控制管理器数据库的句柄。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Starting a Service

To start a service, the following example opens a handle to an installed database and then specifies the handle in a call to the StartService function. It can be used to start either a service or a driver service, but this example assumes that a service is being started. After starting the service, the program uses the members of the SERVICE_STATUS_PROCESS structure returned by the QueryServiceStatusEx function to track the progress of the service.

The function requires a handle to a service control manager database. For more information, see Opening an SCManager Database.

#include <windows.h>
#include <stdio.h>

BOOL StartSampleService(SC_HANDLE schSCManager) 
{ 
    SC_HANDLE schService;
    SERVICE_STATUS_PROCESS ssStatus; 
    DWORD dwOldCheckPoint; 
    DWORD dwStartTickCount;
    DWORD dwWaitTime;
    DWORD dwBytesNeeded;
 
    schService = OpenService( 
        schSCManager,          // SCM database 
        "Sample_Srv",          // service name
        SERVICE_ALL_ACCESS); 
 
    if (schService == NULL) 
    { 
        return 0; 
    }
 
    if (!StartService(
            schService,  // handle to service 
            0,           // number of arguments 
            NULL) )      // no arguments 
    {
        return 0; 
    }
    else 
    {
        printf("Service start pending./n"); 
    }
 
    // Check the status until the service is no longer start pending. 
 
    if (!QueryServiceStatusEx( 
            schService,             // handle to service 
            SC_STATUS_PROCESS_INFO, // info level
            &ssStatus,              // address of structure
            sizeof(SERVICE_STATUS_PROCESS), // size of structure
            &dwBytesNeeded ) )              // if buffer too small
    {
        return 0; 
    }
 
    // Save the tick count and initial checkpoint.

    dwStartTickCount = GetTickCount();
    dwOldCheckPoint = ssStatus.dwCheckPoint;

    while (ssStatus.dwCurrentState == SERVICE_START_PENDING) 
    { 
        // Do not wait longer than the wait hint. A good interval is 
        // one tenth the wait hint, but no less than 1 second and no 
        // more than 10 seconds. 
 
        dwWaitTime = ssStatus.dwWaitHint / 10;

        if( dwWaitTime < 1000 )
            dwWaitTime = 1000;
        else if ( dwWaitTime > 10000 )
            dwWaitTime = 10000;

        Sleep( dwWaitTime );

        // Check the status again. 
 
    if (!QueryServiceStatusEx( 
            schService,             // handle to service 
            SC_STATUS_PROCESS_INFO, // info level
            &ssStatus,              // address of structure
            sizeof(SERVICE_STATUS_PROCESS), // size of structure
            &dwBytesNeeded ) )              // if buffer too small
            break; 
 
        if ( ssStatus.dwCheckPoint > dwOldCheckPoint )
        {
            // The service is making progress.

            dwStartTickCount = GetTickCount();
            dwOldCheckPoint = ssStatus.dwCheckPoint;
        }
        else
        {
            if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint)
            {
                // No progress made within the wait hint
                break;
            }
        }
    } 

    CloseServiceHandle(schService); 

    if (ssStatus.dwCurrentState == SERVICE_RUNNING) 
    {
        printf("StartService SUCCESS./n"); 
        return 1;
    }
    else 
    { 
        printf("/nService not started. /n");
        printf("  Current State: %d/n", ssStatus.dwCurrentState); 
        printf("  Exit Code: %d/n", ssStatus.dwWin32ExitCode); 
        printf("  Service Specific Exit Code: %d/n", 
            ssStatus.dwServiceSpecificExitCode); 
        printf("  Check Point: %d/n", ssStatus.dwCheckPoint); 
        printf("  Wait Hint: %d/n", ssStatus.dwWaitHint); 
        return 0;
    } 
}
<think>我们正在处理用户的问题:"fstrim.serviceis disabledor staticunit notstarting"根据用户的问题,他们遇到了fstrim.service无法启动的问题,错误信息表明该服务被禁用或者是静态单元无法启动。首先,我们需要了解fstrim.service的作用。fstrim.service是一个系统服务,用于定期修剪(trim)SSD驱动器,以优化性能并延长使用寿命。通常,这个服务是通过定时器(timer)定期触发的。在systemd中,服务单元可以是以下几种状态:- enabled:已启用,会在启动时运行或由定时器触发。-disabled:已禁用,不会自动启动。- static:静态单元,不能单独启用,但可以被其他单元(如定时器)作为依赖启动。错误信息表明该服务是“disabled”或“static”。对于静态单元,我们不需要手动启用它,因为它通常由定时器触发。但如果是禁用状态,我们可能需要启用它(尽管通常fstrim.service是静态的)。步骤:1.检查fstrim.service的状态。2.检查fstrim.timer的状态,因为fstrim.service通常由fstrim.timer触发。3.如果定时器没有激活,则启用并启动定时器。具体操作:首先,检查服务状态:systemctl statusfstrim.service如果服务是静态的(static),那么状态可能会显示为“loaded(static)”。静态单元不能被启用,但可以被启动(手动或通过定时器)。然后,检查定时器状态:systemctl statusfstrim.timer如果定时器没有激活,我们需要启用并启动定时器:sudosystemctlenable fstrim.timersudo systemctl startfstrim.timer这样,定时器就会按照计划触发fstrim.service。另外,也可以手动运行一次trim来测试:sudo fstrim-av如果用户希望每周运行一次trim,可以检查定时器的计划:systemctl list-timers fstrim.timer注意:在大多数现代Linux发行版中,fstrim.timer默认是启用的,并且每周运行一次。但有时可能被禁用。如果用户的问题是由于服务被禁用,那么我们可以尝试启用服务?但注意,对于静态服务,启用服务是无效的(会报错)。所以我们应该关注定时器。解决方案总结:1.启用并启动fstrim.timer。2.手动运行一次fstrim以检查是否正常工作。引用说明:根据引用[2],systemd服务重启的条件,但这里不直接相关。我们主要关注如何启用服务/定时器。因此,回答如下:</think>### fstrim.service 无法启动的原因及解决方案 `fstrim.service` 是 Linux 系统中用于 SSD 磁盘维护的服务,其核心功能是执行 `fstrim` 命令,回收未使用的块以优化 SSD 性能。错误信息 **"disabled or static unit not starting"** 通常源于以下原因: #### 📌 根本原因分析 1. **服务状态问题** - `static` 表示该服务不能直接启用/禁用,需通过关联的定时器触发 - `disabled` 表明服务被显式禁用(常见于手动修改) 2. **定时器未激活** fstrim 通过 `fstrim.timer` 触发,若定时器未启用,服务不会自动运行: ```bash systemctl status fstrim.timer ``` ▶️ 若显示 `inactive (dead)` 即定时器未激活 3. **系统配置限制** 某些发行版(如 Ubuntu)默认关闭该服务,需手动启用[^1] #### 🔧 解决方案 ```bash # 1. 启用并启动定时器(关键步骤) sudo systemctl enable fstrim.timer sudo systemctl start fstrim.timer # 2. 手动测试服务功能 sudo systemctl start fstrim.service # 临时运行服务 sudo fstrim -av # 手动执行trim操作 # 3. 验证状态 systemctl list-timers | grep fstrim # 检查定时器计划 journalctl -u fstrim.service # 查看服务日志 ``` #### ⚙️ 配置说明 - **定时器配置文件**:`/usr/lib/systemd/system/fstrim.timer` ▶️ 默认每周触发一次(可通过 `sudo systemctl edit fstrim.timer` 自定义频率) - **服务依赖**: ```ini [Unit] Description=Discard unused blocks ConditionVirtualization=!container ``` 容器环境可能禁用此服务[^2] #### 💡 附加建议 - 若使用 LVM/加密磁盘,确保文件系统支持 trim(`/etc/fstab` 添加 `discard` 选项) - 老旧 SSD 需检查 `/sys/block/sda/queue/discard_granularity` 确认 trim 支持 - 桌面用户可安装 `gnome-disk-utility` 可视化操作
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值