2011-09-23 16 views
5

Possiedo un programma che esegue l'I/O grezzo su dischi in Windows.Prendere dischi online/offline

Tutto funziona correttamente se il disco di destinazione è in linea. Tuttavia, il comportamento predefinito in alcuni sistemi operativi Windows è di avere inizialmente nuovi dischi non in linea.

Ho difficoltà a trovare l'API corretta per eseguire questa operazione su Windows. L'equivalente da riga di comando sarebbe qualcosa come:

"select disk 2", "online disk" | diskpart 

Tuttavia, devo essere in grado di farlo in codice. Ho controllato l'API Win32 DeviceIoControl (che ritengo sia giusto) ma non posso determinare quale codice di controllo utilizzare. Il fatto che non riesca a trovarlo mi fa pensare che potrebbe mancare una migliore API da usare.

+0

perché non solo shell esegue la riga di comando da C#? –

+1

Per una serie di motivi, ma è sufficiente dire che non è un'opzione. Se diskmgmt e diskpart possono farlo, c'è un modo. Voglio sapere in che modo. – Joe

+1

@joe - diskmgmt e diskpart sono gui per i comandi integrati in Windows che potrebbero utilizzare l'API Win32. Considerando che sono stati in giro per un po 'questo è improbabile. Tutto quello che puoi fare attraverso quelle cose che puoi fare attraverso una linea di comando. –

risposta

2

This question ha un paio di collegamenti utili all'API di Windows, incluso il metodo DeviceIOControl.

Dopo aver esaminato tutte le enumerazioni, non sono riuscito a trovare nulla correlato a portare un disco online o apportare modifiche interessanti al disco oltre la formattazione/le partizioni. Ciò è probabile perché solo le unità disco rigido sostituibili a caldo sono supportate da questa funzionalità. Il mercato degli hard disk hot-swappable è molto piccolo, e nella stragrande maggioranza di questi casi ci sono driver che supportano tutte le operazioni necessarie. Infine, il resto dovrebbe essere in grado di utilizzare lo strumento diskpart per tutto ciò che è necessario.

Devi pensare nuovamente alle tue esigenze. Stai eseguendo un processo che ha i diritti necessari per l'online un disco rigido, ma non può accedere ad un programma da riga di comando? Ecco alcuni suggerimenti per motivi comuni a non utilizzare un programma a riga di comando:

  • non può avere una schermata nera pop-up - tonnellate di soluzioni a questo problema sono disponibili on-line
  • sicurezza squadra non gli permetterà - stai già eseguendo il processo come amministratore quindi ti fidi di esso, perché non ti fidi della funzione Windows integrata
  • I problemi tecnici precludono il richiamo di altri processi: sarei interessato a come è stato gestito, dato che il processo è in esecuzione come un amministratore
  • Linee guida di codifica come "Usa sempre l'API" - non ce n'è uno per mancanza di necessità
+0

Esistono in realtà numerosi utilizzi per i dischi dinamici all'esterno di hot-swap. Grazie per il link, ho visto che sebbene tu abbia notato non ci sono soluzioni reali. – Joe

+0

@Joe: Intendevo la capacità fisica del disco non l'azione – Guvante

4

Per le generazioni future, la risposta (su Win 2k3/Vista e successivi) è il Virtual Disk Service (VDS). C'è un po 'di lavoro nel riunire tutto, specialmente se non usi molto gli oggetti COM all'interno di .NET.

Il disco online/offline viene eseguito con IVdsDrive::SetStatus. Almeno dovrebbe; Ho scoperto che potevo risolvere il mio problema semplicemente disabilitando lo stato di sola lettura sul mio disco. Sono stato in grado di farlo con IVdsDisk::SetFlags con il valore di bandiera appropriato.

+0

L'api è un grande inferno, come lo uso? La documentazione è davvero poco chiara. – Gizmo

2

Non sono sicuro di C#, ma sto usando questo in C++: Prova a chiamare DeviceIoControl() con IOCTL_DISK_SET_DISK_ATTRIBUTES. L'handle del file deve avere accesso in lettura e scrittura. Penso che richieda almeno Windows 7. Non funziona su Windows 2003 x64. Windows 8 porta con successo il disco offline e quindi è possibile riscriverlo da un backup.

BOOL disk_offline(HANDLE h_file, bool enable){ 
DWORD bytes_returned = 0; 
BOOL b_offline = 0; 
if(get_size_volume_disk(h_file)){ 
    SET_DISK_ATTRIBUTES disk_attr; 
    ZeroMemory(&disk_attr, sizeof(disk_attr)); 
    disk_attr.Version = sizeof(SET_DISK_ATTRIBUTES); 
    disk_attr.Attributes = enable? DISK_ATTRIBUTE_OFFLINE: 0; 
    disk_attr.AttributesMask = DISK_ATTRIBUTE_OFFLINE; 
    b_offline = DeviceIoControl(h_file, IOCTL_DISK_SET_DISK_ATTRIBUTES, &disk_attr, disk_attr.Version, NULL, 0, &bytes_returned, NULL); 
    // Invalidates the cached partition table and re-enumerates the device. 
    if(!enable) BOOL b_update = DeviceIoControl(h_file, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &bytes_returned, NULL); 
} 
return b_offline; 
} 
0

Uso DeviceIoControl e IOCTL_DISK_IS_WRITABLE codice di controllo, è possibile controllare se il disco è scrivibile. Se il disco è offline, restituisce false.Ciò significa che è possibile determinare se il disco è offline e funziona correttamente con Windows 2003 e successivi. Tuttavia, non sono riuscito a trovare alcun IOCTL utile per portare il disco online su Windows 2003. IOCTL_DISK_SET_DISK_ATTRIBUTES funziona solo con Windows 2008 e successivi.

Problemi correlati