How to get DefragAnalysis using C #

I am currently developing an application in C # (.NET 4.0), which should have the ability to determine the percentage of fragmentation on a particular volume as part of its functionality. All other functions have been tested and work fine, but Ive got into a trap trying to access this data. Ideally, I would prefer to use WMI, since this corresponds to the Im format used for other functions, but at the moment Im is ready to use everything that can be effectively integrated into the application, even if I need to use RegEx to filter data. I am currently developing on a computer with Windows 7 Professional (x64). I tested the following Powershell snippet using admin privileges and it works flawlessly.

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

This is the Im method used in C # to do the same, but InvokeMethod continues to return 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; } 

I even added the following line to app.manifest, but still nothing.

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

Can someone please tell me what Im missing? Failure is not an option for me, therefore, if it is impossible to do it using C #, I do not mind creating a DLL in another language (even if I need to learn it), it will give me the results that I need. Ideally, the application should work with any OS with XP up and should be completely transparent to the user.

These are the resources that I have already used. I wanted to add the jeffrey_wall blog to msdn, but as a new user, I can add only 2 hyperlinks at a time. Thanks again.

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

+4
source share
3 answers

Try to create your own targeting for applications "Any processor" - on the "Assembly" tab of the project properties. I suspect you are using an x86 target. I get the same error code on my Win7 x64 machine if I do this.

In fact, running a PowerShell snippet in the x86 version of PowerShell also gives an empty result set.

You will get the same error if you run any piece of code without full administrator rights, as you already found, so also make sure your app.manifest is correct. The UAC invitation is a handy clue that it is taking effect!

I don’t know why this WMI request doesn’t like working under WoW64, I’m afraid, but hopefully this will give you an edge.

+3
source

You can simply invoke the PowerShell command indicated in your message, since you said that the PowerShell code is working. With C #, you want to follow this workflow:

  • Create an instance of PowerShell RunSpace
  • Open runspace
  • Add a script to the Commands property
  • Call up a list of commands

Here is an example of how to achieve this and handle the resulting output of an object.

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

For Windows XP and Windows Vista, you need to make sure that PowerShell has been installed on each of the systems on which you want to run your program. A good condition that you need to have, but something to keep in mind as a dependency.

Hope this helps.

+1
source

The 32-bit WMI provider for Win32_Volume apparently cannot run defragsvc for any reason. You can force a 64-bit WMI provider even in a 32-bit client running under WOW64 by changing your code to add additional WMI communication:

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

Source: https://habr.com/ru/post/1398904/


All Articles