2011-12-22 15 views
2

インストーラのカスタムアクションを作成しています。インストールディレクトリを決定するには、CSIDL_COMMON_DOCUMENTSに格納されているファイルを読み取る必要があります。 (カスタムアクションでインストールディレクトリを変更するのは問題ではないと思っていますが、それは別の質問です)。.NET 3.5でCSIDL_COMMON_DOCUMENTSへのパスを取得する方法は?

.NET 4が追加されたのはCommonDocumentsからEnvironment.SpecialFolderです。残念ながら、私は.NET 3.5についています。次の最も簡単な方法は何ですか?

+0

[ダウンロードフォルダ:特別ではない?](http://stackoverflow.com/questions/3795023/downloads-folder-not-special-enough) –

答えて

1

私が知っている最も簡単な方法は、SHGetFolderPath functionをP/Invokeすることです。これは.NET FrameworkがEnvironment.SpecialFoldersの値を取得するために内部的に使用するものです。

定義は次のようになります。

[DllImport("shell32.dll"), CharSet = CharSet.Auto] 
static extern int SHGetFolderPath(IntPtr hwndOwner, int nFolder, IntPtr hToken, 
            uint dwFlags, [Out] StringBuilder pszPath); 

ます。またCSIDL_COMMON_DOCUMENTS定数が必要になります。

const int CSIDL_COMMON_DOCUMENTS = 0x002e; 

が存在しない場合は、にフォルダを作成したい場合は、あなたがCSIDL_FLAG_CREATEフラグを渡す必要があります:Windowsのヘッダからの直接。次のようにそれが定義されています

const int CSIDL_FLAG_CREATE = 0x8000; 

はこのようにそれを呼び出す:ちょうどあなたの情報のため

public static string GetCommonDocumentsFolder() 
{ 
    StringBuilder sb = new StringBuilder(); 
    int retVal = SHGetFolderPath(IntPtr.Zero, 
           CSIDL_COMMON_DOCUMENTS | CSIDL_FLAG_CREATE, 
           IntPtr.Zero, 
           0, 
           sb); 
    Debug.Assert(retVal >= 0); // assert that the function call succeeded 
    return sb.ToString(); 
} 

SHGetFolderPath機能は、シェル(SHGetKnownFolderPathの賛成でのWindows Vistaのよう推奨されていませんチームはこれらのことを変えるのが大好きです)。この新しい関数は、新しい識別子のセットをもたらします。 CSIDLの値の代わりに、KNOWNFOLDERIDの値が使用されるようになりました。新しいアプリケーションはすべて新しい機能を使用することをお勧めします。

しかし、古いバージョンの.NET Frameworkをターゲットにしており、アップグレードしたくないと考えると、おそらく最新のAPI関数を呼び出す必要はありません。 :-)

古いものは、Windows Vistaと7では、たとえ内部的には新しい機能の薄いラッパーとして実装されていても、うまく動作します。 Windows 8でエラーが発生した場合は、コードパスを分離するか、最終的にコードを修正し、.NETの最新バージョンにアップグレードする必要があります。

+3

コードで収集されたガベージコレクションが壊れています。文字列ビルダーを259文字の容量に初期化します。 –

+1

面白いことに、 'System.Environment.GetFolderPath'は' Win32Native.SHGetFolderPath'を呼び出し、 'Win32Native.SHGetKnownFolderPath'(.NET FW 4.0)はありません。 –

関連する問題