2016年9月13日火曜日

【bat】batファイル名は内部で使ってるコマンド名にしてはいけない

■自分自身が呼び出されてしまう
echoなどのほとんどのコマンドは大丈夫だが、typeperfなどの一部のコマンドに関しては、
batファイル名をtypeperf.batなどにしてしまうと、自分が呼び出され続け、無限ループとなる。

■echoコマンドは呼び出し元のファイル名をecho.batにしても大丈夫。

例えば、tp.batというファイル名からtypepefコマンドを実行すると問題無し。

■しかし、typeperf.batというファイル名からtypeperfコマンドを呼ぶと
失敗する。以下のように延々と自分が呼び続けられる。

2016年9月12日月曜日

【TortoiseSVN】【VisualStudio】bin/obj/suoはコミット対象外

Microsoft Visual Studioで作成したプロジェクトには、ソースファイルやソリューションファイル、プロジェクトファイルのようなテキストファイル以外にも、exeファイルやユーザ毎の情報を格納するsuoのようなバイナリファイルも含まれる。

これらのバイナリファイルはSVNなどのリポジトリに登録する必要はない。よって、bin、objフォルダ、.suoファイルをコミットの対象外にする。対象外としておかないと、TortoiseSVNでコンフリクトが発生して、邪魔となる。

また、.userファイルはユーザー毎に変更可能なので適宜コミットしないようにすると便利。

【PowerShell】スクリーンショット(画面キャプチャ)

■Win10標準ショートカットキー
Win10では画面キャプチャ&ファイル保存してくれる以下のショートカットキーがあるので、もはやこのページの内容は不要となってしまった。(❖:Windowsロゴキー)

  • アクティブ画面キャプチャ+ファイル保存:❖+Alt+PrtSc
  • 全画面キャプチャ+ファイル保存    :❖+PrtSc
  • 指定範囲キャプチャ(ファイル保存しない) :❖+Shift+S
  • クリップボード履歴          :❖+V

※これらのショートカットキーはWin10のバージョンによって使えないものがあるようです。

話を戻して・・・
■PowerShellソース
$path = "c:\tmp\"                     # 出力先
$file = "Cap_{0:000}.png"             # {0:000} 0番目の引数を3桁の0埋め数字とする。

Add-Type -A System.Windows.Forms      # このセッションに型を追加。

[Windows.Forms.Screen]::PrimaryScreen.Bounds |                   # ディスプレイサイズを取得し、
    % {[Drawing.Bitmap]::New($_.Width, $_.Height)} |             # そのサイズのBitmapデータ生成。
    sv b                                                         # Set-Variable 変数への代入。bにBitmapオブジェクトを代入。

[Drawing.Graphics]::FromImage($b).CopyFromScreen(0, 0, $b.Size)  # 描画オブジェクトで画面キャプチャして、Bitmapデータへ反映。

md -f $path                           # フォルダ作成。-f:force 既に存在する場合エラーを抑止。

1..1000 |                             # 1~1000まで
    % { $path + $file -f $_ }  |      # 繰り返し、フォーマット。c:\tmp\Cap_001.pngなどに変換。
    ? { (Test-Path $_) -eq $false } | # その内、ファイルが存在しないパスのみを取得。
    select -F 1 |                     # 最初の1件のみにフィルタして、
    % { $b.Save($_) }                 # そのパスにBitmapデータをファイル保存。

Newスクリーンショット:上記に少し機能追加したもの。

■ショートカットキー
Win7以降ならタスクバーにピン留めしてWindowsキー+1とか2とか(タスクバーの左からのピン留め位置。ピン留めした位置が1番左なら、Windowsキー+1)。

■フリーソフトが使用できない職場なので、 WinShotも使用できない。仕方なく PowerShellでスクリーンキャプチャ&ファイル(画像ファイル)保存する。ちなみに全画面で保存される。

■Win7でも動くはず。
Download

上記のリンクからダウンロードした場合は、ファイルを右クリックしてプロパティを選択し、「ブロックの解除」が必要な場合がある。
上記のDownloadと下記のコードは同じもの。

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

$filePath = "c:\tmp\Cap_{0:000}.png"
$fileKind = [System.Drawing.Imaging.ImageFormat]::Png
#$fileKind = [System.Drawing.Imaging.ImageFormat]::Jpeg
#$fileKind = [System.Drawing.Imaging.ImageFormat]::Gif
#$fileKind = [System.Drawing.Imaging.ImageFormat]::Bmp

# スクリーンキャプチャして、Graphicsオブジェクトを生成
$rect = [System.windows.forms.Screen]::PrimaryScreen.Bounds
$bitmap = New-Object System.Drawing.Bitmap($rect.Width, $rect.Height)

$graphics = [System.Drawing.Graphics]::FromImage($bitmap)
$zero = New-Object System.Drawing.Point(0, 0)
$graphics.CopyFromScreen($zero, $zero, $bitmap.Size)

# ファイル名を決定するために、存在しないファイルになるまでループ
$i = 0
do
{
    $path = $filePath -F $i # 文字列フォーマット
    $i++
} while (Test-Path $path);

# ファイル保存
$bitmap.Save($path, $fileKind)


■powershell画面を非表示にする。
1. 該当のps1ファイルを右クリックし、ショートカットの作成。
2. 作成したショートカットを右クリックし、プロパティ。

3. リンク先に【powershell.exe -w Hidden -ep RemoteSigned -c "C:\Users\root\Desktop\cap\cap.ps1"】を入力し、【OK】ボタン押下。パスは読み替えること。-ep RemoteSignedを指定した場合、後述のpowershellの有効化は不要。
4. ショートカットファイルをタスクバーにD&D。

上記手順後、タスクバーのpowershellアイコンをクリックするとpowershell画面非表示の状態でキャプチャされる。

■powershell 有効化
1. Winキー押下し、【powershell】と入力し、表示されたWindows PowerShellを右クリックし、「管理者として実行」を選択。

2.  【Set-ExecutionPolicy RemoteSigned】を入力。(Set-Ex入力後Tabで補完、Re入力後、Tabで補完)

■ショートカットキーの登録。(制限事項有り※)
  1. 上記のコードを保存または、リンクからDownload。
     例)c:\bat\スクリーンキャプチャ.ps1
  2. 保存したファイルを右クリック-「ショートカットの作成」を選択。
  3. 作成したショートカットファイルを選択し、Alt + Enterキー。
  4. 「リンク先」欄の先頭にpowershell を追加。
     例1)powershell C:\bat\スクリーンキャプチャ.ps1
     例2)C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe C:\bat\スクリーンキャプチャ.ps1
  5. 「ショートカットキー」欄を選択。
  6. 使用したいショートカットキーを押下。
     例)Ctrl + Alt + P。
  7. 「実行時の大きさ」欄を「最小化」に変更。
  8. Winロゴキー + Rキー押下。
  9. shell:startupを入力し、Enterキーを押下。
  10. エクスプローラが開くので、上記のショートカットファイルを移動。
  11. OS再起動。
※このショートカットキーの登録の場合、アクティブウィンドウが変更されてしまうため、ツールチップなどの一部の表示がキャプチャできないことがある。

2016年9月10日土曜日

【Android】SDカードが認識されなくなる問題

■AndroidでSDカードが認識されなくなる
 Androidのいくつかの機種は、外部SDカード(microSD)が使用できるが、それまでは問題なく使えていたSDカードが、急に取り外された旨の通知が表示され、その後、再挿入・再起動しても認識されなくなることがある。頻繁にあり、年に2、3度遭遇してしまう。

■SDカード自体は壊れてない
 そのSDカードをWindowsで読み込ませても問題なく使用できるのに、その後、Androidに挿し直しても認識されないまま。

 多くのサイトに対策が記載されているが、自分の場合は、ファイル名に特殊文字を含んでいるせいだったと思う。怪しそうなファイル名は全て修正した。特定のアプリがそのファイルを読み込もうとすると発生するのかな?

 そのついでにパスも短くした。全て255文字以内。特殊文字の削除とパスの修正を一緒に実施したため、どちらが原因かはっきりしないが、Androidでは255文字以上のパスも認識するはずなので、特殊文字のほうと思われる。

 怪しいサイトで落としたファイルをたくさん入れてるので、特にzipは気を付けないと。

■大容量のファイルもダメ
 FolderSync Lite(クラウドはもちろん、FTP、SFTP、Windows共有、・・・とAndroid間のファイル・フォルダ同期を行う素晴らしいソフト)というAndroidアプリで 1.46 GBのファイルを転送したことでもSDカードが認識されない問題が発生した。FolderSync Liteの履歴にファイルサイズエラーが出力されていた。FAT32でフォーマットしているため、4GB or 2GBまではいけるはずなのだが、ダメみたいだ。該当のファイルを削除したら、SDカードが認識された。

■フォーマットをexFATに変更
 フォーマットについて完全に勘違いしていたが、AndroidではexFATは使用できないと思っていたが、使用可能だった。使用していたのは、128GBのmicroSDカードだったのでexFATが正しい。
 もしかしたら、上に記載した認識されなくなる問題は全てフォーマットのせいかな?フォーマットし直して、しばらく様子を見ることにする。

2016年9月9日金曜日

シリアル通信アプリ開発でcom0comを使用

シリアル通信のアプリ開発で通信先が存在しない場合や異常系試験ではcom0comとteratermマクロで行う。

2016年9月3日土曜日

【PowerShell】フォルダ内の最新画像を表示

ネット接続できない職場なので、基本的にスクリプトを自作する必要がある。
エクスプローラで画像表示することも可能だが、カスタマイズできるように
スクリプト化。

Download

#==================================================================
# ツールの概要
#==================================================================
# 一定間隔で指定フォルダの最新の画像ファイルを表示する。
# ウィンドウをクリックした場合も最新の画像ファイルを表示する。
# ウィンドウをダブルクリックするとウィンドウが画像にフィットする。

#==================================================================
# 事前準備
#==================================================================
# 管理者権限でpowershellを開き、実行ポリシーを変更しておく。
# Window 8の場合
# 1. キーボードでWindowsキー押下。
# 2. キーボードでpowershellと入力。
# 3. Shift-Ctrlを押しながら、powershellアイコンをクリック。
# 4. キーボードでSet-ExecutionPolicy RemoteSignedと入力。

#==================================================================
# 使用方法
#==================================================================
# このテキストをコピーしてファイルに保存。拡張子はps1とする。
# 下記の「設定値」欄を変更し、powershellからps1ファイルを実行。
# Windows8の場合はファイルを右クリックして「PowerShellで実行」を選択。

#==================================================================
# ライセンス
#==================================================================
# Copyright (c) 2015 Barracuda sh
# This software is released under the MIT License.
# http://opensource.org/licenses/mit-license.php

#==================================================================
# 設定値
#==================================================================
$pictDirPath = "C:\tmp"
$fileExt = @("*.gif", "*.jpg", "*.jpeg", "*.png", "*.bmp")
$interval = 2000
$width = 480
$height = 320
#$DebugPreference = "Continue"

#==================================================================
# メイン処理
#==================================================================
# コンソールを非表示
PowerShell -WindowStyle Hidden -Command Exit

# アセンブリ読み込み
Add-Type -Assembly System.Windows.Forms
Add-Type -Assembly System.Drawing

# Formサイズ(=画像サイズ)
$size = New-Object System.Drawing.Point
$size.X = $width
$size.Y = $height

# Form生成
[System.Windows.Forms.Form]$mainForm = New-Object System.Windows.Forms.Form
$mainForm.ClientSize = $size

# PictureBoxを生成しFormへ追加
[System.Windows.Forms.PictureBox]$pictBox = New-Object System.Windows.Forms.PictureBox
$pictBox.Sizemode = [System.Windows.Forms.PictureBoxSizeMode]::Zoom
$pictBox.AutoSize = $false
$pictBox.Size = $size
$pictBox.anchor = `
    [System.Windows.Forms.AnchorStyles]::Top -bor `
    [System.Windows.Forms.AnchorStyles]::Bottom -bor `
    [System.Windows.Forms.AnchorStyles]::Left -bor `
    [System.Windows.Forms.AnchorStyles]::Right 
$mainForm.Controls.Add($pictBox)

#タイマーイベントコールバック関数
$tick = {
    Write-Debug "[イベント]タイマー"
    # 画像表示を行う
    updatePict $script:mainForm $script:pictBox $script:pictDirPath $script:fileExt $false
}

# ピクチャーボックスクリックイベントコールバック関数
$click = {
    Write-Debug "[イベント]クリック"
    # 強制画像表示を行う
    updatePict $script:mainForm $script:pictBox $script:pictDirPath $script:fileExt $true
}

# ピクチャーボックスクリックイベントコールバック関数 
$doubleClick = {
    Write-Debug "[イベント]ダブルクリック"
    $widthRatio  = $pictBox.Size.Width  / $pictBox.Image.Size.Width
    $heightRatio = $pictBox.Size.Height / $pictBox.Image.Size.Height

    Write-Debug ("width  ratio = " + $widthRatio)
    Write-Debug ("height ratio = " + $heightRatio)

    if ($widthRatio -le $heightRatio)
    {
        [int]$newWidth  = $script:mainForm.ClientSize.Width
        [int]$newHeight = $script:pictBox.Image.Height * $widthRatio + 1
    }
    else
    {
        [int]$newWidth  = $script:pictBox.Image.Width * $heightRatio + 1
        [int]$newHeight = $script:mainForm.ClientSize.Height
    }
    $script:mainForm.ClientSize = New-Object System.Drawing.Size($newWidth, $newHeight)
}

# 画像更新関数
function updatePict ([System.Windows.Forms.Form]$form, [System.Windows.Forms.PictureBox]$pictBoxObj, [string]$path, [array]$ext, [bool]$force) {
    Write-Debug ("path = " + $path)
    Write-Debug ("ext = " + $ext)
    Write-Debug ("force = " + $force)

    # ファイル一覧を取得
    $path = $path + "\*.*"
    $sortFileAry = (Get-ChildItem $path -include $ext | sort CreationTime -Desc)

    # ファイル数が0なら終了
    if ($sortFileAry.Length -eq 0)
    {
        $pictBoxObj.ImageLocation = ""
        $form.Text = ""
        return
    }

    # 最新のファイルのパスを取得
    $latest = $sortFileAry[0].FullName

    # CPU・HDD負荷低減のため、前回と同じファイルパスの場合は画像表示をスキップ。
    if (!$force) {
        if ($pictBoxObj.ImageLocation -eq $latest)
        {
            Write-Debug "更新無"
            return
        }
    }

    # 前回と違うファイルパスの場合は、画像ファイルを表示する。 
    $pictBoxObj.ImageLocation = $latest
    $form.Text = $latest
    Write-Debug $latest
}

# PictureBoxのクリックイベント登録
$pictBox.Add_Click($click)
$pictBox.Add_DoubleClick($doubleClick)

# タイマー生成
$timer = New-Object Windows.Forms.Timer
$timer.Interval = $interval
$timer.Add_Tick($tick)
$timer.Enabled = $true

# 初回画像表示
updatePict $script:mainForm $pictBox $pictDirPath $script:fileExt $true

# メインフォームを表示
$mainForm.ShowDialog()

# タイマーを終了。
$timer.Enabled = $false

2016年9月1日木曜日

【Windows10】【vbs】ログオン時、ログオフ時に確認スクリプト【bat】

■簡易手順
①Win+R
②gpedit.msc
③[ユーザーの構成]-[Windowsの設定]-[スクリプト(ログオン/ログオフ)]-[ログオフ]
④(Win10)[ユーザの構成-管理用テンプレート]-[システム]-[スクリプト]-[実行中のログオフ スクリプトの命令を表示する]

Win10での実施手順についてコメントをいただき、出来る事を確認しました。
何故かWindows7ではできるが、Windows10はできない。
■画像付き手順
  1. c:\vbs\ログオフ時スクリプト.vbsを作成し、以下の内容で保存。
    (パスやファイルの内容は適宜読み替えること。)

     MsgBox "本当に退社して大丈夫ですか?"  
  2. 「Winロゴ」キー+「R」キーを押下。
  3. 「gpedit.msc」を入力。
  4. [ユーザーの構成]-[Windowsの設定]-[スクリプト(ログオン/ログオフ)]と辿り、
    ログオフをダブルクリック。
  5. [追加]ボタン押下。
  6. 最初に作ったvbsを指定して、「開く」ボタン押下。
  7. [OK]ボタン押下。
  8. [OK]ボタン押下。
  9. (Win10のみ)[ユーザの構成]-[管理用テンプレート]-[システム]-[スクリプト]-[実行中のログオフ スクリプトの命令を表示する]の順に辿る。
  10. (Win10のみ)[未構成]を[有効]に変更し、[OK]ボタンを押下。
  11. ログオフやシャットダウンすると以下のようにメッセージボックスが表示され、
    OKが押下されるまで待つ。OKが押されると、ログオフ/シャットダウンされる。
Win7のログオフスクリプト
Win7のログオフスクリプト
Win10のログオフスクリプト
Win10のログオフスクリプト

Win7のログオフは上記のようにメッセージボックスが表示されるが、
Win7のシャットダウンスクリプトではメッセージボックスが表示されず、
以下の画面が延々と続く。裏でメッセージボックスが表示され、
OKが押されるのを待っていると思われる。

何故かWin10の場合、ログオフでも上記ようにメッセージボックスが表示されない。
なんでだ?