﻿# 如何透過 LINQPad 撰寫自動化作業並搭配 CI 自動執行

我現在大多數自動化的小工具都是使用 [LINQPad](https://www.linqpad.net/) 來撰寫，執行速度快且管理方便，但是在 CI/CD 環境中，LINQPad 並不是一個常見的工具，還好 LINQPad 有提供 [LPRun](https://www.linqpad.net/lprun.aspx) 工具，可以直接把現成的 `*.linq` 檔案直接拿來當成腳本執行，因此拿來 CI 的環境用是非常方便的，完全可以當作 C# 腳本來使用。這篇文章我就來介紹一下 `LPRun` 使用的方式。

![LINQPad and CI\_CD integration](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/2b760837b5a47ec1f55f-9f8dfbc6-a1fc-41bf-a454-0833ce324fc6.webp)

### 步驟 1: 下載 LINQPad

由於 LINQPad 本身是一個免費軟體，任何人都可以下載使用，也有提供完整的 IDE 開發環境，但免費版並沒有 IntelliSense 與 AI 功能。所以拿 LINQPad 來執行一些現有的程式還算便利，但拿來寫 Code 就沒有那麼好用了，如果你像我一樣有大量的 Coding 需求，建議購買付費版本。

以下是下載的命令：

```batch
curl -sL https://www.linqpad.net/GetFile.aspx?LINQPad8.zip -o LINQPad8.zip
```

### 步驟 2: 解壓縮 LINQPad8.zip

解壓縮 LINQPad8.zip 到指定的目錄，這裡我們假設用 [7-Zip](https://www.7-zip.org/) 解壓縮到 `C:\LINQPad8` 目錄下。

```batch
7z x LINQPad8.zip -oC:\LINQPad8
```

![C:\\LINQPad8](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/143a18b37ef7aa2dbd73-5bbcca12-a8f5-4690-8662-5ccbb6919b3d.jpg)

可參考我之前文章: [分享幾個常用的 7-Zip 壓縮與解壓縮命令](/post/2021/07/07/Useful-7-Zip-7z-CLI-Command-Options)

### 步驟 3: 設定 PATH 環境變數

`LINQPad8.zip` 解壓縮後會有 `LPRun8-x64.exe`、`LPRun8-x86.exe`、`LPRun8-arm64.exe` 三個執行檔，這三個檔案都是 LINQPad 的 `LPRun` 執行檔，主要用來載入 `*.linq` 查詢並執行查詢中的程式。但為了要能夠在任何地方執行 LINQPad 的查詢，我們需要把解壓縮的路徑加入到加入到 PATH 環境變數中。

如果只是一次性的設定 `PATH` 環境變數，那倒是還蠻簡單的，直接修改當下命令列環境的 Session (工作階段) 環境變數就可以了，這部分相對簡單，命令如下：

-   Command Prompt
    
    ```batch
    SET PATH=C:\LINQPad8;%PATH%
    ```
    
-   PowerShell
    
    ```powershell
    $env:PATH = "C:\LINQPad8;$env:PATH"
    ```
    

但如果要永久性的設定 `PATH` 環境變數，那就需要透過一些技巧來處理。

-   Command Prompt
    
    ```batch
    curl -sL https://github.com/doggy8088/SetEnv/releases/download/1.0/SetEnv.exe -o SetEnv.exe
    SetEnv.exe -ua PATH %"C:\LINQPad8"
    ```
    
-   PowerShell
    
    ```powershell
    Invoke-WebRequest -Uri "https://github.com/doggy8088/SetEnv/releases/download/1.0/SetEnv.exe" -OutFile "SetEnv.exe"
    SetEnv.exe -ua PATH %"C:\LINQPad8"
    ```
    
-   另一個不用下載的 PowerShell 解決方案
    
    ```powershell
    # 這個 $InstallFolder 變數用來指定你要加入 PATH 環境變數的路徑
    $InstallFolder = 'C:\LINQPad8'
    
    # $env:Path, [Environment]::GetEnvironmentVariable('PATH'), and setx all expand
    # variables (e.g. %JAVA_HOME%) in the value. Writing the expanded paths back
    # into the environment would be destructive so instead, read the path directly
    # from the registry with the DoNotExpandEnvironmentNames option and write that
    # value back using the non-destructive [Environment]::SetEnvironmentVariable
    # which also broadcasts environment variable changes to Windows.
    try {
        $registryKey = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment', $false)
        $originalPath = $registryKey.GetValue(`
            'PATH', `
            '', `
            [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames `
        )
        $pathParts = $originalPath -split ';'
    
        if (!($pathParts -contains $InstallFolder)) {
            Write-Host "Adding $InstallFolder to PATH"
    
            # SetEnvironmentVariable broadcasts the "Environment" change to
            # Windows and is NOT destructive (e.g. expanding variables)
            [Environment]::SetEnvironmentVariable(
                'PATH', `
                "$originalPath;$InstallFolder", `
                [EnvironmentVariableTarget]::User`
            )
    
            # Also add the path to the current session
            $env:PATH += ";$InstallFolder"
        } else {
            Write-Host "An entry for $InstallFolder is already in PATH"
        }
    } finally {
        if ($registryKey) {
            $registryKey.Close()
        }
    }
    ```
    
    > 上述命令節錄自 [install-azd.ps1](https://aka.ms/install-azd.ps1) 腳本。
    

### 步驟 4: 執行 LINQPad 查詢

執行時請記得選擇對應的 `LPRun8-*.exe` 執行檔，不同的 CPU 架構需要執行不同的程式。大部分的情況下，選擇 `LPRun8-x64.exe` 應該是不會錯，但是如果你的 LINQPad 查詢有參考到 `x86` 的 DLL 的話，那就需要使用 `LPRun8-x86.exe` 來執行。

執行查詢最簡單的用法如下：

```batch
LPRun8-x64.exe MyQuery.linq
```

> LINQPad 官方是建議將執行檔更名為 `LPRun8.exe` 來跑，這樣你的自動化腳本才能比較通用，不用考慮 CPU 架構的問題。

注意: `LPRun` 其實有非常多很棒的用法，有自動化需求的人建議閱讀 [LINQPad Command-Line and Scripting](https://www.linqpad.net/lprun.aspx) 官方文件。

### 撰寫 Azure Pipeline YAML

如果你是使用 Azure Pipelines 的話，可以透過以下的 YAML 腳本來初始化並執行 LINQPad 查詢：

```yaml
trigger:
  - main

pool:
  vmImage: 'windows-latest'

steps:
- script: 'curl -sL https://www.linqpad.net/GetFile.aspx?LINQPad8.zip -o $(Agent.ToolsDirectory)\LINQPad8.zip'
  displayName: '下載 LINQPad8.zip'

- task: ExtractFiles@1
  displayName: '解壓縮 LINQPad8.zip'
  inputs:
    archiveFilePatterns: '$(Agent.ToolsDirectory)\LINQPad8.zip'
    destinationFolder: '$(Agent.ToolsDirectory)\LINQPad8'
    cleanDestinationFolder: false
    overwriteExistingFiles: true

- script: 'echo ##vso[task.prependpath]$(Agent.ToolsDirectory)\LINQPad8'
  displayName: '加入 LINQPad 8 到 PATH 環境變數'

- script: 'LPRun8-x64.exe MyQuery.linq'
  displayName: '執行 MyQuery.linq'
```

### 撰寫 GitHub Actions YAML

如果你是使用 GitHub Actions 的話，可以透過以下的 YAML 腳本來初始化並執行 LINQPad 查詢：

```yaml
name: LINQPad Workflow

on:
  push:
    branches: [ main ]

jobs:
  run-linqpad:
    runs-on: windows-latest

    steps:
    - uses: actions/checkout@v2

    - name: 下載 LINQPad8.zip
      run: curl -sL https://www.linqpad.net/GetFile.aspx?LINQPad8.zip -o %RUNNER_TOOL_CACHE%\LINQPad8.zip
      shell: cmd

    - name: 解壓縮 LINQPad8.zip
      run: |
        powershell -Command "Expand-Archive -Path %RUNNER_TOOL_CACHE%\LINQPad8.zip -DestinationPath %RUNNER_TOOL_CACHE%\LINQPad8 -Force"
      shell: cmd

    - name: 加入 LINQPad 8 到 PATH 環境變數
      run: echo %RUNNER_TOOL_CACHE%\LINQPad8>> %GITHUB_PATH%
      shell: cmd

    - name: 執行 MyQuery.linq
      run: LPRun8-x64.exe MyQuery.linq
      shell: cmd
```

### 課程推薦

我之前有舉辦過一場[精通 LINQPad 8 開發工具](https://www.accupass.com/event/2312050812101612044991)課程，現在你也可以購買本次課程的錄影來學習，這是一個非常實用的課程，可以讓你快速上手 LINQPad 8 開發工具。報名課程時還可以選擇搭配 **LINQPad 8 Premium 終身授權** 的方案，連同課程一起購買更優惠唷！👍

除此之外，報名此課程還可以加入一個專屬本班學員專屬的 LINPQad 交流社群 (LINE 社群)，裡面有三百多人，大家可以互相交流 LINQPad 的使用心得，也可以提問問題，目前也有累積不少記事本分享，也是一個非常棒的學習資源。

如果你也有興趣購買此課程的話，歡迎[來信洽詢](mailto:training@miniasp.com)！📧

### 相關連結

-   [LINQPad Command-Line and Scripting](https://www.linqpad.net/lprun.aspx)
-   [LINQPad and Portable Deployments](https://www.linqpad.net/PortableDeployment.aspx)
