1717 */
1818package org .jackhuang .hmcl .util .platform .windows ;
1919
20- import com .google .gson .stream .JsonReader ;
21- import com .google .gson .stream .JsonToken ;
20+ import org .jackhuang .hmcl .util .Lang ;
2221import org .jackhuang .hmcl .util .StringUtils ;
23- import org .jackhuang .hmcl .util .gson .JsonUtils ;
24- import org .jackhuang .hmcl .util .io .FileUtils ;
2522import org .jackhuang .hmcl .util .platform .OperatingSystem ;
2623import org .jackhuang .hmcl .util .platform .hardware .GraphicsCard ;
2724import org .jackhuang .hmcl .util .platform .hardware .HardwareDetector ;
2825import org .jetbrains .annotations .NotNull ;
2926
27+ import java .io .BufferedReader ;
3028import java .io .File ;
3129import java .io .IOException ;
32- import java .io .StringReader ;
33- import java .nio .charset .StandardCharsets ;
3430import java .nio .file .Files ;
3531import java .nio .file .Path ;
36- import java .util .ArrayList ;
37- import java .util .Collections ;
38- import java .util .List ;
32+ import java .util .*;
3933import java .util .concurrent .TimeUnit ;
4034import java .util .concurrent .TimeoutException ;
4135
4640 */
4741public final class WindowsHardwareDetector extends HardwareDetector {
4842
49- private static final class Win32_VideoController {
50- String Name ;
51- String AdapterCompatibility ;
52- String DriverVersion ;
53- String AdapterDACType ;
43+ private static List <Map <String , String >> parsePowerShellFormatList (Iterable <String > lines ) {
44+ ArrayList <Map <String , String >> result = new ArrayList <>();
45+ Map <String , String > current = new LinkedHashMap <>();
46+
47+ for (String line : lines ) {
48+ int idx = line .indexOf (':' );
49+
50+ if (idx < 0 ) {
51+ if (!current .isEmpty ()) {
52+ result .add (current );
53+ current = new LinkedHashMap <>();
54+ }
55+ continue ;
56+ }
57+
58+ String key = line .substring (0 , idx ).trim ();
59+ String value = line .substring (idx + 1 ).trim ();
60+
61+ current .put (key , value );
62+ }
63+
64+ if (!current .isEmpty ())
65+ result .add (current );
66+
67+ return result ;
5468 }
5569
5670 @ Override
@@ -60,17 +74,20 @@ private static final class Win32_VideoController {
6074
6175 Path tempFile = null ;
6276 Process process = null ;
63- String json = null ;
6477 try {
65- tempFile = Files .createTempFile ("hmcl-video-controllers-" , ".json " ).toAbsolutePath ().normalize ();
78+ tempFile = Files .createTempFile ("hmcl-video-controllers-" , ".txt " ).toAbsolutePath ().normalize ();
6679 File nul = new File ("NUL" );
6780
81+ String getCimInstance = OperatingSystem .SYSTEM_VERSION .startsWith ("6.1" )
82+ ? "Get-WmiObject"
83+ : "Get-CimInstance" ;
84+
6885 process = new ProcessBuilder ("powershell.exe" ,
6986 "-Command" ,
7087 String .join (" | " ,
71- "Get-CimInstance -Class Win32_VideoController" ,
88+ getCimInstance + " -Class Win32_VideoController" ,
7289 "Select-Object Name,AdapterCompatibility,DriverVersion,AdapterDACType" ,
73- "ConvertTo-Json " ,
90+ "Format-List " ,
7491 "Out-File -Encoding utf8 -FilePath '" + tempFile + "'"
7592 ))
7693 .redirectInput (nul )
@@ -84,36 +101,25 @@ private static final class Win32_VideoController {
84101 if (process .exitValue () != 0 )
85102 throw new IOException ("Bad exit code: " + process .exitValue ());
86103
87- byte [] bytes = Files .readAllBytes (tempFile );
88- if (bytes .length >= 3
89- && bytes [0 ] == (byte ) 0xef
90- && bytes [1 ] == (byte ) 0xbb
91- && bytes [2 ] == (byte ) 0xbf ) // skip bom
92- json = new String (bytes , 3 , bytes .length - 3 , StandardCharsets .UTF_8 );
93- else
94- json = new String (bytes , StandardCharsets .UTF_8 );
95-
96- json = FileUtils .readText (tempFile );
97-
98- JsonReader reader = new JsonReader (new StringReader (json ));
99- List <Win32_VideoController > videoControllers ;
100- JsonToken firstToken = reader .peek ();
101- if (firstToken == JsonToken .BEGIN_ARRAY )
102- videoControllers = JsonUtils .GSON .fromJson (reader , JsonUtils .listTypeOf (Win32_VideoController .class ));
103- else if (firstToken == JsonToken .BEGIN_OBJECT )
104- videoControllers = Collections .singletonList (JsonUtils .GSON .fromJson (reader , Win32_VideoController .class ));
105- else
106- return Collections .emptyList ();
104+ List <Map <String , String >> videoControllers ;
105+ try (BufferedReader reader = Files .newBufferedReader (tempFile )) {
106+ videoControllers = parsePowerShellFormatList (Lang .toIterable (reader .lines ()));
107+ }
107108
108109 ArrayList <GraphicsCard > cards = new ArrayList <>(videoControllers .size ());
109- for (Win32_VideoController videoController : videoControllers ) {
110- if (videoController != null && videoController .Name != null ) {
111- cards .add (GraphicsCard .builder ().setName (videoController .Name )
112- .setVendor (GraphicsCard .Vendor .of (videoController .AdapterCompatibility ))
113- .setDriverVersion (videoController .DriverVersion )
114- .setType (StringUtils .isBlank (videoController .AdapterDACType )
115- || "Internal" .equalsIgnoreCase (videoController .AdapterDACType )
116- || "InternalDAC" .equalsIgnoreCase (videoController .AdapterDACType )
110+ for (Map <String , String > videoController : videoControllers ) {
111+ String name = videoController .get ("Name" );
112+ String adapterCompatibility = videoController .get ("AdapterCompatibility" );
113+ String driverVersion = videoController .get ("DriverVersion" );
114+ String adapterDACType = videoController .get ("AdapterDACType" );
115+
116+ if (StringUtils .isNotBlank (name )) {
117+ cards .add (GraphicsCard .builder ().setName (name )
118+ .setVendor (GraphicsCard .Vendor .of (adapterCompatibility ))
119+ .setDriverVersion (driverVersion )
120+ .setType (StringUtils .isBlank (adapterDACType )
121+ || "Internal" .equalsIgnoreCase (adapterDACType )
122+ || "InternalDAC" .equalsIgnoreCase (adapterDACType )
117123 ? GraphicsCard .Type .Integrated
118124 : GraphicsCard .Type .Discrete )
119125 .build ()
@@ -125,8 +131,7 @@ else if (firstToken == JsonToken.BEGIN_OBJECT)
125131 } catch (Throwable e ) {
126132 if (process != null && process .isAlive ())
127133 process .destroy ();
128-
129- LOG .warning ("Failed to get graphics card info" + (json != null ? ": " + json : "" ), e );
134+ LOG .warning ("Failed to get graphics card info" , e );
130135 return Collections .emptyList ();
131136 } finally {
132137 try {
0 commit comments