.NET TIPS

長いパスを8.3形式の短いパスに変換するには?[C#、VB]

デジタルアドバンテージ 一色 政彦
2007/10/11

 Windows OS以前のMS-DOSシステムでは、フォルダやファイルの名前に8.3形式の短い名前(以降、短いパス)しか利用できなかった。現在のWindows OSでも、一部、8.3形式の短いパスの命名規則が用いられている個所(例えば、レジストリの値など)が存在する。そこで「TIPS:8.3形式の短いパスを長いパスに変換するには?」では、短いパスを、Windowsで使われる通常の長いパスに変換する方法を紹介した。本TIPSでは、その逆に、長いパスから短いパスに変換する方法を紹介する。

長い形式のパスを短い8.3形式のパスに変換する方法

 長いパスを短いパスに変換する機能は、.NET Frameworkでは提供されていないので、Win32 APIを呼び出す必要がある。具体的には、kernel32.dllファイルのGetShortPathName関数を呼び出す。

 GetShortPathName関数は、第1パラメータに長いパス(String型)を指定し、第2パラメータに文字列バッファ(StringBuilder型)を指定する。この関数は、この文字列バッファを介して短いパスを受け取る。第3パラメータには、その文字列バッファのサイズ(=バイト数。int/Integer型)を指定する。このサイズを指定する際には、受け取れるパス文字列のサイズ(=文字列長)に加えて、そのパスの最後に付け加えられる終端記号のNULL文字(=「\0」)分の「1byte」を加えておく(要するに「受け取れる最大の文字数+1」の値を指定する)必要があるので、注意してほしい。例えば第3パラメータで「33bytes」を指定した場合、(最後に終端記号のNULL文字が足されるので)「32文字」分のパス名しか受け取れないことになる。

 そして戻り値として、第2パラメータの文字列バッファに渡した文字列サイズを返す(変換に失敗した場合は「0」が返される)。ただし、このサイズには終端記号のNULL文字(=「\0」)分の「1byte」はカウントされていない(先ほどの第3パラメータとの違いに注意されたい)。そのため、この値は正式な「受け取った文字のバイト数」となる。

 Win32 APIの呼び出し方については、「TIPS:Win32 APIやDLL関数を呼び出すには?」や「TIPS:Win32 APIやDLL関数に文字列や文字列バッファを渡すには?」を参照していただきたい。

 以上のGetShortPathName関数を利用して長いパスを短いパスに変換する処理を実装したコード例を次に示す。

using System;
using System.Text;
using System.Runtime.InteropServices;

class Program
{
  [DllImport("kernel32.dll")]
  private static extern int GetShortPathName(string longPath, StringBuilder shortPathBuffer, int bufferSize);

  static void Main(string[] args)
  {
    string longPath =
      @"C:\Program Files\Mozilla Firefox\FIREFOX.EXE";
    int bufferSize = 260;
    StringBuilder shortPathBuffer = new StringBuilder(bufferSize);
    GetShortPathName(longPath, shortPathBuffer, bufferSize);
   
    string shortPath = shortPathBuffer.ToString();
    Console.WriteLine(shortPath);
    // 出力例:C:\PROGRA~1\MOZILL~1\FIREFOX.EXE
  }
}
Imports System.Text
Imports System.Runtime.InteropServices

Module Module1

  <DllImport("kernel32.dll")> _
  Private Function GetShortPathName(ByVal longPath As String, ByVal shortPathBuffer As StringBuilder, ByVal bufferLength As Integer) As Integer
  End Function

  Sub Main()
    Dim longPath As String = _
      "C:\Program Files\Mozilla Firefox\FIREFOX.EXE"
    Dim bufferLength As Integer = 260
    Dim shortPathBuffer As New StringBuilder(bufferLength)
    GetShortPathName(longPath, shortPathBuffer, bufferLength)

    Dim shortPath As String = shortPathBuffer.ToString()
    Console.WriteLine(shortPath)
    ' 出力例:C:\PROGRA~1\MOZILL~1\FIREFOX.EXE
  End Sub

End Module
長いパスを短いパスに変換するコンソール・アプリケーションのサンプル・プログラム(上:C#、下:VB)

 なお、上記のコードで文字列バッファのサイズを「260」にしている理由は、パスの最大文字列長(マイクロソフトが提供するC/C++ライブラリ・ヘッダのstdlib.hファイルに定義されている「MAX_PATH」)が「260bytes」だからだ(この260bytesには終端記号のNULL文字が含まれるので注意すること。なお、Unicode版のWin32 APIでは「32000bytes」に拡張可能だが、ほとんどのアプリケーションが前述の「MAX_PATH」の定義に従っているため、その低い方の制限に合わせておく方が無難である。例えば260文字以上のパスは、Windowsエクスプローラでエラーになるなどの問題が発生することがある)。End of Article

カテゴリ:クラス・ライブラリ 処理対象:パス
関連TIPS:Win32 APIやDLL関数を呼び出すには?
関連TIPS:Win32 APIやDLL関数に文字列や文字列バッファを渡すには?

この記事と関連性の高い別の.NET TIPS
8.3形式の短いパスを長いパスに変換するには?
パス文字列からファイル名部分を取り出すには?
パス文字列からディレクトリ・パス部分を取り出すには?
アプリケーション設定情報はどこに保存すべきか?
INIファイルを読み書きするには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間