2014年8月30日土曜日

[Windows] ファイルを開いているプロセスを見つける

「*** は編集のためロックされています。」とか
「別のプログラムがこのフォルダーまたはファイルを開いているので、操作を完了できません。フォルダーまたはファイルを閉じてから再実行してください。」

とのエラーメッセージが表示されるものの、一体何がファイルを開いているのか分からない!そこでファイルを開いているプロセスを探す方法です。


### リモートから開いている共有フォルダのファイルを探す ###

ネットワーク端末から該当する PC のファイルにアクセスされている場合の対処について。

■ コマンドで作業する

ファイルの一覧を表示するには、このコマンドを実行します。
> net file
アクセスされてるファイルが一覧表示されます。他に「一覧にエントリが存在しません。」と表示されればファイルは開かれていません。

ファイルを閉じるには、このコマンドを実行します。
> net file ID(※注) /Close
※注:ID は開いているファイルの ID を記述する

■ 画面で作業する

コントロール パネル > システムとセキュリティ > 管理ツール > コンピューターの管理 と辿って
ツリーの「システムツール > 共有フォルダー > セッション」もしくは「開いているファイル」を開く。
閉じたい項目を右クリックして「セッションを閉じる」もしくは「開いているファイルを閉じる」を選択する。


### ローカルで開いているファイルを探す ###

ローカルのプロセスがファイルをロックしている場合の対処について。

■ タスクマネージャ から探す

Windows タスクマネージャ を開いて、「プロセス」タブからプロセスの「コマンド ライン」を確認する。
コマンドラインはデフォルトでは表示されていないので、表示列を追加する必要がある。
(手順)「表示」メニュー > 列の選択 > 「コマンド ライン」をチェック

ドキュメントであればコマンドの引数として起動されている場合が多いので、これで多くは確認することができる。

■ TASKLIST コマンドで探す

タスクマネージャで多くのプロセスを目で追うのが面倒であれば、コマンドでファイル名(の一部)を探せば早い。これはコマンドライン引数でなく、プロセスのウィンドウタイトルを検索することになるのだが、ドキュメントであればファイル名がウィンドウタイトルに使われる傾向が高いことを利用する。このためアプリケーションのデータファイルだと効果が無いが、そういう場合はアプリとファイルの繋がりは特定できるので、こうやって探す必要も無いのでは...?

> tasklist /V | findstr (ファイル名の一部)

プロセスを停止するには、
> taskkill /PID (プロセスID) /T

■ OPENFILES コマンドで探す

これはローカルで開いているファイルをリストアップできるが、スイッチを「有効」に切り替えてシステムの再起動が必要になる。これはフラグを有効にすると、パフォーマンスに負荷がかかるためにデフォルトでは無効になっているのだが、再起動するならロックの調査する必要はないですよね...
コマンドライン引数でないファイルのOpenについては、この方法で見つけることができます。

> openfiles /Local ON
(再起動が必要)
> openfiles /Query | findstr (フォルダ名やファイル名の一部)

■ System.Diagnostics.Process クラスで探す

Process.StartInfo プロパティ(ProcessStartInfo クラス)のうち Arguments プロパティでコマンド ライン引数を確認できるが、これは下記のように条件が厳しくてほとんど使えない。

http://msdn.microsoft.com/ja-jp/library/system.diagnostics.process.startinfo.aspx
プロセスの開始に Start メソッドを使用しなかった場合、StartInfo プロパティはプロセス開始に使用されたパラメーターを反映しません。

■ Windows PowerShell の Get-Process コマンドで探す

実はこの出力は上記の System.Diagnostics.Process クラスになるので、同じ理由で使えない...

(例)Acrobat Reader を検索
PS> Get-Process | Where-Object {$_.ProcessName -match 'AcroRd'}

Get-Process
http://technet.microsoft.com/ja-jp/library/hh849832.aspx

Get-Process コマンドレットの使用
http://technet.microsoft.com/ja-jp/library/ee176855.aspx

■ WMI で探す (コマンド)

WMI(Windows Management Instrumentation)を使って探す。ただし PowerShell のほうが柔軟に操作できるので、次に挙げるほうを選択したほうが良い。

> wmic PROCESS where "CommandLine like '%SampleName ※注%'" get /format:list | findstr /R "CommandLine ProcessId"

※注:フォルダ名やファイル名の一部を記述

Windows Management Instrumentation コマンド ライン
http://msdn.microsoft.com/ja-jp/library/cc784189.aspx

WMIC のヒント集
http://msdn.microsoft.com/ja-jp/library/cc758713.aspx

WMIC の動詞
http://msdn.microsoft.com/ja-jp/library/cc784966.aspx

WMIC で形式を作成および編集する
http://msdn.microsoft.com/ja-jp/library/cc757287.aspx

wmic
http://msdn.microsoft.com/ja-jp/library/aa394531.aspx

■ WMI で探す (Windows PowerShell)

wmic コマンドの PowerShell 版です。

PS> Get-WmiObject -Class Win32_Process | Where-Object {$_.CommandLine -match 'フォルダ名やファイル名の一部'} | Format-Table Caption,CommandLine,ProcessId

Get-WmiObject
http://technet.microsoft.com/ja-jp/library/hh849824.aspx

Win32_Process class
http://msdn.microsoft.com/ja-jp/library/aa394372.aspx

■ 外部のツールで探す

外部製品のプロセスモニタ ソフト等を使って、ファイルのOpenについての操作を探す。ただしファイルのOpenだけでも相当数出力されるので上手くフィルタリングしないと追えません。
これだと、あらゆる調査が可能です。

Process Monitor
http://technet.microsoft.com/ja-jp/sysinternals/bb896645.aspx

2014年8月29日金曜日

[Windows] GoogleUpdate のタスクを停止したい

GoogleUpdate が常時起動するが、これは結構念入りに仕込まれていてなかなか停止できない。
インターネットから隔離された PC などでは意味が無いので止めた方がいい。(ただし普通の PC では止めないほうが良いと思います。)

### GoogleUpdate の停止方法 ###

■ タスクの停止

コントロール パネル > システムとセキュリティ と辿って、「タスク スケジューラ」を起動する。(もしくは taskschd.msc コマンドを実行)
「タスク スケジューラ」画面から GoogleUpdate 関連のタスクを右クリックして「無効」に設定する。タスク名は恐らく以下のものと思われますが、他にも登録されていることがある。
  • GoogleUpdateTaskMachineCore
  • GoogleUpdateTaskMachineUA

■ サービスの停止

コントロール パネル > システムとセキュリティ > 管理ツール と辿って、「サービス」を起動する。(もしくは services.msc コマンドを実行)
「サービス」画面から GoogleUpdate 関連のサービスを右クリックしてプロパティを開き、「スタートアップの種類」を「手動」もしくは「無効」に変更する。

■ スタートアップの停止

コントロール パネル > システムとセキュリティ > 管理ツール と辿って、「システム構成」を起動する。(もしくは msconfig コマンドを実行)
「システム構成」画面の「スタートアップ」タブを開いて、GoogleUpdate 関連の項目のチェックを外す。



これで問題は解決するはずです。
え!?物理的に GoogleUpdate を削除してしまいたい!?というのであれば、もはや手動でも一切 Update できなくなっても消してしまいますか?全くもってお勧めいたしません。

### GoogleUpdate の削除方法 ###

■ プログラムの削除

C:\Program Files\Google\Update フォルダを削除
C:\Users\(ユーザ名)\AppData\Local\Google\Update フォルダを削除

■ タスクの削除

上記の「タスク スケジューラ」画面で GoogleUpdate 関連のタスクを右クリックして「削除」する。

■ サービスの削除

サービスを削除するコマンドを実行する。(サービスの名前は、念のため自分の環境で確認すべき)
sc delete gupdate
sc delete gupdatem

■ スタートアップの削除

「システム構成」画面の「スタートアップ」タブを開いて、GoogleUpdate 関連の項目のチェックを元に戻したうえで、レジストリ エディタを起動(regedit コマンドを実行)します。(スタートアップ をいったん有効にしないと、削除する文字列値が表示されません。)
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run にある「Google Update」文字列値を削除する。

■ レジストリの登録を削除

レジストリを GoogleUpdate で検索して削除する、結構ありますよ...

2014年8月14日木曜日

ペットボトル給水キャップの水量を調整

100円ショップで売っている、プランター用の水やりキャップの水量を調節する方法です。傾向として水が流れ出る勢いが早すぎることになると思います。

今回は、100円ショップのセリア(Seria)で購入した給水キャップで試してみる。


ペットボトルとの相性にもよると思うが、水量は相当多く500mlサイズで30分程度だった。キャップに開いている穴は2つでサイズは相当小さいが、水量が早い原因は穴のサイズではない

原因はキャップとペットボトルの接合部分から空気が吸い込まれてしまうためです。この製品はペットボトルとキャップの密接な接合具合で水量が影響してしまうので、汎用的なペットボトルを想定した商品としてはどうしても無理がある。100円ショップでは売っているけど、クレームの元になると思われてホームセンターではあまり取り扱っていないのも納得できる。

そこで水量調節のために、ちょっと改良します。

ペットボトルとの接合部分を密着するためにパッキンを入れます。薄いシート状の梱包材などを使ってキャップの内側にぴったり納まるサイズに丸くカットします。


パッキン中央の穴のサイズはよほど小さくない限り流量とは関係が無いので適当に開けてよい。今回は見た目重視でパンチ穴を開けました。梱包材がなければラップとかで代用できるが、繰り返し使用する耐久が無いです。

これをキャップに入れてペットボトルを付けると、今度は流量がほとんど無くなった。でもペットボトルを逆さにして水やりキャップの小穴に指先を添えてみると水面張力で水がゆっくり吸い出されてきます。これが水量を最も押さえた状態です。もっと水を流したいならば、パッキンに空気が入る切れ目を入れてやると早くなります。