当前位置: 首页 > news >正文

【C++】防止机械/移动硬盘休眠 - NoSleepHD

初衷         

        由于外置机械桌面硬盘总是在p图找素材的时候自动休眠,总是要不时的唤醒重启很麻烦,所以写了个防止机械/移动硬盘休眠软件。

原理

        原理是定期向硬盘中进行文件操作从而防止硬盘休眠。这里是每60秒向硬盘创建一个文件后立刻删除,即可以唤醒硬盘又没有残留。

        设置了定时退出器,程序到时间会自动退出。(由于每60秒写一次文件,这里的倒计时采用的是每次-1,而不是真的定时器。)

运行截图

代码

#include <windows.h>
#include <iostream>
#include <string>
#include <chrono>
#include <thread>
#include <vector>
#include <sstream>
#include <io.h>
#include <fcntl.h>

// 添加一个辅助函数来输出中文
void PrintW(const wchar_t* text) {
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    DWORD written;
    WriteConsoleW(hConsole, text, wcslen(text), &written, NULL);
}

// 获取可用的硬盘列表
std::vector<char> GetAvailableDrives() {
    std::vector<char> drives;
    DWORD driveMask = GetLogicalDrives();
    
    for (char drive = 'A'; drive <= 'Z'; drive++) {
        if (driveMask & 1) {
            std::string rootPath = std::string(1, drive) + ":\\";
            UINT driveType = GetDriveTypeA(rootPath.c_str());
            
            // 只显示可移动驱动器和固定驱动器
            if (driveType == DRIVE_REMOVABLE || driveType == DRIVE_FIXED) {
                drives.push_back(drive);
            }
        }
        driveMask >>= 1;
    }
    return drives;
}

// 写入文件到指定驱动器
void WriteToFile(char drive, int remainingMinutes) {
    std::string filePath = std::string(1, drive) + ":\\temp_disk_awake";
    HANDLE hFile = CreateFileA(
        filePath.c_str(),
        GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
        NULL
    );
    
    if (hFile != INVALID_HANDLE_VALUE) {
        CloseHandle(hFile);  // 立即关闭文件,会自动删除
        
        // 只在控制台显示时间信息
        SYSTEMTIME st;
        GetLocalTime(&st);
        wchar_t timeStr[200];
        if (remainingMinutes >= 0) {
            swprintf_s(timeStr, L"%c: 写入成功: %04d-%02d-%02d %02d:%02d:%02d,剩余时间:%d 分钟\n",
                drive, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, remainingMinutes);
        } else {
            swprintf_s(timeStr, L"%c: 写入成功: %04d-%02d-%02d %02d:%02d:%02d\n",
                drive, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
        }
        PrintW(timeStr);
    } else {
        wchar_t errorStr[100];
        swprintf_s(errorStr, L"%c: 无法访问磁盘,请确保磁盘已连接且有写入权限\n", drive);
        PrintW(errorStr);
    }
}

int main() {
    _setmode(_fileno(stdout), _O_U16TEXT);
    
    // 获取并显示可用驱动器
    std::vector<char> drives = GetAvailableDrives();
    PrintW(L"可用的驱动器:\n");
    for (size_t i = 0; i < drives.size(); i++) {
        wchar_t driveStr[100];
        swprintf_s(driveStr, L"%zd. %c:\\\n", i + 1, drives[i]);
        PrintW(driveStr);
    }
    
    PrintW(L"请输入要保持唤醒的驱动器编号(多个驱动器用空格分隔,如:1 3):");
    std::string input;
    std::getline(std::cin, input);
    
    // 解析用户输入
    std::vector<char> selectedDrives;
    std::stringstream ss(input);
    int choice;
    while (ss >> choice) {
        if (choice > 0 && choice <= static_cast<int>(drives.size())) {
            selectedDrives.push_back(drives[choice - 1]);
        }
    }
    
    if (selectedDrives.empty()) {
        PrintW(L"未选择任何驱动器,程序退出\n");
        return 1;
    }
    
    PrintW(L"是否需要定时退出?(y/n):");
    char timerChoice;
    std::cin >> timerChoice;
    std::cin.ignore(1000, '\n');
    
    int totalMinutes = -1;  // -1 表示无限运行
    if (timerChoice == 'y' || timerChoice == 'Y') {
        PrintW(L"请输入程序运行时间(分钟):");
        std::cin >> totalMinutes;
        if (totalMinutes <= 0) {
            PrintW(L"时间设置无效,程序退出\n");
            return 1;
        }
    }
    
    PrintW(L"已选择的驱动器:");
    for (char drive : selectedDrives) {
        wchar_t driveStr[10];
        swprintf_s(driveStr, L"%c: ", drive);
        PrintW(driveStr);
    }
    PrintW(L"\n");
    
    wchar_t startMsg[200];
    if (totalMinutes > 0) {
        swprintf_s(startMsg, L"程序已启动,将运行 %d 分钟,每60秒写入一次数据来保持硬盘唤醒...\n", totalMinutes);
    } else {
        swprintf_s(startMsg, L"程序已启动,将持续运行,每60秒写入一次数据来保持硬盘唤醒...\n");
    }
    PrintW(startMsg);
    PrintW(L"按Ctrl+C终止程序\n");
    
    int remainingMinutes = totalMinutes;
    
    while (true) {
        // 写入所有选中的驱动器
        for (char drive : selectedDrives) {
            WriteToFile(drive, remainingMinutes);
        }
        
        // 如果是最后一次写入(remainingMinutes == 0),直接退出
        if (remainingMinutes == 0) {
            break;
        }
        
        // 不是最后一次,则等待并继续
        std::this_thread::sleep_for(std::chrono::seconds(60));
        
        // 更新计时器(只在有限时间模式下)
        if (remainingMinutes > 0) {
            remainingMinutes--;
        }
        // remainingMinutes == -1 时继续循环(无限运行模式)
    }
    
    if (totalMinutes > 0) {
        PrintW(L"\n设定时间已到,程序退出\n");
    }
    return 0;
}
    

相关文章:

  • start DL from stratch (2)!!!
  • 【AI+智造】南京江北新区制造业特点分析及智慧设备运维诊断开发方案
  • RocketMQ的运行架构
  • [特殊字符]【CVPR2024新突破】Logit标准化:知识蒸馏中的自适应温度革命[特殊字符]
  • 中科大 计算机网络原理 第一章 1.6分组延迟、丢失和吞吐量 笔记
  • 如何把网络ip改为动态:全面指南
  • 一个基于C# Winform开源免费的通用快速开发框架,内置完整的权限架构!
  • python爬虫报错信息解决方法
  • C++22——哈希
  • 基于Springboot博物馆文博资源库系统【附源码】
  • 传输层协议TCP
  • Python从0到100(八十九):Resnet、LSTM、Shufflenet、CNN四种网络分析及对比
  • linux学习笔记3
  • Spring IoC
  • kafka consumer 手动 ack
  • 详解直方图均衡化
  • Java最新面试题(全网最全、最细、附答案)
  • mysql 全方位安装教程
  • jvm内存区域、调优参数,堆区栈区分别存什么
  • Buildroot学习笔记
  • 廊坊哪里有做网站建设的/阿里指数官方网站
  • 企业如何选择网站/百度的官方网站
  • 企业网站备案怎么做/百度快照没有了用什么代替了
  • 公司做网站需要多少钱/北京百度搜索排名优化
  • 大连金州/太原建站seo
  • 两款WordPress加速/华为seo诊断及优化分析