2016-04-16 30 views
1

高速ディスク使用状況検出プログラムを作成したい場合、これを実行する最速の方法はFileSystemObjectです。 FileSystemObjectCOM -> Microsoft Scripting Runtimeです。C#でFileSystemObjectを使用中にセキュリティ例外が発生しました

すべてのコードはシンプルで、ここで解析しました。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace DiskUsage 
{ 
    class Program 
    { 
     const string FolderPath = @"C:\Windows\System32"; 

     static void Main(string[] args) 
     { 
      var startTime = DateTime.Now; 

      Scripting.FileSystemObject fso = new Scripting.FileSystemObject(); 
      Scripting.Folder folder = fso.GetFolder(FolderPath); 
      Int64 dirSize = (Int64)folder.Size; 

      TimeSpan span = DateTime.Now.Subtract(startTime); 

      System.Console.WriteLine("{1} size: {0}", dirSize, FolderPath); 
      System.Console.WriteLine("use time: {0}", span); 
      System.Console.ReadKey(); 
     } 
    } 
} 

そして私のセットアップapp.manifest

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> 

私は私のプログラムをテスト

に、セキュリティ例外が私のために申し訳ありませんが、私は手動で変換する(このライン

Int64 dirSize = (Int64)folder.Size; 

例外情報に来ます英語が貧しい人)は

Unhandled exception type “System.Security.SecurityException” occurred in DiskUsage.exe 
Other message: exception from HRESULT:0x800A0046 (CTL_E_PERMISSIONDENIED) 
です

FolderPath@"D:\Codes"に変更した場合。それはうまく動作します。したがって、マニフェストのセキュリティ設定はCOM -> Microsoft Scripting Runtimeには影響しないと思います。誰でもこれを修正する方法を知っていますか?助けてください、ありがとう。

答えて

2

Sizeプロパティが呼び出されると、魔法が発生します。内部的にはまだ完全なフォルダツリーを走査し、フォルダのサイズを決定するのはファイルです。昇格したかどうかにかかわらず、あなたの運が悪いサブフォルダのファイルを一覧表示する権限がない場合は、Sizeへの呼び出しは失敗します。

代わりに、System.IOにあるDirectoryクラスを使用してフォルダトラバーサルを再実装しましたが、いくつかのロギングと例外処理が追加されているため、アクセス可能なファイルの場合はフォルダのサイズがわかりますに。

あなたの主な方法は、この変更を持っている必要があります:

Int64 dirSize; 
try { 
    dirSize = (Int64)folder.Size; 
} 
catch(SecurityException sec) 
{ 
    dirSize = FolderSize(FolderPath); 
} 

あなたが例外に遭遇した場合、我々はFolderSizeのC#実装が、それは許可されていない例外を補償する。この時間に電話をかけます。

static Int64 FolderSize(string path) 
{ 
    long sum =0; 
    try 
    { 
     // scan folders 
     foreach(var dir in Directory.EnumerateDirectories(path)) 
     { 
      //recursive call 
      sum += FolderSize(dir); 
     } 
    } 
    catch(UnauthorizedAccessException unath) 
    { 
     Console.WriteLine("{0} for folder {1}", unath.Message, path); 
    } 
    try 
    { 
     // scan files 
     foreach (var file in Directory.EnumerateFiles(path)) 
     { 
      sum += new FileInfo(file).Length; 
     } 
    } 
    catch(UnauthorizedAccessException filesec) 
    { 
     Console.WriteLine("{0} for file {1}", filesec.Message, path); 
    } 
    return sum; 
} 
+0

ありがとうございました。それはうまくいくだろうが、私は、すべてのファイルにアクセスする許可を得る方法が中心的な問題だと思う? – Jennal

+0

あなたはあなたのプロセスを昇格させたり、権限のないフォルダを見つけたり、所有権を得ようとしたり、権限を割り当てたりすることはできますが、それはフェールセーフではありません。私のソリューションは、あなたがアクセス権を持つファイルのためのフォルダ化を提供します。 – rene

+0

はい、あなたは正しいです。私はあなたの解決策を試みるでしょう。 – Jennal

関連する問題