2550509504 发表于 2025-6-26 15:16:06

系统安装源码火山代码

调用DISM进行系统安装目前
完成功能:映像解析,系统恢复
未完成:引导修复,有思路不知道怎么写有大佬写出来的吗
引导修复流程如下

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

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

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

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

      @ WCHAR szCmd = {0};
      @ WCHAR szOutput = {0};
      @ DWORD dwOutputPos = 0;
      @ WCHAR* pFinalResult = NULL;
      @ BOOL bSuccess = FALSE;
      @ INT iCurrentIndex = 0;
      @ WCHAR szCurrentName = {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 = {0};
      @ DWORD dwBytesRead = 0;

      @ while (ReadFile(hReadPipe, szBuffer, sizeof(szBuffer)-1, &dwBytesRead, NULL) && dwBytesRead > 0) {
      @   szBuffer = '\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 = {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;
      @             _snwprintf_s(szEntry, _countof(szEntry), _TRUNCATE,
      @               L"%d:%s[%.2fGB]", iCurrentIndex, szCurrentName, dCurrentSizeGB);
      @             wcscat_s(szResult, _countof(szResult), szEntry);
      @         }
      @         iCurrentIndex = _wtoi(pLine + 4);
      @         szCurrentName = 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 = {0};
      @         WCHAR* p = szSizeStr;
      @         while (*pSizeStart && (p - szSizeStr) < 255) {
      @             if (*pSizeStart >= L'0' && *pSizeStart <= L'9') {
      @               *p++ = *pSizeStart;
      @             }
      @             pSizeStart++;
      @         }
      @         *p = L'\0';
      @         if (szSizeStr) {
      @             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;
      @   _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 = L"等待开始";
      @ static HANDLE hReadPipe = INVALID_HANDLE_VALUE;
      @ static HANDLE hProcess = INVALID_HANDLE_VALUE;
      @ static CRITICAL_SECTION cs;
      @ static BOOL csInitialized = FALSE;
      @ static CHAR lastBuffer = {0};

      @ // 安全初始化临界区
      @ if (!csInitialized) {
      @   InitializeCriticalSection(&cs);
      @   csInitialized = TRUE;
      @   lastBuffer = '\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 = {0};
      @             DWORD bytesRead = 0;
      @            
      @             if (ReadFile(hReadPipe, buffer, sizeof(buffer)-1, &bytesRead, NULL) && bytesRead > 0) {
      @               buffer = '\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 = {0};
      @   _snwprintf_s(result, _countof(result), _TRUNCATE, L"%d|%s", progress, status);
      @   LeaveCriticalSection(&cs);
      @   return result;
      @ }

      @ // 安全启动新任务
      @ isRunning = TRUE;
      @ progress = 0;
      @ lastBuffer = '\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 = {0};
      @   _snwprintf_s(result, _countof(result), _TRUNCATE, L"0|%s", status);
      @   LeaveCriticalSection(&cs);
      @   return result;
      @ }

      @ // 安全准备命令
      @ WCHAR cmd = {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 = {0};
      @ _snwprintf_s(result, _countof(result), _TRUNCATE, L"%d|%s", progress, status);
      @ LeaveCriticalSection(&cs);
      @ return result;

    }
}



2oon 发表于 2025-6-26 19:00:36

厉害!
页: [1]
查看完整版本: 系统安装源码火山代码