C#でエクスプローラーで表示されるファイルの並び順と同じにソートしてみる

| 2009年6月20日土曜日
必要があったのでメモ。

IComparerを使ってArray.Sort()でソートする。

使い方は、


string[] list = { "01.txt", "1.txt", "02.txt" }
Array.Sort(list, new ExplorerSortComparer());

こんな感じ
--- ExplorerSortComparer Class ---

public class ExplorerSortComparer : IComparer {
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
public static extern int StrCmpLogicalW(string str1, string str2);

public int Compare(object obj1, object obj2) {
return StrCmpLogicalW((string)obj1, (string)obj2));
}
}

VBScriptでゴミ箱のファイルを削除してみる

|
PowerShellではできたので、VBScriptで指定日以前にごみ箱に捨てたファイルを削除してみる。
PowerShellがもっと流行れば、VBScriptから逃げられるんだけど…その日はまだ遠そうだ。

※ごみ箱の中のフォルダを消そうとすると「実行時エラー:・・・」となるので一度Tempフォルダに移動してからcmdのrmdirで消している。

3日前に削除したファイルをけすなら、cmdなどから

> CScript /nologo DeleteGarbabeFiles.vbs /Date:3

とする。
/Date:3 をつけなければ、一週間前までのを削除する。

--- DeleteGarbabeFiles.vbs ---

If WScript.Arguments.Named("Date") = "" Then
nDays = 6
Else
nDays = Int(WScript.Arguments.Named("Date"))
End If

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objShell = CreateObject("Shell.Application")
Set WshShell = CreateObject("WScript.Shell")
Set trash = objShell.NameSpace(10)

For Each item in trash.Items()
If Int(Now() - CDate(trash.GetDetailsOf(item, 2))) >= nDays Then
If objFSO.FileExists(item.Path) Then
objFSO.DeleteFile item.Path
ElseIf objFSO.FolderExists(item.Path) Then
dustFolderPath = objFSO.GetSpecialFolder(2).Path & "_TempDeleteFolder"
objFSO.MoveFolder item.Path, dustFolderPath
delCommand = "cmd.exe /C rmdir /S /Q " & """" & dustFolderPath & """"
WshShell.Run delCommand, 0, true
End If
End If
Next

Set objFSO = Nothing
Set objShell = Nothing
Set WshShell = Nothing
Set trash = Nothing

PowerShellから新しいウィンドウのPowerShellを開く

| 2009年6月16日火曜日
PowerShellから新しいウィンドウのPowerShellを開くには、WScript.Shellを使う。

> $WShell = New-Object -comObject WScript.Shell
> $posh = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
> [void]$WShell.Run($posh , 1)

これを「New-PowerShellWindow.ps1」とかにしてパスの通ったところに置いておけば、キーボードだけでやりたい人には使えるかもしれない。

PowerShellで半角カタカナを全角カタカナに変換してみる

| 2009年4月27日月曜日
必要になったので…
使い方:
> ConvertTo-HankakukatakanaFromZenkakukatakana "デジタルハイビジョンテレビ"

--- ConvertTo-HankakukatakanaFromZenkakukatakana.ps1 ---

  1. function ConvertTo-HankakukatakanaFromZenkakukatakana([string]$value) {
  2. $zenkakukatakana = "アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン゛゜ァィゥェォャュョッ"
  3. $hanakakukatakana = "アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン゙゚ァィゥェォャュョッ"
  4. $dakutenZenkakukatakana = "ガギグゲゴザジズゼゾダヂヅデドバビブベボ"
  5. $dakutenHankakukatakana = "カキクケコサシスセソタチツテトハヒフヘホ"
  6. $handakutenZenkakukatakana = "パピプペポ"
  7. $handakutenHankakukatakana = "ハヒフヘホ"
  8. for ($i = 0; $i -lt $dakutenZenkakukatakana.Length;$i++) {
  9. $value = $value.Replace($dakutenHankakukatakana[$i] + "゙", $dakutenZenkakukatakana[$i])
  10. }
  11. for ($i = 0; $i -lt $handakutenZenkakukatakana.Length; $i++) {
  12. $value = $value.Replace($handakutenHankakukatakana[$i] + "゚", $handakutenZenkakukatakana[$i])
  13. }
  14. for ($i = 0; $i -lt $zenkakukatakana.Length; $i++) {
  15. $value = $value.Replace($hanakakukatakana[$i], $zenkakukatakana[$i])
  16. }
  17. return $value
  18. }

PowerShellでゴミ箱を操作するには

| 2009年3月18日水曜日
まずは、準備。
> $shell = New-Object -comObject Shell.Application
> $shell.NameSpace(10)

Title                      : ごみ箱
Application                : System.__ComObject
Parent                     :
ParentFolder               : System.__ComObject
Self                       : System.__ComObject
OfflineStatus              :
HaveToShowWebViewBarricade : False
ShowWebViewBarricade       : False

ゴミ箱の中のファイル数を取得する。
> $shell.NameSpace(10).Items().Count

3

ごみ箱の中のファイル名の一覧を取得する。
> $shell.NameSpace(10).Items() | % { $_.Name }

新規 Microsoft Office Word 文書.docx
新しいテキスト ドキュメント.txt
新規 Microsoft Office Excel ワークシート.xlsx

一つ目のファイルの情報を取得する。ここでは、$itemに入れている。
> $item = $shell.NameSpace(10).Items().Item(0)
> $item

Application  : System.__ComObject
Parent       : System.__ComObject
Name         : 新規 Microsoft Office Word 文書.docx
Path         : C:\$Recycle.Bin\S-1-5-21-2464054850-802308169-2795062852-1001\$R95HRWN.docx
GetLink      :
GetFolder    : System.__ComObject
IsLink       : False
IsFolder     : False
IsFileSystem : True
IsBrowsable  : False
ModifyDate   : 2009/03/18 21:07:06
Size         : 0
Type         : Microsoft Office Word 文書

上記だけでは、ファイル自身の情報が今一わからないのでGetDetailsOfを使ってもっと細かい情報を取得する。
GetDetailsOfで取得できる情報は、ごみ箱を開いた時に表示される列の順なので、0から順に9列目まで取得する。
> 0..8 | % { $shell.NameSpace(10).GetDetailsOf( $item, $_ ) }

新規 Microsoft Office Word 文書.docx
C:\Test
 2009/ 03/ 18   21:07
0 バイト
Microsoft Office Word 文書
 2009/ 03/ 18   21:07
 2009/ 03/ 18   21:07
 2009/ 03/ 18   21:07
A

ゴミ箱からファイルを削除する。
> Remove-Item $item.Path

指定したファイルを元に戻す、元の場所じゃなくてもいいけど。
> Move-Item $item.Path ( Join-Path $shell.NameSpace(10).GetDetailsOf( $item, 1 ) $item.Name )

PowerShellでPDFのサイズを取得する。

| 2009年3月4日水曜日
PDFの扱うために、iTextSharpからitextsharp-4.1.2-dll.zipを落としてくる。
itextsharp.dllが入っているので適当な場所に配置する。

PowerShellからitextsharp.dllのあるフォルダでDLLを読み込む。

> [System.Reflection.Assembly]::LoadFrom(( Join-Path $pwd itextsharp.dll))

GAC    Version        Location
---    -------        --------
False  v1.1.4322      C:\itextsharp-4.1.2-dll\itextsharp.dll

これで準備ができたので、PdfReaderを使ってサイズを取得したいPDFファイルを読み込む。

> $pdfReader = New-Object iTextSharp.text.pdf.PdfReader(( Join-Path $pwd foo.pdf))

1ページめのサイズを取得する。

> $pdfReader.GetPageSize(1)

Type               : 30
Chunks             : {}
Top                : 841.875
Border             : -1
GrayFill           : 0
Left               : 0
Right              : 595.275
Bottom             : 0
BorderColorBottom  :
BorderColorTop     :
BorderColorLeft    :
BorderColorRight   :
Width              : 595.275
Height             : 841.875
BorderWidth        : -1
BorderColor        :
BackgroundColor    :
Rotation           : 0
BorderWidthLeft    : -1
BorderWidthRight   : -1
BorderWidthTop     : -1
BorderWidthBottom  : -1
UseVariableBorders : False

このファイルのページサイズは、

>$pdfReader.GetPageSize(1).Height #高さ
841.875
>$pdfReader.GetPageSize(1).Width #幅
595.275

このファイルはA4縦なわけだけど、数字だけみてもわからないのでiTextSharpで定義されているA4縦と比較する。
定義されているA4縦はこれでわかる。

> [ITextSharp.text.PageSize]::A4

Top                :
Border             :
GrayFill           :
Left               :
Right              :
Bottom             :
BorderColorBottom  :
BorderColorTop     :
BorderColorLeft    :
BorderColorRight   :
BorderWidth        :
BorderColor        :
BackgroundColor    :
BorderWidthLeft    :
BorderWidthRight   :
BorderWidthTop     :
BorderWidthBottom  :
UseVariableBorders :
Type               : 30
Chunks             : {}
Width              : 595
Height             : 842
Rotation           : 0

上記の値を使って、ファイルのページサイズをint型にキャストして比較する。

> [iTextSharp.text.PageSize]::A4.Height -eq [int]$pdfReader.GetPageSize(1).Height
True

ちなみに、A4横の高さと幅を得るには、

> [iTextSharp.text.PageSize]::A4.Rotate().Height #高さ
595

> [iTextSharp.text.PageSize]::A4.Rotate().Width #幅
842

で、取得できる。

PowerShellでStringTemplateを使ってみる

| 2009年1月29日木曜日
まず、StringTemplateのサイトからDLLを落としてくる。

その中から、
・ antlr.runtime.dll
・ StringTemplate.dll
の二つを、適当なフォルダにコピーしておく。

テンプレートファイルはfoo.stというファイル名で
foo : $foo$
みないなのを作る。

先ほど、コピーした二つのファイルとfoo.stのあるフォルダで下記を実行する。

> [void][System.Reflection.Assembly]::LoadFrom(( Join-Path $pwd StringTemplate.dll))
> $sr = New-Object System.IO.StreamReader(
>> ( Join-Path $pwd foo.st ) ,
>> [System.Text.Encoding]::GetEncoding("shift-jis"))
>>
> $t = New-Object antlr.StringTemplate.StringTemplate($sr.ReadToEnd())
> $sr.Close()
> $t.SetAttribute("foo","テスト")
> $t.ToString()

結果:

foo : テスト

みたいに返ってくる。