MatthewKing / DeviceId

A simple library providing functionality to generate a 'device ID' that can be used to uniquely identify a computer.
MIT License
722 stars 118 forks source link

DeviceId doesn't work in docker for Windows containers. #64

Open jo185104 opened 1 year ago

jo185104 commented 1 year ago

Hello,

we use DeviceId in docker. It works in a Linux container, but not in a Windows container. You support AddDockerContainerId for DeviceId.Linux in the README file. Do you also support Windows containers?

I found the problem where it fails is on this line: https://github.com/MatthewKing/DeviceId/blob/6be01e121f8247203fda38255272c2dcca229bf4/src/DeviceId.Windows.Wmi/Components/WmiSystemDriveSerialNumberDeviceIdComponent.cs#L23

Environment.SpecialFolder.System returns "System" Environment.GetFolderPath(Environment.SpecialFolder.System) returns an empty string so Substring(0, 2) fails.

Failure with this code:

string deviceId = new DeviceIdBuilder()
    .OnWindows(windows => windows
        .AddProcessorId()
        .AddMotherboardSerialNumber()
        .AddSystemDriveSerialNumber()
        .AddSystemUuid())
    .OnLinux(linux => linux
        .AddCpuInfo()
        .AddMotherboardSerialNumber()
        .AddSystemDriveSerialNumber()
        .AddMachineId())
    .AddFileToken(TokenFilePath)
    .AddMachineName()
    .ToString();

Stack Trace:

at System.String.ThrowSubstringArgumentOutOfRange(Int32 startIndex, Int32 length) in /_/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs:line 1878\r\n   
at System.String.Substring(Int32 startIndex, Int32 length) in /_/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs:line 1852\r\n  
at DeviceId.Windows.Wmi.Components.WmiSystemDriveSerialNumberDeviceIdComponent.GetValue() in /_/src/DeviceId.Windows.Wmi/Components/WmiSystemDriveSerialNumberDeviceIdComponent.cs:line 23\r\n
at DeviceId.Formatters.HashDeviceIdFormatter.<>c.<GetDeviceId>b__3_1(KeyValuePair`2 x) in /_/src/DeviceId/Formatters/HashDeviceIdFormatter.cs:line 47\r\n  
at System.Linq.Enumerable.SelectIPartitionIterator`2.PreallocatingToArray(Int32 count) in /_/src/libraries/System.Linq/src/System/Linq/Select.SpeedOpt.cs:line 606\r\n  
at System.Linq.Enumerable.SelectIPartitionIterator`2.ToArray() in /_/src/libraries/System.Linq/src/System/Linq/Select.SpeedOpt.cs:line 620\r\n   
at DeviceId.Formatters.HashDeviceIdFormatter.GetDeviceId(IDictionary`2 components) in /_/src/DeviceId/Formatters/HashDeviceIdFormatter.cs:line 47\r\n   
at DeviceId.DeviceIdBuilder.ToString() in /_/src/DeviceId/DeviceIdBuilder.cs:line 54\r\n  

Probably the same problem here: https://github.com/MatthewKing/DeviceId/blob/9c8124579fc1a075df7ff2d26e73412d6ec6af58/src/DeviceId.Windows.Mmi/Components/MmiSystemDriveSerialNumberDeviceIdComponent.cs#L22

Thank you in advance for your feedback.

jo185104 commented 1 year ago

It looks like the problem is in the dotnet runtime. I had installed .NET SDK 7.0.102. When I updated it to the current version .NET SDK 7.0.200 the problem still exists. It seems to me that they have problems with this call over the years.

https://github.com/dotnet/runtime/issues/21430#issuecomment-1160762782

MatthewKing commented 1 year ago

Good catch, and great issue report, thanks. I'll push out an immediate fix for the unexpected exception, and pencil in some future investigation to find a proper workaround.