2017-09-09 3 views
0

ドライブが使用中であると評価したいと思います(私が間違っていないと、これはドライブで何らかの読み書きが行われていることを意味します)。私はC#アプリケーションで使用できるので、bashスクリプトを使用した解決策も同様の解決策も気にしません。私は既にbashスクリプトhereに関する質問を見つけましたが、答えに私の問題を解決できませんでした。ドライブが使用中であるかどうか評価してください

私はDriveInfoクラスを既に使用していると考えましたが、私には役に立たないようでした。私は、のプロパティをDriveInfoから使用できると思っていました。読み書き中は準備ができていないだろうと思っていたからです。

private static bool IsDriveInUse() 
{ 
    var drive = DriveInfo.GetDrives().FirstOrDefault(info => info.Name.StartsWith(DRIVE_LETTER.ToString())); 
    return drive != null && !drive.IsReady; 
} 

しかし、それは(私は私のドライブから音楽を再生しながら、それはfalseが返さ)動作し​​ませんでした:私はまだそれを試してみましたが

私にとって最適な解決策は、特定の時間内にドライブが使用されていることを知らせる機能です(名前IsDriveInUseに固執しましょう)。つまり、時間が60秒の場合、IsDriveInUseは、ドライブからの関数呼び出しの内容が読み取られる5秒前にtrueを返し、渡された60秒に読み取り/書き込みのアクションがない場合はfalseを返します。使用にによって、私は意味を正確に指定するには


EDIT、私は私がやろうとしているかを説明しようとするでしょう。私はアイドル時やキーボードショートカットを押すと、ハードドライブを自動的にスピンさせるツールを書いています。私はそれをプログラムでスピンダウンすることができました(たとえWindows統合ツールや他のツールでも可能でしたが、別の問題です)。ただし、現在使用中であるかどうかに関わらず、毎分ハードドライブがスピンダウンします。つまり、私がハードドライブから音楽を奏でても、それはまだスピンダウンしています。その直後にスピンアップしてノイズの発生を減らさないということです。

これが問題を明確にすることを希望します。


EDIT私は今(私はIOCTL_DISK_PERFORMANCEの値を見つけることができませんでした)FSCTL_LOCK_VOLUME制御コードを使用してみましたが、私は音楽を演奏している間に、それはまだIsDriveInUse()ためfalseを返しました。さらに、私はそれをスピンダウンすると、Windowsが直接ドライブを回転させる原因となりました(おそらくWindowsのリリースにより、何かがドライブを使用していると思ったからです)。これは私が試したものです:

public class DriveManager 
{ 
    public const int FSCTL_LOCK_VOLUME = 0x00090018; 
    public const int FSCTL_UNLOCK_VOLUME = 0x0009001c; 

    [DllImport ("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    private static extern IntPtr CreateFile (
     string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, 
     uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile); 

    [return: MarshalAs (UnmanagedType.Bool)] 
    [DllImport ("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    public static extern bool DeviceIoControl (
     [In] SafeFileHandle hDevice, 
     [In] int dwIoControlCode, [In] IntPtr lpInBuffer, 
     [In] int nInBufferSize, [Out] IntPtr lpOutBuffer, 
     [In] int nOutBufferSize, out int lpBytesReturned, 
     [In] IntPtr lpOverlapped); 

    public static SafeFileHandle CreateFileR (string device) 
    { 
     string str = device.EndsWith (@"\") ? device.Substring (0, device.Length - 1) : device; 
     return new SafeFileHandle (
      CreateFile (@"\\.\" + str, WinntConst.GENERIC_READ, WinntConst.FILE_SHARE_READ, IntPtr.Zero, 
         WinntConst.OPEN_EXISTING, WinntConst.FILE_ATTRIBUTE_NORMAL, IntPtr.Zero), true); 
    } 

    internal class WinntConst 
    { 
     // Fields 
     internal static uint FILE_ATTRIBUTE_NORMAL = 0x80; 

     internal static uint FILE_SHARE_READ = 1; 
     internal static uint GENERIC_READ = 0x80000000; 
     internal static uint OPEN_EXISTING = 3; 
    } 

    public static bool IsDriveInUse (string deviceName) 
    { 
     var handle = CreateFileR (deviceName); 
     var buffer = Marshal.AllocHGlobal (sizeof (int)); 
     try 
     { 
      return 
       DeviceIoControl (handle, 
           FSCTL_LOCK_VOLUME, 
        IntPtr.Zero, 
        0, 
        buffer, 
        sizeof(int), 
        out var bytesReturned, 
        IntPtr.Zero 
       ); 
     } 
     finally 
     { 
      var sessionId = Marshal.ReadInt32 (buffer); 
      Marshal.FreeHGlobal (buffer); 
      handle.Close(); 
     } 
    } 

と実装:

private static bool IsDriveInUse() => DriveManager.IsDriveInUse ([email protected]"{DRIVE_LETTER}:\"); 

は、多分それは(私はこれのためにSmartmontoolsを使用)だけでなく、私はディスクをスピンダウンしていた部分を見ることができます:

internal static class Program 
{ 
    private const string PROGRAM_PATH = @"External\smartctl.exe"; 
    private const string ARGUMENTS_SHUTDOWN = @"-s standby,now {0}:"; 
    private const char DRIVE_LETTER = 'd'; 


    public static void Main (string [] args) 
    { 
     InitializeHotKey(); 
     Console.WriteLine ("Hotkey registered!"); 

     while (true) 
     { 
      Thread.Sleep (60000); 
      if (!IsDriveInUse()) 
       ShutDownDrive (true); 
     } 
    } 

    private static bool IsDriveInUse() => DriveManager.IsDriveInUse ([email protected]"{DRIVE_LETTER}:\"); 

    private static void InitializeHotKey() 
    { 
     HotKeyManager.RegisterHotKey (Keys.D, KeyModifiers.Alt | KeyModifiers.Control); 
     HotKeyManager.HotKeyPressed += HotKeyPressed; 
    } 

    private static void HotKeyPressed (object sender, HotKeyEventArgs hotKeyEventArgs) => ShutDownDrive (true); 

    private static void ShutDownDrive (bool withDialog = false) 
    { 
     Process process; 
     (process = new Process 
     { 
      StartInfo = new ProcessStartInfo 
      { 
       WindowStyle = ProcessWindowStyle.Hidden, 
       FileName = PROGRAM_PATH, 
       Arguments = string.Format (ARGUMENTS_SHUTDOWN, DRIVE_LETTER) 
      } 
     }).Start(); 

     process.WaitForExit(); 
     process.Close(); 

     if (withDialog) 
      Console.WriteLine ("Drive shut down!"); 
    } 
} 
+0

「使用中」と「準備完了」という意味を正確に指定します。ディスクはスケジューリングによって一度に複数のことを行うことができます。ワークステーションやサーバーのハードディスクには、ほとんど常に読書や書込みが行われています。あなたが解決しようとしている問題は何ですか?マシン、リムーバブルドライブ、またはネットワークドライブに固定されたドライブですか? – CodeCaster

+0

また、「InUse」についての正しい情報を得ることができるとします。あなたの行動を取る前にその状態が変わるかもしれません。 –

+0

@ L.B私は主に私のためにこのツールを書いているので、私は非常に頻繁にハードドライブを使用しないので、これは当てはまらないと約束することができます。 – MetaColon

答えて

関連する問題