2012-02-28 15 views
4

現在、C#(.NET 4.0)で、特定のボリューム上の断片化率を決定する機能を持つアプリケーションを開発中です。他のすべての機能はテストされて正常に動作していますが、私はこのデータにアクセスしようとして困っています。私は理想的には、これは他の機能に使用している形式と一致するため、WMIを使用する方が好きですが、この時点ではRegExを使用してアプリケーションに効率的に統合できるものを使用していますデータ。私は現在、Windows 7 Professional(x64)マシンで開発を行っています。私は以下のPowershellスニペットを管理者権限でテストしており、完璧に動作します。C#を使用してDefragAnalysisを取得する方法

$drive = Get-WmiObject -Class Win32_Volume -Namespace root\CIMV2 -ComputerName . | Where-Object { $_.DriveLetter -eq 'D:' } 
$drive.DefragAnalysis().DefragAnalysis 

これは私が同じことを達成するためにC#で使用していますが、は、invokeMethodは11(0xB)を返す保つ方法です。

public static Fragmentation GetVolumeFragmentationAnalysis(string drive) 
{ 
//Fragmenation object initialization removed for simplicity 
     try 
     { 
      ConnectionOptions mgmtConnOptions = new ConnectionOptions { EnablePrivileges = true }; 
      ManagementScope scope = new ManagementScope(new ManagementPath(string.Format(@"\\{0}\root\CIMV2", Environment.MachineName)), mgmtConnOptions); 
      ObjectQuery query = new ObjectQuery(string.Format(@"SELECT * FROM Win32_Volume WHERE Name = '{0}\\'", drive)); 
      scope.Connect(); 
      using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query)) 
      { 
       object[] outputArgs = new object[2]; 
       foreach (ManagementObject moVolume in searcher.Get()) 
       { 
        // Execution stops at this line as the result is always 11 
        UInt32 result = (UInt32)moVolume.InvokeMethod("DefragAnalysis", outputArgs); 
        if (result == 0) 
        { 
         Console.WriteLine("Defrag Needed: = {0}\n", outputArgs[0]); 
         ManagementBaseObject mboDefragAnalysis = outputArgs[1] as ManagementBaseObject; 
         if (null != mboDefragAnalysis) 
         { 
          Console.WriteLine(mboDefragAnalysis["TotalPercentFragmentation"].ToString()); 
         } 
        } 
        else 
        { 
         Console.WriteLine("Return Code: = {0}", result); 
        } 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("Could not acquire fragmentation data.\n" + ex); 
     } 

     return result; 
    } 

次の行をapp.manifestに追加しましたが、それでも何も表示されません。

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

誰かが私が見落としていることを教えてください。失敗は私の選択肢ではないので、C#を使用して実行できない場合は、別の言語でDLLを作成しても問題はありません。理想的には、アプリケーションはXP以上の任意のOSで動作する必要があり、ユーザーには完全に透過的でなければなりません。

これはすでに使用しているリソースです。私はmsdnにjeffrey_wallブログを追加したかったのですが、新しいユーザーとしては一度に2つのハイパーリンクしか追加できません。再度、感謝します。

http://www.codeproject.com/Messages/2901324/Re-the-result-of-DefragAnalysis-method-in-csharp.aspx

http://social.technet.microsoft.com/Forums/vi-VN/winserverfiles/thread/9d56bfad-dcf5-4258-90cf-4ba9247200da

答えて

3

[すべてのCPU]を対象とするアプリケーションをビルドしてみてください。プロジェクトプロパティの[ビルド]タブにあります。私はあなたがx86のターゲットを使用していると思う。もし私がそれを行う場合、私はWin7 x64マシンで同じエラーコードを取得します。

実際、PowerShellのx86バージョンでPowerShellスニペットを実行すると、空の結果も表示されます。

完全な管理者権限を持たないコードを実行した場合、app.manifestが正しいことを確認すると同じエラーが発生します。 UACプロンプトは有効なヒントです!

このWMIクエリがWoW64での実行が気に入らない理由はわかりませんが、うまくいけば、これで頭がおかしくなります。

+0

それは面白いです - 私はテストし、同じ結果もあった。良い提案。 –

+0

実際、私は、「Any CPU」にアーキテクチャを設定することは*解決策だと思います。よくやった。 –

+1

このような迅速な対応に、ありがとうございました。それが問題の正確な解決策でした。誰が考えただろうか。再度、感謝します。 – YoungGrasshopper

1

あなたはPowerShellのコードが動作すると述べたので、あなたは、単に、あなたがあなたの記事で言及したPowerShellコマンドを呼び出すことができます。コマンドリストを

ここCommandsプロパティ

  • にスクリプトを追加RunSpace
  • Open実行空間
    1. PowerShellをインスタンス化し起動します。C#のからは、次のワークフローに従いたいと思いますこれを達成し、結果のオブジェクト出力を処理する方法の例です。

      Windows XPおよびWindows Vistaの場合

      http://www.codeproject.com/Articles/18229/How-to-run-PowerShell-scripts-from-C

      、あなたはPowerShellを使用すると、上のプログラムを実行する各システムにインストールされたことを確認しなければならないでしょう。持っていることは悪い前提条件ではありませんが、依存関係として心に留めておくべきことです。

      これが役に立ちます。

  • +0

    を感謝トレバー、Dogmangのソリューションは、あなたの提案はそう私のために働いていても私がManagementObjectCollectionで持っていた他の問題に対する素晴らしいアプローチのように。 Dulyは指摘する。 – YoungGrasshopper

    +1

    私はそれを正直に勧めませんでした。あなたがWMIで行うことの大部分(すべてではないにしても)については、System.Management名前空間とC#コードに固執してください。私はWMIを幅広く使ってきましたが、C#コードを書くときには.NET Base Class LibraryのAPIが本当に好きです。一方、主にPowerShellで書いているのであれば、PowerShellのコンストラクトを使用してください。 :)乾杯 –

    0

    Win32_Volume用の32ビットWMIプロバイダは、何らかの理由でdefragsvcを開始できないようです。あなたは追加のWMI接続オプションを追加するようにコードを変更しても、WOW64の下で実行されている32ビットクライアントでは64ビットのWMIプロバイダーを強制することができます。

    ConnectionOptions mgmtConnOptions = new ConnectionOptions { 
        EnablePrivileges = true, 
        Context = new ManagementNamedValueCollection() { 
         { "__ProviderArchitecture", 64 } 
        } 
    }; 
    
    関連する問題