2023年10月12日 星期四

Bat/PowerShell 中呼叫外部程序 ssh 亂碼 (編碼轉換函式)

Bat/PowerShell 中呼叫外部程序 ssh 亂碼 (編碼轉換函式)

遇到的情況蠻坑人的某些程序預設會強制使用 utf8 ,這會導這不支援的 cmd 直接就攤手出亂碼了

還特別坑的是 ssh 會強制修改 chcp 改成 65001 導致出錯誤信息的時候連帶後面的 echo 都一起跟著亂碼了

想了很多辦法最後試出來的是,委託給powershell執行,雖然還是無法避免被切 chcp 不過可以一起封裝在裡面執行完順便切回來





如何正確的在bat中打印utf8編碼的文字

先說一下最簡情況,我們一步一步來強化,首先就是丟進去執行

powershell -nop "winscp.com /script=script.txtx; exit $lastexitcode"


如此一來就可以得到正確的文字了,順便用 Exit 把執行的返回代碼給帶出來。
此時 PowerShell 會把執行結果回丟到 Cmd 上,可以在透過一般的寫法完整的捕捉到。

powershell -nop "winscp.com /script=script.txtx; exit $lastexitcode" > %LOG% 2>&1


這樣錯誤信息也會一起出來了。
再來下一步我們把重要的指令部分提取出來用管道送進去,剩下不重要的封裝在裡面

echo winscp.com /script=script.txt| powershell -nop "$input|iex; exit $lastexitcode"


這樣就抽取出來了,只需要在意管道的左邊即可,剩下都封裝在右邊
下一步是修正前面提到擅自更改 chcp 的問題

echo winscp.com /script=scripts.txt| powershell -nop "$input|iex; [console]::OutputEncoding=[Text.Encoding]::Default; Exit $LASTEXITCODE"


一樣封裝在 PowerShell 這樣可以眼不見為淨,就此就完成了





如何讓遠端 Linux 程序正確的顯示

兩個方法在 Unix 端轉換後傳輸或是接收到之後再轉換。

這邊範例是用 Windows PowerShell 去獲取 WSL 中的 Big5編碼 的注音文檔案。


方法1 在本地端收到後才轉編碼

先上函式
# 轉換編碼
function Convert-Encoding {
    param(
        [Parameter(Mandatory=$true)]
        [string]$FromEncoding,

        [Parameter(ValueFromPipeline=$true)]
        [string]$InputString
    )

    process {
        $bytes = [System.Text.Encoding]::GetEncoding($FromEncoding).GetBytes($InputString)
        $outputString = [System.Text.Encoding]::GetEncoding($FromEncoding).GetString($bytes)
        $outputString
    }
}

然後是用例

ssh chg@localhost "cat TestFile.txt" | Convert-Encoding -FromEncoding Big5


方法2 在發換端先轉換編碼才發送

ssh chg@localhost "cat TestFile.txt |iconv -f BIG5 -t UTF-8"



兩個方法都可以一定程度處理掉編碼的問題,但這種方式有幾個明顯的問題

  1. 無法轉換 stderr 或是直接打印的
  2. 依賴工具間的編碼適應性 [wsl::shell.sh] -> [Win::ssh.exe] -> [Win::program.ps1]

先說第一個如果這個程序直接丟 print 到視窗這種的會被跳過無法擷取,以及如果是丟到通道2錯誤流信息也是無法獲取。

當然這個無法獲取是目前的代碼無法獲取,對代碼進行擴展還是能處理上述的問題的,只是代碼會變得非常龐大,非常沒必要。


第二個問題就比較棘手了,因為 ssh 在中間層而且新版本強制固定下來就是 utf8 了,在這個轉換過程中是可能會丟東西的 (比如說把一個 big5 檔案用 utf8 開啟然後儲存)

一個例子就是打開一個 big5編碼的程序 裡面有直接打印的代碼。這種耍流氓的真的只能讓一個代理去接住先轉好再丟給ssh不然會出問題的。變成兩端都要有程序轉碼就是了。

這個問題要解決只能根本上的就是直接傳二進制,就不應該通過這個會擅自編碼的 ssh.exe 獲取信息,傳二進制就能把最終編碼權延後到接收端自己處理了。

對我想說的就是,這種極端環境通過終端機是無法解決了,只能自己寫代碼只有函式庫級別的才可以接收二進制。

不過這種情況其實很容易可以避免,就適當的調整一下咩,讓中間層級的 ssh.exe 這個只會utf8的流氓不要編錯碼就好。

如果是執行sh檔案記得注意一下那個檔案本身的編碼會影響到的。




2023年10月11日 星期三

在BAT中如何做 Ascii 文本的變換 更換換行符號 (Linux -> Win)

在BAT中如何做 Ascii 文本的變換 更換換行符號 (Linux -> Win)

反過來 dos2Unix 請參考這篇
CHG: 在BAT中如何做 Ascii 文本的變換 更換換行符號 (Win -> Linux) 



Bat能做的事情非常有限,這邊最有效率的辦法是直接呼叫老大哥 PowerShell 來直接擺平這事情。

廢話不多說直接上代碼一行而已

@echo off& Title EOLConverter By Charlotte
echo D:\UnixTextFile.txt | powershell -nop "[string]$fle=$input; if(-not(Test-Path $fle)){Write-Error 'Path is not exist' -ea 1}; $tmp=$fle+'.tmp'; $enc=[Text.Encoding]::Default; $red=New-Object IO.StreamReader($fle,$enc); $wrt=New-Object IO.StreamWriter($tmp,$false,$enc); while(-not $red.EndOfStream){$wrt.WriteLine($red.ReadLine())}; $red.Close();$wrt.Close(); mv $tmp $fle -fo -ea 1"
exit /b %errorlevel%

力求簡約一行直接幹掉,相當於引用一個外部二禁制檔案的概念,內容就不用太糾結了有興趣自己拆行出來看馬上能懂得

不過功能簡單只有針對系統語言編碼做轉換,非系統語言編碼或是涉及到兩種編碼轉換的,自行修改內容吧


內容做的是從Linux轉換到Windwos反過來的自行看著代碼推敲吧




2023年9月22日 星期五

如何在 docker 安裝 SQLServer 2022 的容器

如何在 docker 安裝 SQLServer 2022 的容器

現代在Windwos11上安裝相比於之前簡單了不少,現在一步一步跟著安裝吧。

裝在 docker 上有一個好處是不會掛在服務上要關掉直接關掉 docker 就好一切乾淨,軟體層面切割的比較徹底一些。

另外因為是 docker 是跑在 linux 上的,所以間接的 Mac M2 晶片的電腦也受益了是可以安裝的。



步驟1. WSL2

安裝 WSL2 指令參考這個

wsl --install

以前還要定系統設定現在通通不用了,直接就整合好一個指令裝到好
裝好之後需要重新啟動,重新動之後會看開裡面多出幾個東西

找到多出來的 ubuntu 打開它還會在安裝一次,裝好就能用了,過程會提示要輸入帳號密碼

一切都好了之後,用這個指令做最後的確認可以看安裝的是幾版的

wsl --list --verbose


有一點讓我有點意外的在 Windwos11 上這樣裝完顯示的版本居然是 WSL2 但卻沒有啟用 Hyper-V ,不知道是不是改版了 WSL2 沒有綁定 Hyper-V 還是怎樣。

雖然不知道為什麼,總之有這個疑慮的人照著這篇做完可以放心沒有被強制開啟 Hyper-V ,下面安裝 docker 也要注意要用 WSL 的環境,不然安裝檔會順便幫你啟用。



步驟2. 安裝docker

Docker: Accelerated Container Application Development
首頁就一個大大的下載,載了直接裝就是了

過程中會問你要不要用wsl的環境,全都預設給他按下去就好了
裝好打開看一兩眼沒問題就可以裝 SQLServer 了



步驟3. 安裝 SQLServer

指令只有兩個

下載容器

docker pull mcr.microsoft.com/mssql/server:2022-latest

載好之後再來要啟動它,這個啟動可以當作是實例要啟幾個都行每個獨立的
這邊密碼自己改一個包含<括號>整團是密碼,別留下括號會變成密碼的一部分
sql1就當作實例的區別吧如果要啟第二個實例這邊要改

docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=<Your@Passw0rd>" `
   -p 1433:1433 --name sql1 --hostname sql1 `
   -d mcr.microsoft.com/mssql/server:2022-latest

然後就完成了,再來隨意載個能連的軟體連接看看,預設管理員是SA

推薦載這個輕巧好看的軟體:Download and install Azure Data Studio




參考



SQLServer 在資料庫中反向查詢字串值在哪個表裡

SQLServer 在資料庫中反向查詢字串值在哪個表裡

算是反向查詢吧,不知道表在那裏只知道數值,又正好這個數值足夠特別不是到處都有的,可以反向特定出位於哪個表格裡。



直接上代碼


-- 宣告搜尋的字串和結果表格
DECLARE @TargetString nvarchar(255) = '<要檢索的字串>';
DECLARE @SearchResults TABLE (
    TableType nvarchar(10),
    FullTableName nvarchar(500),
    ColumnName nvarchar(370),
    ColumnValue nvarchar(3630)
);

-- 宣告用於循環處理的變數
DECLARE 
    @CurrentTable nvarchar(256),
    @CurrentColumn nvarchar(128),
    @QueryString nvarchar(110),
    @CurrentTableType nvarchar(10),
    @DatabaseName nvarchar(128)

-- 初始設定
SET @CurrentTable = ''
SET @QueryString = QUOTENAME('%' + @TargetString + '%','''')
SET @DatabaseName = QUOTENAME(DB_NAME())

-- 在資料庫中迭代所有的表格和視圖
WHILE @CurrentTable IS NOT NULL
BEGIN
    SET @CurrentColumn = ''

    -- 獲取下一個表格或視圖名稱
    SET @CurrentTable =
    (
        SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
        FROM INFORMATION_SCHEMA.TABLES
        WHERE (TABLE_TYPE = 'BASE TABLE' OR TABLE_TYPE = 'VIEW')
            AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @CurrentTable
            AND OBJECTPROPERTY(OBJECT_ID(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)), 'IsMSShipped') = 0
    )

    -- 確定當前的表格/視圖類型
    SELECT @CurrentTableType = TABLE_TYPE
    FROM INFORMATION_SCHEMA.TABLES
    WHERE QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) = @CurrentTable

    -- 打印當前搜尋的表格或視圖名稱
    PRINT 'Searching ' + @DatabaseName + '.' + @CurrentTable + ' (Type: ' + @CurrentTableType + ')';

    -- 迭代當前表格/視圖的所有列
    WHILE (@CurrentTable IS NOT NULL) AND (@CurrentColumn IS NOT NULL)
    BEGIN
        -- 獲取下一個列名稱
        SET @CurrentColumn =
        (
            SELECT MIN(QUOTENAME(COLUMN_NAME))
            FROM INFORMATION_SCHEMA.COLUMNS
            WHERE TABLE_SCHEMA = PARSENAME(@CurrentTable, 2)
                AND TABLE_NAME  = PARSENAME(@CurrentTable, 1)
                AND QUOTENAME(COLUMN_NAME) > @CurrentColumn
        )

        -- 如果該列存在,則搜尋目標字串
        IF @CurrentColumn IS NOT NULL
        BEGIN
            BEGIN TRY
                SET NOCOUNT ON;
                INSERT INTO @SearchResults
                EXEC
                (
                    'SELECT ''' + @CurrentTableType + ''', ' + 
                        '''' + @DatabaseName + '.' + @CurrentTable + ''', ' + 
                        '''' + @CurrentColumn + ''', ' + 
                        'LEFT(CONVERT(nvarchar(3630), ' + @CurrentColumn + '), 3630) ' + 
                    'FROM ' + @CurrentTable + ' (NOLOCK) ' + 
                    'WHERE ' + @CurrentColumn + ' IS NOT NULL' + 
                        ' AND CONVERT(nvarchar(3630), ' + @CurrentColumn + ') LIKE ' + @QueryString
                )
                SET NOCOUNT OFF;
            END TRY
            BEGIN CATCH
                PRINT '  Warning: Skipped searching ' + @DatabaseName + '.' + @CurrentTable + ' (Type: ' + @CurrentTableType + ') perhaps due to potential locking issues.';
                PRINT '    Message: ' + ERROR_MESSAGE();
                BREAK;
            END CATCH
        END
    END 
END

-- 返回搜尋結果
SELECT TableType, FullTableName, ColumnName, ColumnValue FROM @SearchResults



2023年9月18日 星期一

刪除右鍵 "在Visual Studio中打開" 的選單

刪除右鍵 “在Visual Studio中打開” 的選單

對於希望右鍵選單簡潔強迫症的人來說,多這些用不到的選單真的很煩



停用右鍵選單

直接上命令快速停用

reg add "HKEY_CLASSES_ROOT\Directory\Background\shell\AnyCode" /v "LegacyDisable" /t REG_SZ /f
reg add "HKEY_CLASSES_ROOT\Directory\shell\AnyCode" /v "LegacyDisable" /t REG_SZ /f

執行完畢再回到桌面點右鍵該選單就會消失了



復原變更

由於沒有直接刪除原本的值,要復原的話刪除 LegacyDisable 這個項目即可

reg delete "HKEY_CLASSES_ROOT\Directory\Background\shell\AnyCode" /v "LegacyDisable" /f
reg delete "HKEY_CLASSES_ROOT\Directory\shell\AnyCode" /v "LegacyDisable" /f

就此就能輕易復原了



2023年9月13日 星期三

[Win10/Win11] 移除右鍵菜單中 "使用skype共享" 選項

[Win10/Win11] 移除右鍵菜單中 “使用skype共享” 選項



右鍵的選項不知道己版開始偷偷加了這東西,看了很礙眼這邊提供幾個方法消除。


從命令列輸入這行可以快速消除

reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PackagedCom\Package\Microsoft.SkypeApp_15.103.3208.0_x64__kzf8qxf38zg5c\Class\{776DBC8D-7347-478C-8D71-791E12EF49D8}" /v "DllPath" /t REG_SZ /d "-Skype\SkypeContext.dll" /f


復原的話把 -Skype\SkypeContext.dll 中的負號移除即可,這邊僅添加負號盡可能保持原本的數據沒刪除了,可以很容易復原。




登陸檔位置在這裡

HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PackagedCom\Package\Microsoft.SkypeApp_15.103.3208.0_x64__kzf8qxf38zg5c\Class\{776DBC8D-7347-478C-8D71-791E12EF49D8}







2023年9月10日 星期日

PowerShell 爬蟲自動化安裝 Maven 最新版本

PowerShell 爬蟲自動化安裝 Maven 最新版本

為了方便安裝,寫一個自動爬 Maven 官方最新版的爬蟲,再搭配自動化執行後續安裝的批次檔,可以實現全自動安裝。

主要是寫一個基礎版本,往後有什麼要自動化的參考這個版本就能快速修改了。
https://gist.github.com/hunandy14/0f3377e468ac85a589818295e3c3c27e


快速使用

irm bit.ly/3RdEkBK|iex; Install-Maven "C:\app"