성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] 그냥 RSS Reader 기능과 약간의 UI 편의성 때문에 사용...
[이종효] 오래된 소프트웨어는 보안 위협이 되기도 합니다. 혹시 어떤 기능...
[정성태] @Keystroke IEEE의 문서를 소개해 주시다니... +_...
[손민수 (Keystroke)] 괜히 듀얼채널 구성할 때 한번에 같은 제품 사라고 하는 것이 아...
[정성태] 전각(Full-width)/반각(Half-width) 기능을 토...
[정성태] Vector에 대한 내용은 없습니다. Vector가 닷넷 BCL...
[orion] 글 읽고 찾아보니 디자인 타임에는 InitializeCompon...
[orion] 연휴 전에 재현 프로젝트 올리자 생각해 놓고 여의치 않아서 못 ...
[정성태] 아래의 글에 정리했으니 참고하세요. C# - Typed D...
[정성태] 간단한 재현 프로젝트라도 있을까요? 저런 식으로 설명만 해...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>C# - WMI 논리 디스크가 속한 물리 디스크의 정보를 얻는 방법</h1> <p> 다음과 같은 질문이 있군요. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 드라이브 문자를 통해서 물리 디스크 명칭을 알아내고 싶습니다. ; <a target='tab' href='https://www.sysnet.pe.kr/3/0/5803'>https://www.sysnet.pe.kr/3/0/5803</a> </pre> <br /> 윈도우에서 "drive"는 논리적인 디스크 정보에 해당합니다. 즉, "물리적인 하드 디스크"를 1개 구매해서, 거기에 3개의 파티션을 나눈 다음 각각 C, D, E 드라이브 문자를 할당할 수 있는데요, 그런 경우 다음과 같이 정리할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 물리 디스크 0 논리 디스크 0 - C 논리 디스크 1 - D 논리 디스크 2 - E </pre> <br /> 그러니까, 논리 디스크 자체에는 <a target='tab' href='https://www.sysnet.pe.kr/2/0/10913'>물리 디스크</a>의 Serial number를 확인할 수 없습니다. 그것을 확인하기 위해서는 논리 디스크가 속한 물리 디스크를 먼저 구하는 선행 작업이 필요합니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 결국 문제는, 논리 디스크(<a target='tab' href='https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-logicaldisk'>Win32_LogicalDisk</a>)와 물리 디스크의 관계를 연결할 수 있는 접점이 필요한 건데요, 이에 대해서는 다음의 Q&A에서 잘 설명하고 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > WMI Association of LogicalDisk with DiskPartition ; <a target='tab' href='https://stackoverflow.com/questions/48116174/wmi-association-of-logicaldisk-with-diskpartition'>https://stackoverflow.com/questions/48116174/wmi-association-of-logicaldisk-with-diskpartition</a> </pre> <br /> 위의 글에서 설명하듯이, 논리 디스크 정보에 포함된 "VolumeSerialNumber" 고윳값이 <a target='tab' href='https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-diskdrivetodiskpartition'>Win32_DiskDriveToDiskPartition</a>을 통해 물리 디스크 정보인 <a target='tab' href='https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-diskdrive'>Win32_DiskDrive</a>에 대한 교각 역할을 합니다.<br /> <br /> 따라서 다음과 같이 코딩을 하면,<br /> <br /> <pre style='height: 400px; margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > using System.Management; using System.Runtime.Versioning; using ConsoleApp1; [assembly: SupportedOSPlatform("windows")] // Install-Package System.Management internal class Program { static void Main(string[] args) { List<Win32_DiskDrive> physicalDisks = GetPhysicalDiskList(); foreach (Win32_LogicalDisk drive in GetLogicalDiskList()) { Console.WriteLine($"{nameof(drive.DeviceID)}: {drive.DeviceID}"); Console.WriteLine($"{nameof(drive.VolumeSerialNumber)}: {drive.VolumeSerialNumber}"); drive.PhysicalDisk = physicalDisks.Find(disk => disk.Partitions.Find(partition => partition.VolumeSerialNumber == drive.VolumeSerialNumber) != null); if (drive.PhysicalDisk != null) { Console.WriteLine($"{nameof(drive.PhysicalDisk.SerialNumber)}: {drive.PhysicalDisk.SerialNumber}"); Console.WriteLine($"{nameof(drive.PhysicalDisk.DeviceID)}: {drive.PhysicalDisk.DeviceID}"); } Console.WriteLine(); } } public static List<Win32_LogicalDisk> GetLogicalDiskList() { List<Win32_LogicalDisk> drives = new List<Win32_LogicalDisk>(); try { ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_LogicalDisk"); foreach (ManagementObject queryObj in searcher.Get()) { Win32_LogicalDisk item = new Win32_LogicalDisk(); item.Caption = queryObj.GetAsString("Caption"); item.Description = queryObj.GetAsString("Description"); item.DeviceID = queryObj.GetAsString("DeviceID"); item.Name = queryObj.GetAsString("Name"); item.VolumeName = queryObj.GetAsString("VolumeName"); item.VolumeSerialNumber = queryObj.GetAsString("VolumeSerialNumber"); drives.Add(item); } } catch (ManagementException) { } return drives; } public static List<Win32_DiskDrive> GetPhysicalDiskList() { List<Win32_DiskDrive> drives = new List<Win32_DiskDrive>(); try { ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_DiskDrive"); foreach (ManagementObject queryObj in searcher.Get()) { Win32_DiskDrive item = new Win32_DiskDrive(); item.DeviceID = queryObj.GetAsString("DeviceID"); item.Caption = queryObj.GetAsString("Caption"); item.Description = queryObj.GetAsString("Description"); item.Index = queryObj.GetAsUInt32("Index"); item.SerialNumber = queryObj.GetAsString("SerialNumber").Trim(); item.PNPDeviceID = queryObj.GetAsString("PNPDeviceID"); ListPartitions(item); drives.Add(item); } } catch (ManagementException) { } return drives; } // <a target='tab' href='https://stackoverflow.com/questions/48116174/wmi-association-of-logicaldisk-with-diskpartition'>https://stackoverflow.com/questions/48116174/wmi-association-of-logicaldisk-with-diskpartition</a> private static void ListPartitions(Win32_DiskDrive drive) { string assocQuery = $"Associators of {{Win32_DiskDrive.DeviceID='{drive.DeviceID}'}} where AssocClass=Win32_DiskDriveToDiskPartition"; var assocPart = new ManagementObjectSearcher(assocQuery); assocPart.Options.Timeout = System.Management.EnumerationOptions.InfiniteTimeout; foreach (ManagementObject moPart in assocPart.Get()) { string logDiskQuery = $"Associators of {{Win32_DiskPartition.DeviceID='{moPart.Properties["DeviceID"].Value.ToString()}'}} where AssocClass=Win32_LogicalDiskToPartition"; var logDisk = new ManagementObjectSearcher(logDiskQuery); logDisk.Options.Timeout = System.Management.EnumerationOptions.InfiniteTimeout; foreach (var logDiskEnu in logDisk.Get()) { Win32_DiskDriveToDiskPartition partition = new Win32_DiskDriveToDiskPartition(); partition.VolumeSerialNumber = logDiskEnu.GetAsString("VolumeSerialNumber"); drive.Partitions.Add(partition); } } } } public class Win32_LogicalDisk { public string Caption = ""; public string Description = ""; public string DeviceID = ""; public string Name = ""; public string VolumeName = ""; public string VolumeSerialNumber = ""; public Win32_DiskDrive? PhysicalDisk; } public class Win32_DiskDrive { public string DeviceID = ""; public string Caption = ""; public string Description = ""; public uint Index; public string SerialNumber = ""; public string PNPDeviceID = ""; public List<Win32_DiskDriveToDiskPartition> Partitions = new List<Win32_DiskDriveToDiskPartition>(); } public class Win32_DiskDriveToDiskPartition { public string VolumeSerialNumber = ""; } </pre> <br /> 실행 시 이와 같은 결과가 나옵니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Ligical-DeviceID: C: VolumeSerialNumber: C54B0E7F SerialNumber: 0015_4222_153C_557E. Physical-DeviceID: \\.\PHYSICALDRIVE1 Ligical-DeviceID: D: VolumeSerialNumber: D29D0282 SerialNumber: 0015_4222_153C_5562. Physical-DeviceID: \\.\PHYSICALDRIVE2 Ligical-DeviceID: E: VolumeSerialNumber: A8A69CBD SerialNumber: 0015_4222_153C_5562. Physical-DeviceID: \\.\PHYSICALDRIVE2 Ligical-DeviceID: F: VolumeSerialNumber: 38C805A0 SerialNumber: WD-WXT1DC0JKWHY Physical-DeviceID: \\.\PHYSICALDRIVE0 </pre> <br /> 실제로 해당 시스템에 설치된 물리 디스크에 따른 디스크 정보는 아래와 같은 상황입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 물리 디스크 - PHYSICALDRIVE0 논리 디스크 F: 물리 디스크 - PHYSICALDRIVE1 논리 디스크 C: 물리 디스크 - PHYSICALDRIVE2 논리 디스크 D: 논리 디스크 E: </pre> <br /> (<a target='tab' href='https://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=2011&boardid=331301885'>첨부 파일은 이 글의 예제 코드를 포함</a>합니다.)<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
3570
(왼쪽의 숫자를 입력해야 합니다.)