В настоящее время я занимаюсь разработкой приложения на 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 и выше и должно быть полностью прозрачным для пользователя.
Это ресурсы, которые я уже использовал. Я также хотел добавить блог jeffrey_wall на msdn, но как новый пользователь я могу добавлять только 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