none
GetTempPath やGetTempFileName の動作について RRS feed

  • 質問

  • Visual Basic 2008で、GetTempPathメソッド、GetTempFileNameメソッドを使うと、8.3形式でなく、ロングファイルネームで取得されます。

    以前(少なくとも、Visual Basic .NET + .NET Framework1.1)では、8.3形式で取得されていたため、

    「C:\Documents and Settings~」のような半角スペースが入ったパスも正常にVBプログラムで認識できていたのですが

    Visual Basic 2008 + .NET Framework3.5.1でビルドしたものだと、ロングファイルネームで取得されてしまうため

    半角スペースが入ったパスが認識されず、そのパス配下にファイルを作成するなどを行うとエラーになってしまいます。

    Visual Basic 2008から何か仕様などが変わったのでしょうか?

    また、元の動作(ショートファイルネームが取得される)に戻す方法はありますでしょうか?

    実行環境、開発環境ともにWindowsXP sp3になります。

    2011年9月5日 11:13

回答

  • 同じWinXPで同じEXEをデバッグしたところ、VS2003では、ショートファイルネームが取得されていて、VS2008ではロングファイルネームが取得されていることが判明しています。同じ端末で、このような差異が発生してしまう原因をご教授して頂けないでしょうか?

    これを最初から書いて欲しかったです。.NET 1.1は今さらインストールしたくないので、動作確認せずにコメントしています。

    直接の回答ではありませんが、GetTempPathやGetTempFileNameが内部的に呼び出しているPath.GetFullPathメソッドの.NET 1.1、2.0には

    ショート ファイル名で渡すと、長いファイル名に拡張されません。

    とありますが、.NET 3.0以降には

    ショート ファイル名で渡すと、長いファイル名に拡張されます。

    とありました。
    # 2.0と3.0とでこのメソッドを含むmscorlib.dllに変更はありませんから2.0はドキュメントバグくさいですけど。

    ともかく、1.1と3.0とでパスの扱いが変わっているようでした。また長いファイル名に拡張しないように制御するオプション等は見つけられませんでした。

    • 回答としてマーク KYS31 2011年9月6日 1:46
    2011年9月5日 15:11

すべての返信

  • それらは Win32API の GetTempPath 関数や GetTempFileName 関数を呼び出しているだけで変わってないはずなので、変更があったとすれば .NET ではなく Windows の方でしょう。

    で、例えば FileStream クラスや StreamWriter クラスを使う限りパスに空白があるかどうかなんて一切関係ありませんが、どうやってファイルの作成などされているのでしょう?

    2011年9月5日 11:59
  • で、Windows APIのGetTempPathは、環境変数のTMPなどを返すので、この値が以前の環境ではshort file nameだったのでしょう。
    2011年9月5日 12:04
  • で、Windows APIのGetTempPathは、環境変数のTMPなどを返すので、この値が以前の環境ではshort file nameだったのでしょう。

    回答ありがとうございます。


    環境変数にショートファイルネームを設定すれば良いということでしょうか?

    そして、環境変数のTMPを返すということは、EXEを動かす端末の設定に依存してしまうということでしょうか?(A端末では、ショートファイルネームが取れても、B端末ではロングファイルネームがとれない?)

    しかし、疑問があります。

    同じWinXPで同じEXEをデバッグしたところ、VS2003では、ショートファイルネームが取得されていて、VS2008ではロングファイルネームが取得されていることが判明しています。同じ端末で、このような差異が発生してしまう原因をご教授して頂けないでしょうか?

    • 編集済み KYS31 2011年9月5日 13:07
    2011年9月5日 12:55
  • 同じWinXPで同じEXEをデバッグしたところ、VS2003では、ショートファイルネームが取得されていて、VS2008ではロングファイルネームが取得されていることが判明しています。同じ端末で、このような差異が発生してしまう原因をご教授して頂けないでしょうか?

    これを最初から書いて欲しかったです。.NET 1.1は今さらインストールしたくないので、動作確認せずにコメントしています。

    直接の回答ではありませんが、GetTempPathやGetTempFileNameが内部的に呼び出しているPath.GetFullPathメソッドの.NET 1.1、2.0には

    ショート ファイル名で渡すと、長いファイル名に拡張されません。

    とありますが、.NET 3.0以降には

    ショート ファイル名で渡すと、長いファイル名に拡張されます。

    とありました。
    # 2.0と3.0とでこのメソッドを含むmscorlib.dllに変更はありませんから2.0はドキュメントバグくさいですけど。

    ともかく、1.1と3.0とでパスの扱いが変わっているようでした。また長いファイル名に拡張しないように制御するオプション等は見つけられませんでした。

    • 回答としてマーク KYS31 2011年9月6日 1:46
    2011年9月5日 15:11
  • これを最初から書いて欲しかったです。.NET 1.1は今さらインストールしたくないので、動作確認せずにコメントしています。

    ともかく、1.1と3.0とでパスの扱いが変わっているようでした。また長いファイル名に拡張しないように制御するオプション等は見つけられませんでした。

    大変失礼致しました。

    .NET Framework のバージョンの差異によって、GetFullPath メソッドの仕様が変わったということで、了解致しました。

    原因が分かり、とてもすっきりしました。

    対応としては、GetShortPathName メソッドでショートファイルネームを取得するなどを考えます。

    ありがとうございました。

    2011年9月6日 1:46
  • 蛇足ですが、最近ではSSDの普及に伴って、NTFSの設定で「ショートファイル名を作成しない」になっている場合もあります。根本的な問題として、空白を含むような場合でも、有効なファイル名であればきちんと扱えるようにするべきかと思います。
    2011年9月6日 2:10
  • 蛇足ですが、最近ではSSDの普及に伴って、NTFSの設定で「ショートファイル名を作成しない」になっている場合もあります。根本的な問題として、空白を含むような場合でも、有効なファイル名であればきちんと扱えるようにするべきかと思います。

    そうなんですね。ご指摘ありがとうございます。
    2011年9月6日 5:31