xlogI125’s blog

パソコン作業を効率化したい

PowerShell練習 Add-Type (StrCmpLogicalW) 3

メモ

  • 現在のフォルダ内にあるファイル名を StrCmpLogicalW と List<T>.Sort(Comparison<T>) でソートして取得

使い捨てスクリプト

  • このスクリプトを起動させるショートカット(.lnk)をSendToフォルダに入れて使用
# PowerShell 5.1, Windows 11

# ファイル名
#   "%USERPROFILE%\Desktop\Sort_StrCmpLogicalW_File.ps1"
# エンコード
#   UTF-8 (BOM付き)

# ショートカット(.lnk)
#   リンク先(T):
#     PowerShell.exe -NoLogo -NoExit -ExecutionPolicy RemoteSigned -File "%USERPROFILE%\Desktop\Sort_StrCmpLogicalW_File.ps1"
#   作業フォルダー(S):
#     ""

# SendToフォルダ
#   %APPDATA%\Microsoft\Windows\SendTo

using namespace System.IO

Set-StrictMode -Version Latest

$srcCSharp = @'
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.IO;

namespace MyNamespace {
  public class MyClass {
    [DllImport(
      "Shlwapi.dll", EntryPoint = "StrCmpLogicalW", CharSet = CharSet.Unicode
    )]
    public static extern int StrCmpLogicalW(
      [MarshalAs(UnmanagedType.LPWStr)] string psz1, 
      [MarshalAs(UnmanagedType.LPWStr)] string psz2
    );

    public static int SortStrCmpLW<T>(T obj1, T obj2) where T : FileSystemInfo {
      return StrCmpLogicalW(obj1.Name, obj2.Name);
    }

    public static T[] MySort<T>(T[] obj) where T : FileSystemInfo {
      List<T> tmp = new List<T>(obj);
      tmp.Sort(SortStrCmpLW<T>);
      return tmp.ToArray();
    }
  }
}
'@

Add-Type -Language CSharp -TypeDefinition $srcCSharp

## フォルダに移動
# Set-Location "${env:USERPROFILE}\Desktop"

# ファイルを取得
$gciOrig = [FileSystemInfo[]]@(Get-ChildItem -Force -File)

# ソート
$gciSorted = [MyNamespace.MyClass]::MySort($gciOrig)

Write-Host "`$gciSorted.count: $($gciSorted.count)"

if ( $gciSorted.count -gt 0 ) {
  # 画面に表示
  Write-Host ($gciSorted.Name -join "`n")
  # クリップボードにコピー
  $gciSorted.Name | Set-Clipboard
} else {
  # クリップボードにコピー
  @() | Set-Clipboard
}

過去記事

dy100ms.hatenadiary.jp