递归火山软件开发平台

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 火山 源码 类库
查看: 81|回复: 1
打印 上一主题 下一主题

[视窗] 系统安装源码火山代码

[复制链接]

3

主题

8

帖子

77

积分

注册会员

Rank: 2

积分
77
跳转到指定楼层
楼主
发表于 昨天 15:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
调用DISM进行系统安装目前
完成功能:映像解析,系统恢复
未完成:引导修复,有思路不知道怎么写  有大佬写出来的吗
引导修复流程如下

----------------------------------(BIOS启动)   则→执行MBR修复⬇
                                        ⬆  
检测启动方式(UEFI或BIOS)                                               执行BCD深度配置→→返回修复结果
                                        ⬆   
------------------------------------(UEFI启动)则→执行UEFI修复 ⬆

个别机器同时兼容(MBR和UEFI启动)这时需要进行检测分区类型(MBR分区是否活动分区或GPT分区检测efi引导分区是否存在如果存 挂载引导分区)
efi引导分区不纯在则根据安装盘符进行取出硬盘所在索引创建efi分区并设置第一分区 修复引导

附上系统安装代码
<火山程序 类型 = "通常" 版本 = 1 />

类 安装系统 <公开 折叠2 @文档 = "category = \"DISM系统恢复\"" @全局类 = 真>
{
    方法 DISM镜像解析 <公开 类型 = 文本型 折叠 @禁止流程检查 = 真>
    参数 映像路径 <类型 = 文本型>
    {

        @ WCHAR szCmd[1024] = {0};
        @ WCHAR szOutput[65536] = {0};
        @ DWORD dwOutputPos = 0;
        @ WCHAR* pFinalResult = NULL;
        @ BOOL bSuccess = FALSE;
        @ INT iCurrentIndex = 0;
        @ WCHAR szCurrentName[256] = {0};
        @ DOUBLE dCurrentSizeGB = 0.0;
        @ BOOL bHasIndex = FALSE;

        @ // 构建 DISM 命令
        @ _snwprintf_s(szCmd, _countof(szCmd), _TRUNCATE,
        @     L"dism /Get-WimInfo /WimFile:\"%s\"",
        @     (LPCWSTR)@<映像路径>.GetText());

        @ // 创建管道
        @ SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, TRUE };
        @ HANDLE hReadPipe = NULL, hWritePipe = NULL;
        @ if (!CreatePipe(&hReadPipe, &hWritePipe, &sa, 0)) {
        @     return L"错误|无法创建管道";
        @ }

        @ // 设置进程启动信息
        @ STARTUPINFOW si = { sizeof(si) };
        @ si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
        @ si.wShowWindow = SW_HIDE;
        @ si.hStdOutput = hWritePipe;
        @ si.hStdError = hWritePipe;

        @ PROCESS_INFORMATION pi = {0};

        @ // 启动 DISM 进程
        @ if (!CreateProcessW(NULL, szCmd, NULL, NULL, TRUE,
        @     CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
        @     CloseHandle(hReadPipe);
        @     CloseHandle(hWritePipe);
        @     return L"错误|无法启动 DISM 进程";
        @ }

        @ // 读取输出
        @ CloseHandle(hWritePipe);
        @ CloseHandle(pi.hThread);

        @ CHAR szBuffer[4096] = {0};
        @ DWORD dwBytesRead = 0;

        @ while (ReadFile(hReadPipe, szBuffer, sizeof(szBuffer)-1, &dwBytesRead, NULL) && dwBytesRead > 0) {
        @     szBuffer[dwBytesRead] = '\0';
        @     INT iConverted = MultiByteToWideChar(CP_ACP, 0, szBuffer, -1,
        @         szOutput + dwOutputPos, _countof(szOutput) - dwOutputPos);
        @     if (iConverted > 0) {
        @         dwOutputPos += iConverted - 1;
        @     }
        @ }

        @ CloseHandle(hReadPipe);
        @ WaitForSingleObject(pi.hProcess, INFINITE);
        @ CloseHandle(pi.hProcess);

        @ // 解析 DISM 输出
        @ WCHAR* pLine = szOutput;
        @ WCHAR* pEnd = szOutput + wcslen(szOutput);
        @ WCHAR szResult[4096] = {0};

        @ while (pLine < pEnd) {
        @     WCHAR* pLineEnd = pLine;
        @     while (*pLineEnd != L'\r' && *pLineEnd != L'\n' && pLineEnd < pEnd) pLineEnd++;
        @     WCHAR cSaved = *pLineEnd;
        @     *pLineEnd = L'\0';

        @     // 解析索引
        @     if (wcsstr(pLine, L"索引:") == pLine) {
        @         if (bHasIndex) {
        @             // 添加分隔符
        @             if (wcslen(szResult) > 0) {
        @                 wcscat_s(szResult, _countof(szResult), L"-");
        @             }
        @             // 添加条目
        @             WCHAR szEntry[512];
        @             _snwprintf_s(szEntry, _countof(szEntry), _TRUNCATE,
        @                 L"%d:%s[%.2fGB]", iCurrentIndex, szCurrentName, dCurrentSizeGB);
        @             wcscat_s(szResult, _countof(szResult), szEntry);
        @         }
        @         iCurrentIndex = _wtoi(pLine + 4);
        @         szCurrentName[0] = L'\0';
        @         dCurrentSizeGB = 0.0;
        @         bHasIndex = TRUE;
        @     }
        @     // 解析名称
        @     else if (wcsstr(pLine, L"名称:") == pLine) {
        @         WCHAR* pNameStart = pLine + 4;
        @         while (*pNameStart == L' ') pNameStart++;
        @         wcscpy_s(szCurrentName, _countof(szCurrentName), pNameStart);
        @     }
        @     // 解析大小
        @     else if (wcsstr(pLine, L"大小:") == pLine) {
        @         WCHAR* pSizeStart = pLine + 4;
        @         WCHAR szSizeStr[256] = {0};
        @         WCHAR* p = szSizeStr;
        @         while (*pSizeStart && (p - szSizeStr) < 255) {
        @             if (*pSizeStart >= L'0' && *pSizeStart <= L'9') {
        @                 *p++ = *pSizeStart;
        @             }
        @             pSizeStart++;
        @         }
        @         *p = L'\0';
        @         if (szSizeStr[0]) {
        @             dCurrentSizeGB = _wtoi64(szSizeStr) / 1073741824.0; // 转换为 GB
        @         }
        @     }

        @     *pLineEnd = cSaved;
        @     pLine = pLineEnd;
        @     while ((*pLine == L'\r' || *pLine == L'\n') && pLine < pEnd) pLine++;
        @ }

        @ // 添加最后一个镜像
        @ if (bHasIndex) {
        @     if (wcslen(szResult) > 0) {
        @         wcscat_s(szResult, _countof(szResult), L"-");
        @     }
        @     WCHAR szEntry[512];
        @     _snwprintf_s(szEntry, _countof(szEntry), _TRUNCATE,
        @         L"%d:%s[%.2fGB]", iCurrentIndex, szCurrentName, dCurrentSizeGB);
        @     wcscat_s(szResult, _countof(szResult), szEntry);
        @     bSuccess = TRUE;
        @ }

        @ if (!bSuccess) {
        @     return L"错误|未找到有效的镜像信息";
        @ }

        @ // 返回结果
        @ pFinalResult = (WCHAR*)LocalAlloc(LPTR, (wcslen(szResult)+1)*sizeof(WCHAR));
        @ wcscpy_s(pFinalResult, wcslen(szResult)+1, szResult);
        @ return (LPCWSTR)pFinalResult;

    }

    方法 DISM安装 <公开 类型 = 文本型 折叠 @禁止流程检查 = 真>
    参数 映像路径 <类型 = 文本型>
    参数 目标磁盘 <类型 = 文本型>
    参数 映像索引 <类型 = 整数>
    {
        @ // 安全稳定版:修复所有缓冲区溢出问题
        @ static volatile LONG progress = 0;
        @ static volatile BOOL isRunning = FALSE;
        @ static WCHAR status[256] = L"等待开始";
        @ static HANDLE hReadPipe = INVALID_HANDLE_VALUE;
        @ static HANDLE hProcess = INVALID_HANDLE_VALUE;
        @ static CRITICAL_SECTION cs;
        @ static BOOL csInitialized = FALSE;
        @ static CHAR lastBuffer[4096] = {0};

        @ // 安全初始化临界区
        @ if (!csInitialized) {
        @     InitializeCriticalSection(&cs);
        @     csInitialized = TRUE;
        @     lastBuffer[0] = '\0';
        @ }

        @ EnterCriticalSection(&cs);

        @ // 安全处理运行中任务
        @ if (isRunning) {
        @     if (hReadPipe != INVALID_HANDLE_VALUE) {
        @         DWORD bytesAvailable = 0;
        @         if (PeekNamedPipe(hReadPipe, NULL, 0, NULL, &bytesAvailable, NULL) && bytesAvailable > 0) {
        @             CHAR buffer[4096] = {0};
        @             DWORD bytesRead = 0;
        @            
        @             if (ReadFile(hReadPipe, buffer, sizeof(buffer)-1, &bytesRead, NULL) && bytesRead > 0) {
        @                 buffer[bytesRead] = '\0';
        @                 
        @                 // 安全缓冲区拼接
        @                 size_t currentLen = strnlen_s(lastBuffer, sizeof(lastBuffer));
        @                 if (currentLen + bytesRead < sizeof(lastBuffer)) {
        @                     strcat_s(lastBuffer, sizeof(lastBuffer), buffer);
        @                 } else {
        @                     size_t overflow = (currentLen + bytesRead) - sizeof(lastBuffer) + 1;
        @                     memmove_s(lastBuffer, sizeof(lastBuffer),
        @                              lastBuffer + overflow,
        @                              sizeof(lastBuffer) - overflow);
        @                     strcat_s(lastBuffer, sizeof(lastBuffer), buffer);
        @                 }
        @                 
        @                 // 安全解析进度(仅捕获百分比,过滤无关日志)
        @                 const CHAR* p = lastBuffer;
        @                 while (*p != '\0') {
        @                     if (*p == '[') {
        @                         const CHAR* percentPos = strchr(p, '%');
        @                         if (percentPos != NULL && (percentPos - p) < 50) {
        @                             const CHAR* numStart = percentPos - 1;
        @                             while (numStart > p &&
        @                                 (isdigit(*numStart) || *numStart == '.')) {
        @                                 numStart--;
        @                             }
        @                             
        @                             if (numStart < percentPos) {
        @                                 float newProgress = 0.0f;
        @                                 if (sscanf_s(numStart + 1, "%f", &newProgress) == 1) {
        @                                     progress = max(progress, min((int)newProgress, 99));
        @                                     _snwprintf_s(status, _countof(status), _TRUNCATE, L"正在应用映像");
        @                                 }
        @                             }
        @                         }
        @                     }
        @                     p++;
        @                 }
        @             }
        @         }
        @     }
        @     
        @     // 安全检查进程状态
        @     if (hProcess != INVALID_HANDLE_VALUE) {
        @         DWORD exitCode = 0;
        @         if (GetExitCodeProcess(hProcess, &exitCode)) {
        @             if (exitCode != STILL_ACTIVE) {
        @                 isRunning = FALSE;
        @                 progress = (exitCode == 0) ? 100 : 0;
        @                 _snwprintf_s(status, _countof(status), _TRUNCATE,
        @                     exitCode == 0 ? L"安装完成" : L"失败(错误码:%d)", exitCode);
        @                 
        @                 if (hReadPipe != INVALID_HANDLE_VALUE) {
        @                     CloseHandle(hReadPipe);
        @                     hReadPipe = INVALID_HANDLE_VALUE;
        @                 }
        @                 if (hProcess != INVALID_HANDLE_VALUE) {
        @                     CloseHandle(hProcess);
        @                     hProcess = INVALID_HANDLE_VALUE;
        @                 }
        @             }
        @         }
        @     }
        @     
        @     // 返回格式:"进度|状态"(确保不返回无关日志)
        @     WCHAR result[256] = {0};
        @     _snwprintf_s(result, _countof(result), _TRUNCATE, L"%d|%s", progress, status);
        @     LeaveCriticalSection(&cs);
        @     return result;
        @ }

        @ // 安全启动新任务
        @ isRunning = TRUE;
        @ progress = 0;
        @ lastBuffer[0] = '\0';
        @ wcscpy_s(status, _countof(status), L"正在初始化");

        @ // 创建安全管道
        @ SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, TRUE };
        @ HANDLE hWritePipe = INVALID_HANDLE_VALUE;
        @ if (!CreatePipe(&hReadPipe, &hWritePipe, &sa, 4096)) {
        @     isRunning = FALSE;
        @     DWORD err = GetLastError();
        @     _snwprintf_s(status, _countof(status), _TRUNCATE, L"失败(错误码:%d)", err);
        @     WCHAR result[256] = {0};
        @     _snwprintf_s(result, _countof(result), _TRUNCATE, L"0|%s", status);
        @     LeaveCriticalSection(&cs);
        @     return result;
        @ }

        @ // 安全准备命令
        @ WCHAR cmd[1024] = {0};
        @ _snwprintf_s(cmd, _countof(cmd), _TRUNCATE,
        @     L"DISM /Apply-Image /ImageFile:\"%s\" /Index:%d /ApplyDir:%s",
        @     (LPCWSTR)@<映像路径>.GetText(),
        @     @<映像索引>,
        @     (LPCWSTR)@<目标磁盘>.GetText());

        @ // 安全启动进程
        @ STARTUPINFOW si = {0};
        @ si.cb = sizeof(si);
        @ si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
        @ si.wShowWindow = SW_HIDE;
        @ si.hStdOutput = hWritePipe;
        @ si.hStdError = hWritePipe;

        @ PROCESS_INFORMATION pi = {0};
        @ BOOL bSuccess = CreateProcessW(
        @     NULL, cmd, NULL, NULL, TRUE,
        @     CREATE_NO_WINDOW | DETACHED_PROCESS | CREATE_UNICODE_ENVIRONMENT,
        @     NULL, NULL, &si, &pi);

        @ // 安全清理
        @ if (hWritePipe != INVALID_HANDLE_VALUE) {
        @     CloseHandle(hWritePipe);
        @ }

        @ if (bSuccess) {
        @     hProcess = pi.hProcess;
        @     CloseHandle(pi.hThread);
        @     progress = 5;
        @     wcscpy_s(status, _countof(status), L"正在应用映像");
        @ } else {
        @     DWORD err = GetLastError();
        @     isRunning = FALSE;
        @     if (hReadPipe != INVALID_HANDLE_VALUE) {
        @         CloseHandle(hReadPipe);
        @         hReadPipe = INVALID_HANDLE_VALUE;
        @     }
        @     _snwprintf_s(status, _countof(status), _TRUNCATE, L"失败(错误码:%d)", err);
        @ }

        @ // 返回格式:"进度|状态"(确保不返回无关日志)
        @ WCHAR result[256] = {0};
        @ _snwprintf_s(result, _countof(result), _TRUNCATE, L"%d|%s", progress, status);
        @ LeaveCriticalSection(&cs);
        @ return result;

    }
}



回复

使用道具 举报

14

主题

302

帖子

2244

积分

核心用户

Rank: 9Rank: 9Rank: 9

积分
2244
沙发
发表于 昨天 19:00 | 只看该作者
厉害!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|递归火山软件开发平台 ( 鄂ICP备18029190号 )

GMT+8, 2025-6-27 00:05 , Processed in 0.090891 second(s), 19 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表