如何使用C#获取DefragAnalysis

You*_*per 5 c# powershell wmi defragmentation wql

我目前正在开发一个C#(.NET 4.0)应用程序,该应用程序应该具有确定特定卷上碎片百分比的功能.所有其他功能都经过测试,工作正常,但我试图访问这些数据.我理想情况下更喜欢使用WMI,因为这与我用于其他功能的格式相匹配,但此时我愿意使用任何可以有效集成到应用程序中的内容,即使我必须使用RegEx来过滤数据.我目前正在Windows 7 Professional(x64)机器上进行开发.我使用管理员权限测试了以下Powershell代码段,它可以完美运行.

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

这是我在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;
    }
Run Code Online (Sandbox Code Playgroud)

我甚至在app.manifest中添加了以下行,但仍然没有.

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
Run Code Online (Sandbox Code Playgroud)

有人可以告诉我我在俯瞰什么吗?失败对我来说不是一个选择,所以如果不能使用C#我不介意用另一种语言创建一个DLL(即使我必须学习它),这将给我我需要的结果.理想情况下,应用程序应该可以在XP以上的任何操作系统上运行,并且必须对用户完全透明.

这些是我已经使用过的资源.我想在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

Dog*_*ang 3

尝试在项目属性的“构建”选项卡上构建针对“任何 CPU”的应用程序。我怀疑您使用的是 x86 目标。如果我这样做,我会在我的 Win7 x64 机器上得到相同的错误代码。

事实上,在 x86 版本的 PowerShell 中运行 PowerShell 代码段也会给出一组空结果。

正如您所发现的,如果您在没有完全管理员权限的情况下运行任意一段代码,您会遇到相同的错误,因此还要确保您的 app.manifest 正确。UAC 提示是一个方便的提示,表明它正在生效!

恐怕不知道为什么这个 WMI 查询不喜欢在 WoW64 下运行,但希望这会给您一个良好的开端。