2026年2月6日金曜日

GCP のクラウドストレージに上書きアップロードしてもオブジェクトが変更されない場合の対応方法

GCP のクラウドストレージに上書きアップロードしてもオブジェクトが変更されない場合の対応方法

概要

おそらくキャッシュされているのが問題です
特に発生しやすいのが「同じような画像を上書きアップロードした場合」で例えば元の画像を90度回転させた画像などは上書きアップロードしても反映されないことが多いです

そんな場合の反映方法を紹介します

環境

  • GCP 2026/02/04 時点

ブラウザのキャッシュを削除する

とりあえず削除して再度アクセスしてみましょう

クエリ付きでアクセスする

クラウドストレージ側でキャッシュしている可能性があるのでクエリ付きでアクセスしましょう

https://storage.googleapis.com/your_bucket_name/file.jpg?nocache=1

Cache-Control を確認し短くする

curl -I https://storage.googleapis.com/your_bucket_name/file.jpg

これで「Cache-Control:」「Age:」「X-Cache:」があればクラウドストレージ側のキャッシュが有効になっています

  • gsutil setmeta -h "Cache-Control:public,max-age=60" gs://your_bucket_name/file.jpg

60秒など短い時間にしましょう
0 だと毎回クラウドストレージにアクセスしネットワーク量が多くなり金額上がるので注意しましょう

別のファイル名にする

これが一番カンタンです
がアプリ側の改修などが必要になるケースがあるので注意しましょう

よくあるパターンはファイル名にハッシュなどを含めるケースです

ダメだったケース

  • 削除 -> 再度アップロード
    • なぜか元の画像がクラウドストレージ側でも利用されてしまう
  • 実はファイルが回転できていない
    • exif の Orientation にまだデータが残っている
    • ビューアの見た目だけが回転している

最後に

まずはキャッシュを疑いましょう

2026年2月5日木曜日

VSCode の git で認証ダイアログが定期的に出てくる場合の対処方法

VSCode の git で認証ダイアログが定期的に出てくる場合の対処方法

概要

タイトルの通りなぜか定期的に出てくるので抑制します

環境

  • Windows 11
  • VScode 1.108.2

方法

  • git config --global credential.helper cache

最後に

ただしこれでも push や pull 時には認証情報が聞かれるので注意してください
また Windows を再起動しても再度入力する必要があります

wincred とか使ってもなぜか毎回聞かれてしまいます

https の認証だとそうなるのかも

2026年2月4日水曜日

Windows 起動時に特定のページで Chrome を起動する方法

Windows 起動時に特定のページで Chrome を起動する方法

概要

ホームページにはしたくないが Windows 起動時に特定ページを開く方法を紹介します

環境

  • Windows11
  • Chrome 144.0.7559.110

shell:startup を開く

エクスプローラで「shell:startup」と入力し起動時に自動で開くフォルダを開きます

ショートカットの作成

  • 右クリック
  • 新規作成
  • ショートカット

ショートカットの設定

  • 項目の場所を入力してくださいに以下を入力
    • "C:\Program Files\Google\Chrome\Application\chrome.exe" "http://xxx.xxx.xxx.xxx"
  • 次へ
  • 適当なショートカットの名前を設定

最後に

ホームページを設定し Chrome のショートカットをスタートアップに追加してもいいですがホームページに設定すると毎回そのページからになるのでそれが嫌な場合は便利です

2026年2月3日火曜日

VSCode + Continue でエージェント開発をする

VSCode + Continue でエージェント開発をする

概要

前回 VSCode + copilot + ollama でローカル開発する方法を紹介しました
Ask モードしか使えないのが残念でした
今回は VSCode + continue + ollama で Agent 開発してみます

環境

  • M2 mac mini macOS 26.2
    • ollama 0.14.3
    • codegemma 7b
    • llama3.1 8b
  • VSCode 1.108.2

Continue のインストール

VSCode の拡張一覧から「continue」で検索しインストールすれば OK です

https://github.com/continuedev/continue

Continue の設定

  • 左メニューから Continue のアイコンを選択
  • 右上の歯車マークを選択
  • Configs
  • Local Config の歯車マークを選択
  • YAML を以下のように編集 (IP部分は適宜変更)
name: Local Config
version: 1.0.0
schema: v1
models:
  - name: codegemma
    provider: ollama
    model: codegemma:latest
    apiBase: http://192.168.1.65:11434
    roles:
      - chat
      - edit
      - apply
      - autocomplete

動作確認

あとは Continue のチャット画面に移動しチャットすれば OK です
「Agent」になっておりかつ先程設定したモデルが選択されていることを確認してからチャットしましょう

M2 mac mini 上では特にストレスなくレスポンスが返ってきました

トラブルシューティング: Agent モードが使えない

「Agent might not work well with this model」という警告が出ている場合は Agent モードが使えません

codegemma は tools に対応しているモデルではないようです
https://ollama.com/library/codegemma に「Tools」というタグが付与されていないと Agent モードは使えません

なのでモデルを変更しましょう
ただ Tools が使えるモデルは比較的大きめなのでマシンスペックが必要になるので注意しましょう

公式のおすすめモデルは https://docs.continue.dev/ide-extensions/agent/model-setup です

  • ollama run llama3.2
name: Local Config
version: 1.0.0
schema: v1
models:
  - name: llama3.2
    provider: ollama
    model: llama3.2:latest
    apiBase: http://192.168.1.65:11434
    roles:
      - chat
      - edit
      - apply
      - autocomplete
    capabilities: 
     - tool_use
     - image_input

最後に

コンテキストの渡し方 (現在選択中のファイルや別のファイル) を送信する方法などは copilot chat プラグインとは少し違うので注意しましょう

また ollama を使う場合エージェントモードが使えるモデルと使えないモデルがあり使えるモデルはそれなりの大きさのモデルが必要になるようです

gemma3 などは使えませんでした
この辺り最適なモデルの選択などは続けていきたいです

エージェントモードで動かすと回答の処理や Continue の挙動がおかしくなるのでその場合は素直に Chat モードを使いましょう

参考サイト

2026年2月2日月曜日

VSCode で copilot の無料プランの上限が来たらローカル LLM を使おう

VSCode で copilot の無料プランの上限が来たらローカル LLM を使おう

概要

ollama を使います

環境

  • M2 mac mini macOS 26.2
    • ollama 0.14.3
    • codegemma 7b
  • VSCode 1.108.2

ollama の起動

インストールはこちら

LISTEN ポートを公開する場合はこちら

モデルのダウンロード

  • ollama pull codegemma

ollama run はしなくて OK です
API でモデルを指定して呼び出すだけなのでインタラクティブモードで放置しておかないで大丈夫です

VSCode の設定

ollama のエンドポイントを指定します
json は以下

{
  "github.copilot.chat.byok.ollamaEndpoint": "http://192.168.1.65:11434"
}

ここで一度 VSCode を再起動することをおすすめします

copilot 設定

  • 右ペインのチャットにある「Auto」から「Manage Models」を選択
  • 一覧に Ollama 上の codegemma モデルが表示されることを確認
  • 目のマークがあるのでクリックして有効にする

使用するモデルの選択

「Auto」ではなく追加したモデルを選択しましょう

Agent モードは使えない

copilot chat のプラグインにある「Agent」は使えないので「Ask」に切り替えましょう

動作確認

あとはいつも通りソースコードなどを選択して質問しれば回答してくれます

マシンスペックにもよりますが M2 mac mini + codegemma:7b で質問したらすぐにレスポンスが返ってきました

最後に

copilot + ollama を試してみました
Agent モードが使えないのは辛いです
次回は copilot + Continue を試してみます

参考サイト

2026年1月29日木曜日

Windows11 のプロキシ設定のセットアップスクリプトを Powershell で設定する

Windows11 のプロキシ設定のセットアップスクリプトを Powershell で設定する

概要

タイトルの通りです

環境

  • Windows11

Powershell スクリプト

# Windows proxy setup script configuration tool
# Usage: .\change_proxy.ps1 -ScriptURL "http://xxx.xxx.xxx.xxx/proxy.pac"
#        .\change_proxy.ps1 -Reset

param(
    [string]$ScriptURL = "http://xxx.xxx.xxx.xxx/proxy.pac",
    [switch]$Reset = $false
)

# Check admin privileges
function Test-IsAdmin {
    $currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
    $principal = New-Object Security.Principal.WindowsPrincipal($currentUser)
    return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}

# Elevate to admin if needed
if (-not (Test-IsAdmin)) {
    Write-Host "Admin privileges required. Elevating..." -ForegroundColor Yellow
    $scriptPath = $MyInvocation.MyCommand.Path
    $arguments = "-NoProfile -ExecutionPolicy Bypass -File `"$scriptPath`""
    if ($ScriptURL -ne "http://xxx.xxx.xxx.xxx/proxy.pac") {
        $arguments += " -ScriptURL `"$ScriptURL`""
    }
    if ($Reset) {
        $arguments += " -Reset"
    }
    Start-Process PowerShell -ArgumentList $arguments -Verb RunAs -Wait
    exit 0
}

if ($Reset) {
    # Reset proxy settings
    Write-Host "Resetting proxy settings..."
    netsh winhttp reset proxy

    # Reset registry settings
    $regPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
    if (Test-Path $regPath) {
        Set-ItemProperty -Path $regPath -Name ProxyEnable -Value 0 -ErrorAction SilentlyContinue
        Set-ItemProperty -Path $regPath -Name AutoConfigURL -Value "" -ErrorAction SilentlyContinue
        Set-ItemProperty -Path $regPath -Name AutoDetect -Value 0 -ErrorAction SilentlyContinue
        Set-ItemProperty -Path $regPath -Name ProxyServer -Value "" -ErrorAction SilentlyContinue
        Write-Host "Proxy settings reset." -ForegroundColor Green
    }
} else {
    # Configure setup script
    Write-Host "Configuring setup script: $ScriptURL"

    $regPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
    if (-not (Test-Path $regPath)) {
        New-Item -Path $regPath -Force | Out-Null
    }

    # Disable direct proxy
    Set-ItemProperty -Path $regPath -Name ProxyEnable -Value 0 -ErrorAction SilentlyContinue
    # Set auto-config script
    Set-ItemProperty -Path $regPath -Name AutoConfigURL -Value $ScriptURL -ErrorAction SilentlyContinue
    # Disable auto-detect
    Set-ItemProperty -Path $regPath -Name AutoDetect -Value 0 -ErrorAction SilentlyContinue

    Write-Host "Setup script configured." -ForegroundColor Green
}

# Display current settings
Write-Host "`nCurrent proxy settings:" -ForegroundColor Cyan
$regPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
if (Test-Path $regPath) {
    $proxyEnable = (Get-ItemProperty -Path $regPath -Name ProxyEnable -ErrorAction SilentlyContinue).ProxyEnable
    $autoConfigURL = (Get-ItemProperty -Path $regPath -Name AutoConfigURL -ErrorAction SilentlyContinue).AutoConfigURL
    $autoDetect = (Get-ItemProperty -Path $regPath -Name AutoDetect -ErrorAction SilentlyContinue).AutoDetect
    $proxyServer = (Get-ItemProperty -Path $regPath -Name ProxyServer -ErrorAction SilentlyContinue).ProxyServer

    Write-Host "  ProxyEnable: $proxyEnable"
    Write-Host "  AutoConfigURL: $autoConfigURL"
    Write-Host "  AutoDetect: $autoDetect"
    Write-Host "  ProxyServer: $proxyServer"
}
Write-Host ""
netsh winhttp show proxy

最後に

当然ですが管理者権限が必要になります

2026年1月24日土曜日

RDP で毎回認証を求められるがそれを回避して認証情報なしで自動で接続する方法

RDP で毎回認証を求められるがそれを回避して認証情報なしで自動で接続する方法

概要

ダウンロードした RDP ファイルをコピーして書き換えて実行します 前回の続きです

環境

  • Windows11

monitory_rdp_file.ps1

param(
    [Parameter(Mandatory=$false)]
    [string]$RDPServer = "your.rdp.server.or.ip",
    
    [Parameter(Mandatory=$false)]
    [string]$RDPUsername = "domain\username",
    
    [Parameter(Mandatory=$false)]
    [string]$RDPPassword = "xxxx",
    
    [Parameter(Mandatory=$false)]
    [switch]$TestMode = $false
)

# Basic file logging to help diagnose scheduled task behavior
$logDir = Join-Path $env:LOCALAPPDATA "RDPFileMonitor"
if (-not (Test-Path $logDir)) {
    New-Item -Path $logDir -ItemType Directory -Force | Out-Null
}
$logPath = Join-Path $logDir "monitor.log"

# Emit a simple startup marker
("Started: " + (Get-Date -Format 'yyyy-MM-dd HH:mm:ss')) | Out-File -FilePath (Join-Path $logDir 'started.txt') -Append -Encoding utf8

try {
    Start-Transcript -Path $logPath -Append -ErrorAction SilentlyContinue | Out-Null
} catch {}

# Get user profile path - handle both system and user context execution
$userProfile = [Environment]::GetFolderPath("UserProfile")
if (-not (Test-Path $userProfile)) {
    $userProfile = "C:\Users\username"
}
$downloadFolder = Join-Path $userProfile "Downloads"
$targetRDPFileName = "rdgateway101_vdgate_nifcloud_net.rdp"
$processedFiles = @()

Write-Host "Starting RDP file monitoring (polling method)"
Write-Host "Executed by: $env:USERNAME from host: $env:COMPUTERNAME"
Write-Host "User Profile: $userProfile"
Write-Host "Log: $logPath"
Write-Host "Target folder: $downloadFolder"
Write-Host "Target file name: $targetRDPFileName"

if ($TestMode) {
    Write-Host "Test Mode: Running one iteration only"
} else {
    Write-Host "Checking every 2 seconds..."
}

$iterationCount = 0
$maxIterations = if ($TestMode) { 1 } else { [int]::MaxValue }

while ($iterationCount -lt $maxIterations) {
    $iterationCount++
    Write-Host "Iteration $iterationCount at $(Get-Date -Format 'HH:mm:ss')" -ForegroundColor Gray
    
    try {
        if (Test-Path $downloadFolder) {
            # Clean up processed files list - remove entries for files that no longer exist
            $processedFiles = @($processedFiles | Where-Object { Test-Path $_ })
            
            $files = Get-ChildItem -Path $downloadFolder -Filter "*.rdp" -File
            
            foreach ($file in $files) {
                if ($file.Name -eq $targetRDPFileName -and $file.FullName -notin $processedFiles) {
                    Write-Host "Target file detected: $($file.Name) at $(Get-Date -Format 'HH:mm:ss')"
                    Write-Host "Full path: $($file.FullName)"
                    
                    Start-Sleep -Seconds 2
                    
                    try {
                        Write-Host "Executing RDP file: $($file.FullName)"
                        
                        # If credentials provided, cache them and modify RDP file
                        if ($RDPUsername -and $RDPPassword) {
                            Write-Host "Caching credentials for: $RDPServer"
                            
                            # Cache credentials using cmdkey (more reliable than embedding in RDP)
                            $cmdkeyCmd = "cmdkey.exe /generic:$RDPServer /user:$RDPUsername /pass:$RDPPassword"
                            Invoke-Expression $cmdkeyCmd | Out-Null
                            Write-Host "Credentials cached successfully"
                            
                            # Read original RDP file
                            $rdpContent = Get-Content -Path $file.FullName -Encoding ASCII
                            
                            # Remove or disable credential prompting settings
                            $rdpContent = $rdpContent -replace 'prompt for credentials:i:1', 'prompt for credentials:i:0'
                            $rdpContent = $rdpContent -replace 'promptcredentialonce:i:1', 'promptcredentialonce:i:0'
                            $rdpContent = $rdpContent -replace 'enablecredsspsupport:i:1', 'enablecredsspsupport:i:0'
                            
                            # Ensure username is set in RDP file
                            if ($rdpContent -notmatch 'username:s:') {
                                $rdpContent += "`r`nusername:s:$RDPUsername"
                            } else {
                                $rdpContent = $rdpContent -replace 'username:s:.*', "username:s:$RDPUsername"
                            }
                            
                            # Create temporary RDP file
                            $tempRDPPath = [System.IO.Path]::GetTempFileName() -replace '\.tmp$', '.rdp'
                            Set-Content -Path $tempRDPPath -Value $rdpContent -Encoding ASCII
                            Write-Host "Temporary RDP file created: $tempRDPPath"
                            
                            Start-Sleep -Seconds 1
                            
                            # Execute temporary RDP file with cached credentials
                            Start-Process -FilePath $tempRDPPath
                            $processedFiles += $file.FullName
                            Write-Host "Executed successfully with cached credentials"
                            
                            # Clean up temporary file after a delay
                            Start-Sleep -Seconds 3
                            Remove-Item -Path $tempRDPPath -Force -ErrorAction SilentlyContinue
                            Write-Host "Temporary RDP file cleaned up"
                        }
                        else {
                            # Execute without credentials modification
                            Write-Host "No credentials provided, executing original RDP file"
                            Start-Process -FilePath $file.FullName
                            $processedFiles += $file.FullName
                            Write-Host "Executed successfully"
                        }
                        
                        Start-Sleep -Seconds 1
                        Remove-Item -Path $file.FullName -Force
                        Write-Host "File deleted: $($file.FullName)"
                    }
                    catch {
                        Write-Error "Error executing RDP file: $($_.Exception.Message)"
                    }
                }
            }
        }
        else {
            Write-Host "Download folder not found: $downloadFolder"
        }
    }
    catch {
        Write-Error "Error during monitoring: $($_.Exception.Message)"
    }
    
    # For test mode, exit after one iteration
    if ($TestMode) {
        Write-Host "Test mode iteration complete. Exiting."
        break
    }
    
    # Normal mode: sleep before next iteration
    Start-Sleep -Seconds 2
}

Write-Host "RDP file monitor stopped at $(Get-Date -Format 'HH:mm:ss')"
Stop-Transcript -ErrorAction SilentlyContinue

最後に

RDP ファイルは中身はテキストなのでいろいろハックできます