繁体   English   中英

如何使用C#获取DefragAnalysis

[英]How to obtain DefragAnalysis using C#

我目前正在使用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

这是我在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以上版本的任何操作系统上运行,并且必须对用户完全透明。

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

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

实际上,在x86版本的PowerShell中运行PowerShell代码段也会产生一组空结果。

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

恐怕我不知道为什么这个WMI查询不喜欢在WoW64下运行,但是希望这能给您一个领先的机会。

无论出于何种原因,Win32_Volume的32位WMI提供程序似乎都无法启动defragsvc。 通过更改代码以添加其他WMI连接选项,即使在以WOW64运行的32位客户端中,也可以强制使用64位WMI提供程序:

ConnectionOptions mgmtConnOptions = new ConnectionOptions {
    EnablePrivileges = true,
    Context = new ManagementNamedValueCollection() { 
        { "__ProviderArchitecture", 64 }
    }
};

您可以简单地调用您在文章中提到的PowerShell命令,因为您说PowerShell代码可以工作。 在C#中,您需要遵循以下工作流程:

  1. 实例化PowerShell RunSpace
  2. Open空间
  3. 将脚本添加到Commands属性
  4. 调用命令列表

这是如何实现此目标以及处理结果对象输出的示例。

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

对于Windows XP和Windows Vista,您必须确保要在其上运行程序的每个系统上都安装了PowerShell。 有一个不错的先决条件,但作为依赖项要牢记。

希望这可以帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM