2024年3月3日 星期日

【已解決】安全性更新 KB5034441 無法安裝 0x80070643 錯誤

【已解決】安全性更新 KB5034441 無法安裝 0x80070643 錯誤

針對這次更新官方的說明:KB5034441: 適用於 Windows 10 版本 21H2 和 22H2 的 Windows 修復環境更新: 2024 年 1 月 9 日 - Microsoft 支援服務

裡面明確的提到這次造成災難的主因

此更新需要修復磁碟分割區中有 250 MB 的可用空間才可成功安裝。 如果修復磁碟分割區沒有足夠的可用空間,此更新將會失敗。

(另一個解法是就不解決了直接使用微軟的工具隱藏掉更新)


回到正題,正常來說RE分區太小會自動生成新的變成兩個,但這次似乎並沒有自動生成而是直接跳錯了。

這次的問題不外乎就幾個三情況

  1. 不明原因RE分區被關掉 (單純重啟即可)
  2. 手癢把RE分區砍了 (要找其他電腦補檔案)
  3. 本次更新 KB5034441 包含900M的RE映像檔,RE分區容量不足導致的
    (有能力的話用分區軟體直接調大RE分區也可)

以下代碼請用管理員打開 PowerShell 後貼上執行 (命令提示字元不行)


執行過程可以參考這部影片




步驟1 重新啟用RE分區

先看一下啥狀況 (若已經是啟用狀態直接跳步驟3)

reagentc /info

如果是關閉狀態重啟看看 (某些情況卡BUG可能需要兩次)

reagentc /enable

出現 REAGENTC.EXE: 找不到 Windows RE 映像。 的話繼續步驟2補檔案
成功啟用或是本來就是啟用狀態的話,直接跳到步驟3就行了



步驟2 修復RE映像檔

無法重啟且這個路徑底下沒有 winre.wim 映像檔

C:\windows\system32\recovery

(這檔案可能是隱藏的記得打開檢視隱藏檔)

如果沒有檔案,參考這裡文末提供的檔案,放到上述的位置即可
https://charlottehong.blogspot.com/2018/02/windows-re.html



步驟3 重新生成修復分區

先把原本的刪除乾淨,參考的是這篇文章的工具

執行這段代碼,會自動刪除當前使用中的修復分區,並合併到前方分區

irm bit.ly/EditRecovery|iex; Remove-RecoveryPartition -Current -Merage -ForceEnable




然後接下來需要重新生成RE分區,參考這篇文章的工具

執行這段代碼,從C曹壓縮1G出來生成修復分區並重新啟用RE系統

irm bit.ly/EditRecovery|iex; New-RecoveryPartition -Size 1280MB -ReEnableRecovery


生成1G的修復分區之後就可以正常更新了。




錯誤應對

如果是舊系統一路升級上來的,似乎有一定概率會遇到一個問題是,C曹無法被壓縮



具體的原因是因為系統檔案正好被寫在C曹的結尾處,以至於磁碟管理內建的功能無法壓縮磁碟,這個只能用第三方的軟體處理,而且還必須要有第二個系統才能處理

遇到的話比較推薦的做法是刪除修復分區後(也就是執行第二個指令後看到上圖的錯誤時),直接啟用RE系統就好


啟用RE系統

reagentc /enable; reagentc /info


這時候由於沒有修復分區,系統會直接用C槽來頂替,RE系統的映像檔會展開到C槽底下。結果而言RE系統可以正常動作,更新也可以正常更新。




參考

  1. 【已解決】(請看留言B12) 0x80070643 安全性更新KB5034441無法安裝 @電腦應用綜合討論 哈啦板 - 巴哈姆特 (gamer.com.tw)
  2. KB5034441: 適用於 Windows 10 版本 21H2 和 22H2 的 Windows 修復環境更新: 2024 年 1 月 9 日 - Microsoft 支援服務
  3. KB5028997: 手動調整磁碟分割區大小以安裝 WinRE 更新的指示 - Microsoft 支援服務
  4. Windows 10 解除安裝更新與隱藏更新 - Microsoft 社群

2024年2月14日 星期三

PowerShell 從網址下載檔案的所有方法

PowerShell 從網址下載檔案的所有方法


驗證網址是否有效

在下載前要先確認網址是否有效,比較簡易有效率的方法試直接驗Head就行,邏輯簡單但可能會有不適用情況,再自行調整。

# 檢查鏈接是否有效
function Test-URI {
    param (
        [Parameter(Mandatory)]
        [string] $Uri
    )
    try {
        # 嘗試發送 HEAD 請求
        $response = Invoke-WebRequest -Uri $Uri -Method Head -TimeoutSec 10
        # 檢查 HTTP 狀態碼是否為 200
        if ($response -and $response.StatusCode -eq 200) {
            return $true
        } else {
            # Write-Warning "Received HTTP status code $($response.StatusCode). The link might not be valid."
            return $false
        }
    } catch {
        # Write-Warning "Error checking the link: $_"
        return $null
    }
}

用例

$link = 'https://www.google.com/'
if (!(Test-URI $link)) {
    Write-Error "The link might not be valid" -ErrorAction Stop
} else { Write-Host $link -ForegroundColor DarkGray }




下載指令

這裡有好幾個指令大概簡單介紹一下,自己挑一個合適的用


方法1 .Net 方法

最建議使用的方法
事實上有許多大型專案的教學安裝時用指令就是這個

(New-Object Net.WebClient).DownloadFile($Url, $DLPath)


方法2 Start-BitsTransfer 方法

這個載起來也比 Invoke-WebRequest 好上一些,有個優點是可以續傳
不過只能在 Windwos 下使用並且如果系統本身沒啟用該服務也會無法使用

Start-BitsTransfer -Source $Url -Destination $DLPath


方法3 Invoke-WebRequest 方法

這個其實更適合用來載純文字的網址,主要是用來查網頁Headder之類的

其他還有好幾個別名可以用

  • curl -> Invoke-WebRequest
  • iwr -> Invoke-WebRequest
  • wget -> Invoke-WebRequest
Invoke-WebRequest -Uri $Url -OutFile $DLPath



2024年2月11日 星期日

Onedrive突然變成全亂碼 奇怪的語言

Onedrive突然變成全亂碼 奇怪的語言

之前幫朋友處理過突然他的 Onedrive 變成奇怪的語言,但仔細看又好像不是語言是亂碼



測試過用線上網頁看是正常的,並不是設置到語言

最後是重新安裝了 Onedrive 解決掉的
https://www.microsoft.com/zh-hk/microsoft-365/onedrive/download

移除的話直接到新增移除程式把 Onedrive 刪除即可,重裝就可以復原了

2024年2月4日 星期日

[Win10/11] 如何新增 修復磁碟分割區 (RE分區)

[Win10/11] 如何新增 修復磁碟分割區 (RE分區)

繼上一篇刪除的,這篇來說明如何新增
https://charlottehong.blogspot.com/2022/06/win1011-re.html

以下代碼要使用管理員模式打開 PowerShell 後執行
有個比較快捷的方式是對著開始按右鍵然後選擇 終端機(系統管理員) 打開


新增修復分區

這邊直接提供寫好的程式,能簡易的追加出修復分區


New-RecoveryPartition 各項參數的意義
-Size
要追加的修復分區的大小

-CompressDriveLetter
從哪個磁碟壓縮容量 (預設C)

-RestartRecovery
追加完後嘗試啟用RE系統


PowerShell 管理員權限執行

irm bit.ly/EditRecovery|iex; New-RecoveryPartition -Size 1024MB -RestartRecovery

執行完畢會自行從C槽壓縮出1024MB做成RE分區




[圖文] OpenCV 4.9.0 安裝配置在Win11 Visual Studio 2022

[圖文] OpenCV 4.9.0 安裝配置在 Visual Studio 2022

-



安裝 OpenCV 與文件說明

先到官方下載這兩項軟體 (點擊有連結)
https://opencv.org/releases/



打開之後即可安裝,把他指定到C槽



會用到的路徑有這下面這些

  1. 執行檔目錄

    C:\opencv\build\x64\vc16\bin
  2. 包含目錄

    C:\opencv\build\include
  3. 程式庫目錄

    C:\opencv\build\x64\vc16\lib
  4. 程式庫檔案

    opencv_world490d.lib (Debug Mode)
    opencv_world490.lib (Release Mode)



設定環境變數

打開設定,並依照下圖打開進階系統設定

系統 → 系統資訊 (截圖少點開"系統資訊"的步驟,這個在最下方)



然後在環境變數 Path 中追加這個路徑

C:\opencv\build\x64\vc16\bin


再來依序按"確定"把所有視窗關閉,這邊的步驟電腦設置一次即可。



設置 OpenCV 專案

再來打開 Visual Studio 2022 建立新的專案



選擇空白專案



專案名稱隨意預設即可



建立好專案之後先建立好空的 cpp 檔案



檔名隨意這邊是取 OpenCVTest.cpp



然後對著專案按右鍵屬性



設置包含目錄

C:\opencv\build\include



設置程式庫目錄

C:\opencv\build\x64\vc16\lib



設置程式庫檔案 (沒有d結尾的檔案是Release模式用的)

opencv_world490d.lib



到這邊針對這個專案就設置好了,這邊的設定更換專案的話還得再來一次



測試 OpenCV 執行結果

在剛剛創建的空檔案貼上下面的代碼

/*****************************************************************************
Name :
Date : 2016/05/29
By   : CharlotteHonG
Final: 2016/05/29
*****************************************************************************/
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;

int main(int argc, char const* argv[]) {
    /* 畫布 */
    Mat img(270, 720, CV_8UC3, Scalar(56, 50, 38));
    /* 直線 */
    line(img, Point(20, 40), Point(120, 140), Scalar(255, 0, 0), 3);
    /* 實心方塊 */
    rectangle(img, Point(150, 40), Point(250, 140), Scalar(0, 0, 255), -1);
    /* 實心圓 */
    circle(img, Point(330, 90), 50, Scalar(0, 255, 0), -1);
    /* 空心橢圓 */
    ellipse(img, Point(460, 90), Size(60, 40), 45, 0, 360, Scalar(255, 255, 0), 2);
    /* 不規則圖形 */
    Point points[1][5];
    int x = 40, y = 540;
    points[0][0] = Point(0 + y, 50 + x);
    points[0][1] = Point(40 + y, 0 + x);
    points[0][2] = Point(110 + y, 35 + x);
    points[0][3] = Point(74 + y, 76 + x);
    points[0][4] = Point(28 + y, 96 + x);
    const Point* ppt[1] = { points[0] };
    int npt[] = { 5 };
    polylines(img, ppt, npt, 1, 1, Scalar(0, 255, 255), 3);
    /* 繪出文字 */
    putText(img, "Test Passed !!", Point(10, 230), 0, 3, Scalar(255, 170, 130), 3);
    /* 開啟畫布 */
    namedWindow("OpenCV Test By:Charlotte.HonG", WINDOW_AUTOSIZE);
    imshow("OpenCV Test By:Charlotte.HonG", img);
    waitKey(0);
    return 0;
}


然後按下 F5 執行或是上方的 本機偵錯工具 執行該代碼



執行後如果看到這圖就表示成功了



好了,就此就完成了


2023年12月22日 星期五

Bat/PowerShell 提權執行的指令

Bat/PowerShell 提權執行的指令



PowerShell

啟動一個新的進程並以管理員權限執行指定的命令

Start-Process 'cmd.exe' -ArgumentList "/c $cmdStr" -Verb RunAs



Bat 通常解法

批處理檔(.bat 檔)中實現類似的功能,事情就有些不同了,因為批處理檔沒有內建的提升權限命令。

一種解決方案是創建一個臨時的 VBScript 檔,這個腳本會觸發 UAC 提示以提升權限,然後執行您的批處理檔。這裡有一個例子:

  • 1. 創建一個 VBScript 檔案:
保存以下代碼到一個 .vbs 檔案,例如 elevate.vbs。這段代碼會以管理員身份執行一個指定的命令。
If WScript.Arguments.Count >= 1 Then
    Command = WScript.Arguments(0)
    Set Shell = CreateObject("Shell.Application")
    Shell.ShellExecute "cmd.exe", "/c " & Command, "", "runas", 1
End If


  • 2. 從批處理檔中調用這個 VBScript:
在您的 .bat 檔案中,使用以下命令來調用 elevate.vbs,並傳遞您想要以管理員權限執行的命令作為參數。
cscript //nologo elevate.vbs "您的命令"




進階手段

先利用執行內建需要管理員的程式來判斷是不是管理員

  1. 如果不是則委託給 PowerShell 重新讀取自己再次執行,並結束(並免重複執行自己)
  2. 如果已經是則繼續執行底下 bat

只需要將這行貼在首行即可

fltmc >nul || (set Admin=/x /d /c call "%~f0" %* & powershell -nop -c start cmd $env:Admin -verb runas; & exit /b)





2023年12月21日 星期四

PowerShell 如何讀取解析 Env/Properties 檔案

PowerShell 如何讀取解析 Env/Properties 檔案

實作做的功能包含了

  1. 自動讀取 “.env”, “.env.development”, “.env.production” 三個檔案,優先順序是後面覆蓋前面,同檔案間優先順序也是後面覆蓋前面
  2. 支援擴充功能使用斜線換行
  3. 支援擴充功能雙引號解析 PowerShell 變數


為什麼要拆分這麼多env檔案主要是兩個觀點

  1. 把連接資訊放在“.env.production”中避免部署設置時不小心動到連接資訊。
  2. 拆分development跟production,僅共用.env檔案這樣可以很好的區分開發機跟生產環境


範例 .env

A1="  AAA  
A2=  AAA  "
B1=" AAA "
B2=' AAA '
C1= \
arr1,\
arr2
D1="$($env:USERNAME)"
D2='$($env:USERNAME)'
Z=\
A\
B\
C\
D\


讀取用函式
ConvertFrom-Env.ps1

# 轉換 Env 文件
function ConvertFrom-Env {
    param (
        [string[]]$EnvFiles = @(".env", ".env.development", ".env.production"),
        [System.Text.Encoding]$Encoding = [System.Text.Encoding]::Default
    )

    # 使用有序字典保持讀取的順序
    $envVariables = [Ordered]@{}

    function ProcessLine {
        param (
            [string]$line
        )

        # 忽略註釋行
        if ($line -and -not $line.StartsWith("#")) {
            if ($line -match "^\s*([^#=]+?)\s*=\s*(.*)$") {
                $key = $matches[1].Trim()
                $value = $matches[2]
                if ($value -match '^"(.+)"$') {
                    # 處理雙引號包圍的值並展開字符串
                    $value = $matches[1] -replace '\\n', "`n" -replace '\\r', "`r" -replace '\\t', "`t"
                    $value = $ExecutionContext.InvokeCommand.ExpandString($value)
                } elseif ($value -match "^'(.+)'$") {
                    # 處理單引號包圍的值
                    $value = $matches[1]
                } else {
                    $value = $value.Trim()
                }

                # 將解析後的鍵值對加入字典
                $envVariables[$key] = $value
            }
        }
    }

    # 遍歷所有指定的文件
    foreach ($file in $EnvFiles) {
        if (Test-Path $file) {
            try {
                $reader = New-Object System.IO.StreamReader -ArgumentList $file, $Encoding
                try {
                    $currentLine = ''
                    while ($null -ne ($line = $reader.ReadLine())) {
                        $trimmedLine = $line.Trim()
                        if ($trimmedLine.EndsWith('\')) {
                            # 跨行值的處理
                            $currentLine += $trimmedLine.TrimEnd('\').TrimEnd()
                            continue
                        } else {
                            $currentLine += $trimmedLine
                        }
                        ProcessLine -line $currentLine
                        $currentLine = ''
                    }
                    # 處理跨行結尾在最一行時沒被處理的剩餘值
                    if ($currentLine) { ProcessLine -line $currentLine }
                } finally {
                    $reader.Close()
                }
            } catch {
                Write-Warning "無法讀取文件 '$file': $_"
            }
        }
    } # $envVariables = [PSCustomObject]$envVariables
    return $envVariables
} ConvertFrom-Env


代碼開源於此: hunandy14/ConvertFrom-Env (github.com)