diff --git a/jlib/win32/duireg.h b/jlib/win32/duireg.h
new file mode 100644
index 0000000000000000000000000000000000000000..113643de0e77eb08ff26feb34caf87d638a620fb
--- /dev/null
+++ b/jlib/win32/duireg.h
@@ -0,0 +1,72 @@
+#pragma once
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#include <intrin.h>
+#include <string>
+#include <array>
+#include <vector>
+
+// device unique identifier by registry
+
+namespace jlib {
+namespace win32 {
+namespace duireg {
+
+// https://docs.microsoft.com/en-us/cpp/intrinsics/cpuid-cpuidex?view=msvc-160
+inline std::string cpu_id() {
+    std::array<int, 4> cpui;
+    std::vector<std::array<int, 4>> data_;
+
+    __cpuid(cpui.data(), 0);
+    int nIds_ = cpui[0];
+
+    for (int i = 0; i <= nIds_; ++i) {
+        __cpuidex(cpui.data(), i, 0);
+        data_.push_back(cpui);
+    }
+
+    char serialnumber[0x14] = { 0 };
+    sprintf_s(serialnumber, sizeof(serialnumber), "%08X%08X", data_[1][3], data_[1][0]);
+    return serialnumber;
+}
+
+// CPU 型号
+inline std::string cpu_model_name() {
+    HKEY hkey;
+    if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, R"(HARDWARE\DESCRIPTION\System\CentralProcessor\0)", 0, KEY_READ, &hkey))
+        return {};
+
+    char identifier[128] = { 0 };
+    DWORD identifier_len = sizeof(identifier);
+    LPBYTE lpdata = static_cast<LPBYTE>(static_cast<void*>(&identifier[0]));
+    if (RegQueryValueExA(hkey, "ProcessorNameString", nullptr, nullptr, lpdata, &identifier_len)) {
+        RegCloseKey(hkey);
+        return {};
+    }
+    RegCloseKey(hkey);
+    return identifier;
+}
+
+// 主板型号
+inline std::string baseboard_product() {
+    HKEY hkey;
+    if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, R"(HARDWARE\DESCRIPTION\System\BIOS)", 0, KEY_READ, &hkey))
+        return {};
+
+    char identifier[128] = { 0 };
+    DWORD identifier_len = sizeof(identifier);
+    LPBYTE lpdata = static_cast<LPBYTE>(static_cast<void*>(&identifier[0]));
+    if (RegQueryValueExA(hkey, "BaseBoardProduct", nullptr, nullptr, lpdata, &identifier_len)) {
+        RegCloseKey(hkey);
+        return {};
+    }
+    RegCloseKey(hkey);
+    return identifier;
+}
+
+}
+}
+}
diff --git a/jlib/win32/info/baseboard.cpp b/jlib/win32/info/baseboard.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f64e2ac93ad05974012abf102fa801a43c0875cc
--- /dev/null
+++ b/jlib/win32/info/baseboard.cpp
@@ -0,0 +1,61 @@
+#include "baseboard.h"
+#include "../wmi.h"
+#include "../UnicodeTool.h"
+
+namespace jlib {
+namespace win32 {
+namespace info {
+namespace baseboard {
+
+static std::string BIOS_get_value(const char* key)
+{
+    HKEY hkey;
+    if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, R"(HARDWARE\DESCRIPTION\System\BIOS)", 0, KEY_READ, &hkey))
+        return {};
+
+    char value[4096] = { 0 };
+    DWORD value_len = sizeof(value);
+    LPBYTE lpdata = static_cast<LPBYTE>(static_cast<void*>(&value[0]));
+    if (RegQueryValueExA(hkey, key, nullptr, nullptr, lpdata, &value_len)) {
+        RegCloseKey(hkey);
+        return {};
+    }
+    RegCloseKey(hkey);
+    return value;
+}
+
+std::string manufacturer()
+{
+    return BIOS_get_value("BaseBoardManufacturer");
+}
+
+std::string product()
+{
+    return BIOS_get_value("BaseBoardProduct");
+}
+
+std::string serial()
+{
+    wmi::Result result;
+    if (wmi::WmiBase::simpleSelect({ L"SerialNumber" }, L"Win32_BaseBoard", L"", result) && result.size() == 1) {
+        auto serial = result[0][L"SerialNumber"];
+        return utf16_to_mbcs(serial);
+    }
+    return std::string();
+}
+
+std::string bios_serial()
+{
+    wmi::Result result;
+    if (wmi::WmiBase::simpleSelect({ L"SerialNumber" }, L"Win32_BIOS", L"", result) && result.size() == 1) {
+        auto serial = result[0][L"SerialNumber"];
+    }
+    return std::string();
+}
+
+
+
+}
+}
+}
+}
diff --git a/jlib/win32/info/baseboard.h b/jlib/win32/info/baseboard.h
new file mode 100644
index 0000000000000000000000000000000000000000..91ef24451dee9e0c483d7d3d53486fcebbe7355e
--- /dev/null
+++ b/jlib/win32/info/baseboard.h
@@ -0,0 +1,26 @@
+#pragma once
+
+
+#include "def.h"
+#include <string>
+#include <cstdint>
+
+namespace jlib {
+namespace win32 {
+namespace info {
+namespace baseboard {
+
+// like: ASUSTeK COMPUTER INC.
+JINFO_API std::string manufacturer();
+// like: ROG STRIX B360-F GAMING
+JINFO_API std::string product();
+// like: "190449658701311" or "Default string" or "To be filled by O.E.M." or "None"
+JINFO_API std::string serial();
+// like: "416096H316A6240134" or "System Serial Number" or "To be filled by O.E.M."
+JINFO_API std::string bios_serial();
+
+
+}
+}
+}
+}
diff --git a/jlib/win32/info/cpu.cpp b/jlib/win32/info/cpu.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..46353dac3abcae679d4a15f2c5af43875aff65c9
--- /dev/null
+++ b/jlib/win32/info/cpu.cpp
@@ -0,0 +1,134 @@
+#include "cpu.h"
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <intrin.h>
+#include <bitset>
+#include <array>
+#include <vector>
+
+
+namespace jlib {
+namespace win32 {
+namespace info {
+namespace cpu {
+
+struct cpu_id_helper {
+    std::string vendor_;
+    std::string brand_;
+    std::string cpuid_;
+
+	cpu_id_helper() {
+        //int cpuInfo[4] = {-1};
+        std::array<int, 4> cpui;
+        std::vector<std::array<int, 4>> data_;
+        std::vector<std::array<int, 4>> extdata_;
+
+        // Calling __cpuid with 0x0 as the function_id argument
+        // gets the number of the highest valid function ID.
+        __cpuid(cpui.data(), 0);
+        int nIds_ = cpui[0];
+        for (int i = 0; i <= nIds_; ++i) {
+            __cpuidex(cpui.data(), i, 0);
+            data_.push_back(cpui);
+        }
+
+        // Capture vendor string
+        char vendor[0x20];
+        memset(vendor, 0, sizeof(vendor));
+        *reinterpret_cast<int*>(vendor) = data_[0][1];
+        *reinterpret_cast<int*>(vendor + 4) = data_[0][3];
+        *reinterpret_cast<int*>(vendor + 8) = data_[0][2];
+        vendor_ = vendor;
+
+        char vendor_serialnumber[0x14] = { 0 };
+        sprintf_s(vendor_serialnumber, sizeof(vendor_serialnumber), "%08X%08X", data_[1][3], data_[1][0]);
+        cpuid_ = vendor_serialnumber;
+
+        // Calling __cpuid with 0x80000000 as the function_id argument
+        // gets the number of the highest valid extended ID.
+        __cpuid(cpui.data(), 0x80000000);
+        int nExIds_ = cpui[0];
+
+        char brand[0x40];
+        memset(brand, 0, sizeof(brand));
+
+        for (int i = 0x80000000; i <= nExIds_; ++i) {
+            __cpuidex(cpui.data(), i, 0);
+            extdata_.push_back(cpui);
+        }
+
+        // Interpret CPU brand string if reported
+        if (nExIds_ >= 0x80000004) {
+            memcpy(brand, extdata_[2].data(), sizeof(cpui));
+            memcpy(brand + 16, extdata_[3].data(), sizeof(cpui));
+            memcpy(brand + 32, extdata_[4].data(), sizeof(cpui));
+            brand_ = brand;
+        }
+	}
+};
+
+static const cpu_id_helper cpu_id_helper_;
+
+Architecture architecture() noexcept
+{
+	SYSTEM_INFO si;
+    GetNativeSystemInfo(&si);
+	switch (si.wProcessorArchitecture) 	{
+	case PROCESSOR_ARCHITECTURE_INTEL: return Architecture::x86;
+	case PROCESSOR_ARCHITECTURE_AMD64: return Architecture::x64;
+	case PROCESSOR_ARCHITECTURE_ARM:   return Architecture::arm;
+	case PROCESSOR_ARCHITECTURE_ARM64: return Architecture::arm64;
+	case PROCESSOR_ARCHITECTURE_IA64:  return Architecture::ia64;
+	}
+	return Architecture::unknown;
+}
+
+std::string architecture_to_string(Architecture arch)
+{
+    switch (arch) 	{
+    case jlib::win32::info::cpu::Architecture::x86: return "x86";
+    case jlib::win32::info::cpu::Architecture::x64: return "x64";
+    case jlib::win32::info::cpu::Architecture::arm: return "ARM";
+    case jlib::win32::info::cpu::Architecture::arm64: return "ARM64";
+    case jlib::win32::info::cpu::Architecture::ia64: return "IA64";
+    case jlib::win32::info::cpu::Architecture::unknown:
+    default: return "unknown architecture";
+    }
+}
+
+std::string cpu_id()
+{
+    return cpu_id_helper_.cpuid_;
+}
+
+std::string vendor()
+{
+	return cpu_id_helper_.vendor_;
+}
+
+std::string brand()
+{
+	return cpu_id_helper_.brand_;
+}
+
+std::string brand_registry()
+{
+    HKEY hkey;
+    if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, R"(HARDWARE\DESCRIPTION\System\CentralProcessor\0)", 0, KEY_READ, &hkey))
+        return {};
+
+    char identifier[256] = { 0 };
+    DWORD identifier_len = sizeof(identifier);
+    LPBYTE lpdata = static_cast<LPBYTE>(static_cast<void*>(&identifier[0]));
+    if (RegQueryValueExA(hkey, "ProcessorNameString", nullptr, nullptr, lpdata, &identifier_len)) {
+        RegCloseKey(hkey);
+        return {};
+    }
+    RegCloseKey(hkey);
+    return identifier;
+}
+
+}
+}
+}
+}
diff --git a/jlib/win32/info/cpu.h b/jlib/win32/info/cpu.h
new file mode 100644
index 0000000000000000000000000000000000000000..99c278c04612469f91b33cf75d97c1b6cb64b1c6
--- /dev/null
+++ b/jlib/win32/info/cpu.h
@@ -0,0 +1,104 @@
+#pragma once
+
+#include "def.h"
+#include <string>
+#include <cstdint>
+
+namespace jlib {
+namespace win32 {
+namespace info {
+namespace cpu {
+
+enum class Architecture {
+	x86,
+	x64,	// AMD or Intel
+	arm,		
+	arm64,		
+	ia64,	// Intel Itanium-based
+	unknown,
+};
+
+struct Quantity {
+
+};
+
+JINFO_API Architecture architecture() noexcept;
+JINFO_API std::string architecture_to_string(Architecture arch);
+
+
+// like BFEBFBFF000906EA, read from __cpuid
+JINFO_API std::string cpu_id();
+
+// GenuineIntel or AuthenticAMD
+JINFO_API std::string vendor();
+
+// like Intel(R) Core(TM) i5-2500 CPU @ 3.30GHz
+JINFO_API std::string brand();
+// get cpu_brand by registry
+JINFO_API std::string brand_registry();
+
+
+//namespace instruction_set_support {
+//JINFO_API bool sse3();
+//JINFO_API bool pclmulqdq();
+//JINFO_API bool monitor();
+//JINFO_API bool ssse3();
+//JINFO_API bool fma();
+//JINFO_API bool cmpxchg16b();
+//JINFO_API bool sse41();
+//JINFO_API bool sse42();
+//JINFO_API bool movbe();
+//JINFO_API bool popcnt();
+//JINFO_API bool aes();
+//JINFO_API bool xsave();
+//JINFO_API bool osxsave();
+//JINFO_API bool avx();
+//JINFO_API bool f16c();
+//JINFO_API bool rdrand();
+//
+//JINFO_API bool msr();
+//JINFO_API bool cx8();
+//JINFO_API bool sep();
+//JINFO_API bool cmov();
+//JINFO_API bool clfsh();
+//JINFO_API bool mmx();
+//JINFO_API bool fxsr();
+//JINFO_API bool sse();
+//JINFO_API bool sse2();
+//
+//JINFO_API bool fsgsbase();
+//JINFO_API bool bmi1();
+//JINFO_API bool hle();
+//JINFO_API bool avx2();
+//JINFO_API bool bmi2();
+//JINFO_API bool erms();
+//JINFO_API bool invpcid();
+//JINFO_API bool rtm();
+//JINFO_API bool avx512f();
+//JINFO_API bool rdseed();
+//JINFO_API bool adx();
+//JINFO_API bool avx512pf();
+//JINFO_API bool avx512er();
+//JINFO_API bool avx512cd();
+//JINFO_API bool sha();
+//
+//JINFO_API bool prefetchwt1();
+//
+//JINFO_API bool lahf();
+//JINFO_API bool lzcnt();
+//JINFO_API bool abm();
+//JINFO_API bool sse4a();
+//JINFO_API bool xop();
+//JINFO_API bool tbm();
+//
+//JINFO_API bool syscall();
+//JINFO_API bool mmxext();
+//JINFO_API bool rdtscp();
+//JINFO_API bool _3dnowext();
+//JINFO_API bool _3dnow();
+//}
+
+}
+}
+}
+}
diff --git a/jlib/win32/info/def.h b/jlib/win32/info/def.h
new file mode 100644
index 0000000000000000000000000000000000000000..70ba0493f1354556b58dfda325de91c1efc95189
--- /dev/null
+++ b/jlib/win32/info/def.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#if defined(_LIB) || defined(LINK_JINFO_STATIC_LIB)
+#define JINFO_API
+#else
+#ifdef JINFO_EXPORTS
+#define JINFO_API __declspec(dllexport)
+#else
+#define JINFO_API __declspec(dllimport)
+#endif
+#endif
diff --git a/jlib/win32/info/diskdrive.cpp b/jlib/win32/info/diskdrive.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..16ee22fc9bc9d8547c6252e9825cc37a1c2ed264
--- /dev/null
+++ b/jlib/win32/info/diskdrive.cpp
@@ -0,0 +1,53 @@
+#include "diskdrive.h"
+#include "../wmi.h"
+#include "../UnicodeTool.h"
+#include <algorithm>
+
+namespace jlib {
+namespace win32 {
+namespace info {
+namespace diskdrive {
+
+std::vector<DiskDrive> disk_drives()
+{
+	std::vector<DiskDrive> drives;
+
+	wmi::Result result;
+	if (wmi::WmiBase::simpleSelect({ L"DeviceID", L"Index", L"Model", L"Partitions", L"SerialNumber", L"Size", }, L"Win32_DiskDrive", L"", result)) {
+		for (auto& item : result) {
+			DiskDrive drive;
+			drive.device_id = utf16_to_mbcs(item[L"DeviceID"]);
+			drive.index = std::stoi(item[L"Index"]);
+			drive.model = utf16_to_mbcs(item[L"Model"]);
+			drive.partitions = std::stoi(item[L"Partitions"]);
+			drive.serial = utf16_to_mbcs(item[L"SerialNumber"]);
+			drive.size = std::stoull(item[L"Size"]);
+			drives.push_back(drive);
+		}
+	}
+
+	std::sort(drives.begin(), drives.end(), [](const DiskDrive& d1, const DiskDrive& d2) {
+		return d1.index < d2.index;
+	});
+
+	return drives;
+}
+
+std::string bootable_disk_serial()
+{
+	wmi::Result result;
+	if (wmi::WmiBase::simpleSelect({ L"SerialNumber", }, L"Win32_DiskDrive", L"Where Index=0", result) && result.size() == 1) {
+		return utf16_to_mbcs(result[0][L"SerialNumber"]);
+	}
+
+	auto drives = disk_drives();
+	if (!drives.empty()) {
+		return drives[0].serial;
+	}
+	return {};
+}
+
+}
+}
+}
+}
diff --git a/jlib/win32/info/diskdrive.h b/jlib/win32/info/diskdrive.h
new file mode 100644
index 0000000000000000000000000000000000000000..b28d08222134e7858f3f71167c07b710efa0b353
--- /dev/null
+++ b/jlib/win32/info/diskdrive.h
@@ -0,0 +1,29 @@
+#pragma once
+
+#include "def.h"
+#include <string>
+#include <cstdint>
+#include <vector>
+
+namespace jlib {
+namespace win32 {
+namespace info {
+namespace diskdrive {
+
+struct DiskDrive {
+	int index = 0;
+	int partitions{};
+	std::string device_id{}; // like \\.\PHYSICALDRIVE0
+	std::string model{}; // like Samsung SSD 840 EVO 250GB
+	std::string serial{};
+	std::uint64_t size{};
+};
+
+JINFO_API std::vector<DiskDrive> disk_drives();
+
+JINFO_API std::string bootable_disk_serial();
+
+}
+}
+}
+}
diff --git a/jlib/win32/info/gpu.cpp b/jlib/win32/info/gpu.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..94f2ea5419c3e22cf61bcd4d795d7b5847964bde
--- /dev/null
+++ b/jlib/win32/info/gpu.cpp
@@ -0,0 +1,28 @@
+#include "gpu.h"
+#include "../wmi.h"
+#include "../UnicodeTool.h"
+
+namespace jlib {
+namespace win32 {
+namespace info {
+namespace gpu {
+
+std::vector<Gpu> gpus()
+{
+	std::vector<Gpu> gs;
+	wmi::Result result;
+	if (wmi::WmiBase::simpleSelect({ L"AdapterRAM", L"Description" }, L"Win32_VideoController", L"", result)) {
+		for (auto&& item : result) {
+			Gpu gpu;
+			gpu.name = utf16_to_mbcs(item[L"Description"]);
+			gpu.memsz = std::stoull(item[L"AdapterRAM"]);
+			gs.push_back(gpu);
+		}
+	}
+	return gs;
+}
+
+}
+}
+}
+}
diff --git a/jlib/win32/info/gpu.h b/jlib/win32/info/gpu.h
new file mode 100644
index 0000000000000000000000000000000000000000..eb2403c10a7d58a9373f173c0ae1a845b54fec62
--- /dev/null
+++ b/jlib/win32/info/gpu.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include "def.h"
+#include <string>
+#include <cstdint>
+#include <vector>
+
+namespace jlib {
+namespace win32 {
+namespace info {
+namespace gpu {
+
+struct Gpu {
+	std::string name{};
+	std::uintmax_t memsz{};
+};
+
+JINFO_API std::vector<Gpu> gpus();
+
+}
+}
+}
+}
diff --git a/jlib/win32/info/logicaldrive.cpp b/jlib/win32/info/logicaldrive.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e19f783f61eedcd68a1ae8322e46ad39cf06d5d1
--- /dev/null
+++ b/jlib/win32/info/logicaldrive.cpp
@@ -0,0 +1,58 @@
+#include "logicaldrive.h"
+#include "../wmi.h"
+#include "../UnicodeTool.h"
+
+namespace jlib {
+namespace win32 {
+namespace info {
+namespace logicaldrive {
+
+std::string drive_type_to_string(DriveType type)
+{
+	switch (type) 	{
+	case DriveType::no_root_dir:	return "no_root_dir";
+	case DriveType::removable:		return "removable";
+	case DriveType::fixed:			return "fixed";
+	case DriveType::remote:			return "remote";
+	//case DriveType::cdrom:			return "cdrom";
+	case DriveType::ramdisk:		return "ramdisk";
+	default:						return "unkown drive type";
+	}
+}
+
+static DriveType parseDriveType(const std::wstring& str) {
+	int type = std::stoi(str);
+	switch (type) 	{
+	case DRIVE_NO_ROOT_DIR: return DriveType::no_root_dir;
+	case DRIVE_REMOVABLE:	return DriveType::removable;
+	case DRIVE_FIXED:		return DriveType::fixed;
+	case DRIVE_REMOTE:		return DriveType::remote;
+	case DRIVE_RAMDISK:		return DriveType::ramdisk;
+	default:				return DriveType::unknown;
+	}
+}
+
+std::vector<LogicalDrive> logical_drives()
+{
+	std::vector<LogicalDrive> drives;
+
+	wmi::Result result;
+	if (wmi::WmiBase::simpleSelect({ L"DeviceID", L"DriveType", L"FreeSpace", L"Size", L"VolumeName" }, L"Win32_LogicalDisk", L"where DriveType != 5", result)) {
+		for (auto&& item : result) {
+			LogicalDrive drive;
+			drive.device_id = utf16_to_mbcs(item[L"DeviceID"]);
+			drive.drive_type = parseDriveType(item[L"DriveType"]);
+			drive.free_space = std::stoull(item[L"FreeSpace"]);
+			drive.size = std::stoull(item[L"Size"]);
+			drive.volume_name = utf16_to_mbcs(item[L"VolumeName"]);
+			drives.push_back(drive);
+		}
+	}
+
+	return drives;
+}
+
+}
+}
+}
+}
diff --git a/jlib/win32/info/logicaldrive.h b/jlib/win32/info/logicaldrive.h
new file mode 100644
index 0000000000000000000000000000000000000000..5fa65e079f2ba5aac51262c54ea278675b7db440
--- /dev/null
+++ b/jlib/win32/info/logicaldrive.h
@@ -0,0 +1,38 @@
+#pragma once
+
+#include "def.h"
+#include <string>
+#include <cstdint>
+#include <vector>
+
+namespace jlib {
+namespace win32 {
+namespace info {
+namespace logicaldrive {
+
+enum class DriveType {
+	unknown,
+	no_root_dir,
+	removable,
+	fixed,
+	remote,
+	//cdrom,
+	ramdisk,
+};
+
+struct LogicalDrive {
+	std::string device_id{}; // C:, D:, ...
+	DriveType drive_type{};
+	//std::string provider_name{}; 
+	std::string volume_name{};
+	std::uint64_t free_space{};
+	std::uint64_t size{};
+};
+
+JINFO_API std::string drive_type_to_string(DriveType type);
+JINFO_API std::vector<LogicalDrive> logical_drives();
+
+}
+}
+}
+}
diff --git a/jlib/win32/info/system.cpp b/jlib/win32/info/system.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3b26830ccb25dcd9772a43bf4bebfb9521f1f188
--- /dev/null
+++ b/jlib/win32/info/system.cpp
@@ -0,0 +1,199 @@
+#include "system.h"
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#define _WIN32_DCOM
+#include <comdef.h>
+#include <Wbemidl.h>
+#include <memory>
+#include <functional>
+#include "../../util/space.h"
+#include "../UnicodeTool.h"
+#include "../wmi.h"
+
+#pragma comment(lib, "wbemuuid.lib")
+// require Api-ms-win-core-version-l1-1-0.dll
+#pragma comment(lib, "Version.lib")
+
+
+namespace jlib {
+namespace win32 {
+namespace info {
+namespace system {
+
+static std::string NT_get_value(const char* key)
+{
+	HKEY hkey;
+	if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)", 0, KEY_READ | KEY_WOW64_64KEY, &hkey))
+		return {};
+
+	char value[4096] = { 0 };
+	DWORD value_len = sizeof(value);
+	LPBYTE lpdata = static_cast<LPBYTE>(static_cast<void*>(&value[0]));
+	LSTATUS ret = RegQueryValueExA(hkey, key, nullptr, nullptr, lpdata, &value_len);
+	if (ret != ERROR_SUCCESS) {
+		RegCloseKey(hkey);
+		return {};
+	}
+	RegCloseKey(hkey);
+	return value;
+}
+
+static std::uint32_t NT_get_value_i(const char* key)
+{
+	HKEY hkey;
+	if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)", 0, KEY_READ, &hkey))
+		return {};
+
+	DWORD value{};
+	DWORD value_len = sizeof(value);
+	if (RegGetValueA(hkey, nullptr, key, RRF_RT_REG_DWORD, nullptr, &value, &value_len)) {
+		RegCloseKey(hkey);
+		return {};
+	}
+	RegCloseKey(hkey);
+	return value;
+}
+
+Memory memory() noexcept
+{
+	MEMORYSTATUSEX mem;
+	mem.dwLength = sizeof(mem);
+	if (!GlobalMemoryStatusEx(&mem))
+		return {};
+
+	return { mem.ullAvailPhys, mem.ullTotalPhys, mem.ullAvailVirtual, mem.ullTotalVirtual };
+}
+
+// Get OS (platform) version from kernel32.dll because GetVersion is deprecated in Win8+
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724439(v=vs.85).aspx
+Version kernel_version()
+{
+	std::string path;
+	path.resize(GetSystemDirectoryA(nullptr, 0) - 1);
+	GetSystemDirectoryA(&path[0], static_cast<UINT>(path.size() + 1));
+	path += "\\kernel32.dll";
+
+	const auto ver_info_len = GetFileVersionInfoSizeA(path.c_str(), nullptr);
+	auto ver_info = std::make_unique<std::uint8_t[]>(ver_info_len);
+	GetFileVersionInfoA(path.c_str(), 0, ver_info_len, ver_info.get());
+
+	VS_FIXEDFILEINFO* file_version;
+	unsigned int file_version_len;
+	VerQueryValueA(ver_info.get(), "", reinterpret_cast<void**>(&file_version), &file_version_len);
+
+	return { HIWORD(file_version->dwProductVersionMS), LOWORD(file_version->dwProductVersionMS),
+			HIWORD(file_version->dwProductVersionLS), LOWORD(file_version->dwProductVersionLS) };
+}
+
+std::string os_name()
+{
+	wmi::Result result;
+	if (wmi::WmiBase::simpleSelect({ L"Name" }, L"Win32_OperatingSystem", L"", result) && result.size() == 1) {
+		auto str = utf16_to_mbcs(result[0][L"Name"]);
+		return str.substr(0, str.find('|'));
+	}
+	return {};
+}
+
+std::string computer_name()
+{
+	const auto INFO_BUFFER_SIZE = 4096;
+	char  infoBuf[INFO_BUFFER_SIZE];
+	DWORD  bufCharCount = INFO_BUFFER_SIZE;
+
+	// Get and display the name of the computer.
+	if (GetComputerNameA(infoBuf, &bufCharCount)) {
+		return (infoBuf);
+	}
+	return {};
+}
+
+static BOOL IsWow64()
+{
+	BOOL bIsWow64 = FALSE;
+
+	typedef BOOL(WINAPI* LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
+	//IsWow64Process is not available on all supported versions of Windows.
+	//Use GetModuleHandle to get a handle to the DLL that contains the function
+	//and GetProcAddress to get a pointer to the function if available.
+
+	LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(
+		GetModuleHandle(TEXT("kernel32")), "IsWow64Process");
+
+	if (NULL != fnIsWow64Process)     {
+		if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64))         {
+			//handle error
+		}
+	}
+	return bIsWow64;
+}
+
+bool is_64bit_windows()
+{
+#if defined(_WIN64)
+	return true;  // 64-bit programs run only on Win64
+#elif defined(_WIN32)
+	return IsWow64();
+#else
+	return false; // Win64 does not support Win16
+#endif
+}
+
+OsInfo os_info()
+{
+	return { "Windows NT", os_name(), kernel_version() };
+}
+
+std::string display_version()
+{
+	return NT_get_value("DisplayVersion");
+}
+
+std::string current_build()
+{
+	return NT_get_value("CurrentBuild");
+}
+
+std::uint32_t ubr()
+{
+	return NT_get_value_i("UBR");
+}
+
+std::string os_version()
+{
+	return current_build() + "." + std::to_string(ubr());
+}
+
+std::string system_info_string()
+{
+	auto info = os_name() + " ";
+	const auto ki = kernel_version();
+	info += std::to_string(ki.major) + "."
+		+ std::to_string(ki.minor) + "."
+		+ std::to_string(ki.patch) + "."
+		+ std::to_string(ki.build_number) + " ";
+	info += is_64bit_windows() ? "64bit" : "32bit";
+	info += " Memory:";
+	info += jlib::human_readable_byte_count(memory().physical_total);
+	return info;
+}
+
+std::string product_id()
+{
+	return NT_get_value("ProductId");
+}
+
+std::string uuid()
+{
+	wmi::Result result;
+	if (wmi::WmiBase::simpleSelect({ L"UUID" }, L"Win32_ComputerSystemProduct", L"", result) && result.size() == 1) {
+		auto str = utf16_to_mbcs(result[0][L"UUID"]);
+		return str;
+	}
+	return {};
+}
+
+}
+}
+}
+}
diff --git a/jlib/win32/info/system.h b/jlib/win32/info/system.h
new file mode 100644
index 0000000000000000000000000000000000000000..725f4abbe495018b8a7fb60faa6741a1b7c2b3e3
--- /dev/null
+++ b/jlib/win32/info/system.h
@@ -0,0 +1,64 @@
+锘�#pragma once
+
+#include "def.h"
+#include <cstdint>
+#include <string>
+
+namespace jlib {
+namespace win32 {
+namespace info {
+namespace system {
+
+struct Memory {
+	std::uint64_t physical_available = 0;
+	std::uint64_t physical_total = 0;
+	std::uint64_t virtual_available = 0;
+	std::uint64_t virtual_total = 0;
+};
+
+struct Version {
+	std::uint32_t major = 0;
+	std::uint32_t minor = 0;
+	std::uint32_t patch = 0;
+	std::uint32_t build_number = 0;
+};
+
+struct OsInfo {
+	std::string name{};
+	std::string full_name{};
+	Version version{};
+};
+
+JINFO_API Memory memory() noexcept;
+JINFO_API Version kernel_version();
+// like: Microsoft Windows 7 瀹跺涵鏅€氱増
+JINFO_API std::string os_name();
+// like: DESKTOP-HK8EHO
+JINFO_API std::string computer_name();
+// check OS is 32bit or 64bit
+JINFO_API bool is_64bit_windows();
+
+// { "Windows NT", os_name(), kernel_version() }
+JINFO_API OsInfo os_info();
+
+// like 20H2
+JINFO_API std::string display_version();
+
+// like 19042
+JINFO_API std::string current_build();
+// like 867
+JINFO_API std::uint32_t ubr();
+// 19042.867
+JINFO_API std::string os_version();
+
+// one line description like:
+// Microsoft Windows 7 瀹跺涵鏅€氱増  6.1.7601.17514 32bit Memory:3.9995GiB
+JINFO_API std::string system_info_string();
+
+JINFO_API std::string product_id();
+JINFO_API std::string uuid();
+
+}
+}
+}
+}
diff --git a/jlib/win32/info/user.cpp b/jlib/win32/info/user.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7f7d0d9bea3327ccfed99424f765d11ce50cd3a6
--- /dev/null
+++ b/jlib/win32/info/user.cpp
@@ -0,0 +1,135 @@
+#include "user.h"
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h> 
+#include <lm.h>
+#include <assert.h>
+#include "../UnicodeTool.h"
+
+#pragma comment(lib, "netapi32.lib")
+
+namespace jlib {
+namespace win32 {
+namespace info {
+namespace user {
+
+
+static std::string curUserName()
+{
+	char name[UNLEN + 1];
+	DWORD len = sizeof(name);
+	if (GetUserNameA(name, &len)) {
+		return name;
+	}
+	return {};
+}
+
+std::vector<User> users()
+{
+	std::vector<User> users;
+	std::string cur_user_name = curUserName();
+
+	using User3 = LPUSER_INFO_3;
+	User3 pBuf = NULL;
+	NET_API_STATUS nStatus;
+
+	// Call the NetUserEnum function, specifying level 0; 
+	//   enumerate global user account types only.
+	//
+	do // begin do
+	{
+		User3 pTmpBuf;
+		DWORD dwLevel = 3;
+		DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH;
+		DWORD dwEntriesRead = 0;
+		DWORD dwTotalEntries = 0;
+		DWORD dwResumeHandle = 0;
+
+		LPTSTR pszServerName = NULL;
+
+		nStatus = NetUserEnum((LPCWSTR)pszServerName,
+							  dwLevel,
+							  FILTER_NORMAL_ACCOUNT, // global users
+							  (LPBYTE*)&pBuf,
+							  dwPrefMaxLen,
+							  &dwEntriesRead,
+							  &dwTotalEntries,
+							  &dwResumeHandle);
+		//
+		// If the call succeeds,
+		//
+		if ((nStatus == NERR_Success) || (nStatus == ERROR_MORE_DATA)) {
+			if ((pTmpBuf = pBuf) != NULL) {
+				//
+				// Loop through the entries.
+				//
+				for (DWORD i = 0; (i < dwEntriesRead); i++) {
+					assert(pTmpBuf != NULL);
+
+					if (pTmpBuf == NULL) {
+						fprintf(stderr, "An access violation has occurred\n");
+						break;
+					}
+
+					if (pTmpBuf->usri3_priv >= USER_PRIV_USER) {
+						auto priv = [](int p) {
+							if (p == USER_PRIV_USER) { return L"User"; }
+							if (p == USER_PRIV_ADMIN) { return L"Admin"; }
+							return L"";
+						};
+						//wprintf(L"\t--%s\t--%s\t--%s\n", pTmpBuf->usri3_name, pTmpBuf->usri3_full_name, priv(pTmpBuf->usri3_priv));
+						auto userName = utf16_to_mbcs(pTmpBuf->usri3_name);
+						/*QString user = QString("%1 %2 %3")
+							.arg(userName)
+							.arg(QString::fromWCharArray(pTmpBuf->usri3_full_name))
+							.arg(QString::fromWCharArray(priv(pTmpBuf->usri3_priv)));*/
+
+						User u = { userName, utf16_to_mbcs(pTmpBuf->usri3_full_name), utf16_to_mbcs(priv(pTmpBuf->usri3_priv)) };
+
+						if (userName == cur_user_name) {
+							//users.push_front(user);
+							users.insert(users.begin(), u);
+						} else {
+							//users.push_back(user);
+							users.push_back(u);
+						}
+					}
+					//
+					//  Print the name of the user account.
+					//
+					//wprintf(L"\t-- %s\n", pTmpBuf->usri2_name);
+
+					pTmpBuf++;
+				}
+			}
+		}
+		//
+		// Otherwise, print the system error.
+		//
+		else
+			fprintf(stderr, "A system error has occurred: %d\n", nStatus);
+		//
+		// Free the allocated buffer.
+		//
+		if (pBuf != NULL) {
+			NetApiBufferFree(pBuf);
+			pBuf = NULL;
+		}
+	}
+	// Continue to call NetUserEnum while 
+	//  there are more entries. 
+	// 
+	while (nStatus == ERROR_MORE_DATA); // end do
+										//
+										// Check again for allocated memory.
+										//
+	if (pBuf != NULL)
+		NetApiBufferFree(pBuf);
+
+	return users;
+}
+
+}
+}
+}
+}
+
diff --git a/jlib/win32/info/user.h b/jlib/win32/info/user.h
new file mode 100644
index 0000000000000000000000000000000000000000..0d58b753c921a32532d452b3f6affed591802c5f
--- /dev/null
+++ b/jlib/win32/info/user.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include "def.h"
+#include <string>
+#include <vector>
+
+namespace jlib {
+namespace win32 {
+namespace info {
+namespace user {
+
+struct User {
+	std::string name{};
+	std::string full_name{};
+	std::string privilege{};
+};
+
+JINFO_API std::vector<User> users();
+
+}
+}
+}
+}
diff --git a/jlib/win32/jinfo.h b/jlib/win32/jinfo.h
new file mode 100644
index 0000000000000000000000000000000000000000..5631de001dcef608b92e601569f31b2be2fa5095
--- /dev/null
+++ b/jlib/win32/jinfo.h
@@ -0,0 +1,11 @@
+#pragma once
+
+// all returned strings are MBCS
+
+#include "info/cpu.h"
+#include "info/gpu.h"
+#include "info/baseboard.h"
+#include "info/system.h"
+#include "info/user.h"
+#include "info/diskdrive.h"
+#include "info/logicaldrive.h"
diff --git a/jlib/win32/wmi.h b/jlib/win32/wmi.h
index ed07886319d4f71ac5a3c812abbbeae56732ad99..f2aae188099b4fa6b1702ccbbed9f9f739a19c8c 100644
--- a/jlib/win32/wmi.h
+++ b/jlib/win32/wmi.h
@@ -79,7 +79,7 @@ public:
 	* @return 鎴愬姛鎴栧け璐�
 	* @note 渚嬶細keys=["captian, key"], provider="Win32_Process", 鍒檙esult缁撴瀯搴斾负锛歔 {caption: value, key:value}, {caption: value, key:value}, ...]
 	*/
-	static bool simpleSelect(const std::vector<std::wstring>& keys, const std::wstring& provider, Result& result) {
+	static bool simpleSelect(const std::vector<std::wstring>& keys, const std::wstring& provider, const std::wstring& where, Result& result) {
 		std::vector<std::wstring> values, errors;
 		auto output = [&values](const std::wstring& key, const std::wstring& value) {
 			values.push_back(value);
@@ -94,11 +94,11 @@ public:
 			return false;
 		}
 
-		if (!wmi.execute(std::wstring(L"select ") + join(keys, std::wstring(L",")) + L" from " + provider) || !errors.empty()) {
+		if (!wmi.execute(std::wstring(L"select ") + join(keys, std::wstring(L",")) + L" from " + provider + L" " + where) || !errors.empty()) {
 			return false;
 		}
 
-		for (size_t i = 0; (i + 1) < values.size(); i += keys.size()) {
+		for (size_t i = 0; (i + keys.size()) <= values.size(); i += keys.size()) {
 			ResultItem item;
 			for (size_t j = 0; j < keys.size(); j++) {
 				item.insert({ keys.at(j % keys.size()), values.at(i + j) });				
diff --git a/test/jinfo/dllmain.cpp b/test/jinfo/dllmain.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..638333a18a8f242fd9e704e0a6e608ea6a80e353
--- /dev/null
+++ b/test/jinfo/dllmain.cpp
@@ -0,0 +1,19 @@
+// dllmain.cpp : Defines the entry point for the DLL application.
+#include "framework.h"
+
+BOOL APIENTRY DllMain( HMODULE hModule,
+                       DWORD  ul_reason_for_call,
+                       LPVOID lpReserved
+                     )
+{
+    switch (ul_reason_for_call)
+    {
+    case DLL_PROCESS_ATTACH:
+    case DLL_THREAD_ATTACH:
+    case DLL_THREAD_DETACH:
+    case DLL_PROCESS_DETACH:
+        break;
+    }
+    return TRUE;
+}
+
diff --git a/test/jinfo/framework.h b/test/jinfo/framework.h
new file mode 100644
index 0000000000000000000000000000000000000000..54b83e94fd330dce07fdad560a0101140e0989a3
--- /dev/null
+++ b/test/jinfo/framework.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
+// Windows Header Files
+#include <windows.h>
diff --git a/test/jinfo/jinfo.vcxproj b/test/jinfo/jinfo.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..0e6d6d48accbc3643a28bcf3677c791fca40e794
--- /dev/null
+++ b/test/jinfo/jinfo.vcxproj
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <VCProjectVersion>16.0</VCProjectVersion>
+    <Keyword>Win32Proj</Keyword>
+    <ProjectGuid>{7b505b49-5584-4cf7-a2bb-65cc84303b33}</ProjectGuid>
+    <RootNamespace>jinfo</RootNamespace>
+    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <TargetName>$(ProjectName)_x64</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+    <TargetName>$(ProjectName)_x64</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;_DEBUG;JINFO_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableUAC>false</EnableUAC>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;NDEBUG;JINFO_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableUAC>false</EnableUAC>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>_DEBUG;JINFO_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableUAC>false</EnableUAC>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>NDEBUG;JINFO_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableUAC>false</EnableUAC>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\jlib\win32\info\baseboard.h" />
+    <ClInclude Include="..\..\jlib\win32\info\gpu.h" />
+    <ClInclude Include="..\..\jlib\win32\info\diskdrive.h" />
+    <ClInclude Include="..\..\jlib\win32\info\logicaldrive.h" />
+    <ClInclude Include="..\..\jlib\win32\info\system.h" />
+    <ClInclude Include="..\..\jlib\win32\info\user.h" />
+    <ClInclude Include="..\..\jlib\win32\jinfo.h" />
+    <ClInclude Include="..\..\jlib\win32\info\cpu.h" />
+    <ClInclude Include="..\..\jlib\win32\info\def.h" />
+    <ClInclude Include="framework.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\jlib\win32\info\baseboard.cpp" />
+    <ClCompile Include="..\..\jlib\win32\info\cpu.cpp" />
+    <ClCompile Include="..\..\jlib\win32\info\diskdrive.cpp" />
+    <ClCompile Include="..\..\jlib\win32\info\gpu.cpp" />
+    <ClCompile Include="..\..\jlib\win32\info\logicaldrive.cpp" />
+    <ClCompile Include="..\..\jlib\win32\info\system.cpp" />
+    <ClCompile Include="..\..\jlib\win32\info\user.cpp" />
+    <ClCompile Include="dllmain.cpp" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/test/jinfo/jinfo.vcxproj.filters b/test/jinfo/jinfo.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..1994dd0e71026b2950f52c1b535f8c6b7efa4d91
--- /dev/null
+++ b/test/jinfo/jinfo.vcxproj.filters
@@ -0,0 +1,78 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+    <Filter Include="info">
+      <UniqueIdentifier>{670b86dd-7169-41ed-8dc2-31144e6b971e}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="framework.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\jlib\win32\jinfo.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\jlib\win32\info\cpu.h">
+      <Filter>info</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\jlib\win32\info\def.h">
+      <Filter>info</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\jlib\win32\info\system.h">
+      <Filter>info</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\jlib\win32\info\user.h">
+      <Filter>info</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\jlib\win32\info\logicaldrive.h">
+      <Filter>info</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\jlib\win32\info\gpu.h">
+      <Filter>info</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\jlib\win32\info\baseboard.h">
+      <Filter>info</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\jlib\win32\info\diskdrive.h">
+      <Filter>info</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="dllmain.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\jlib\win32\info\cpu.cpp">
+      <Filter>info</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\jlib\win32\info\system.cpp">
+      <Filter>info</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\jlib\win32\info\user.cpp">
+      <Filter>info</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\jlib\win32\info\logicaldrive.cpp">
+      <Filter>info</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\jlib\win32\info\gpu.cpp">
+      <Filter>info</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\jlib\win32\info\baseboard.cpp">
+      <Filter>info</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\jlib\win32\info\diskdrive.cpp">
+      <Filter>info</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/test/jinfo/jinfo.vcxproj.user b/test/jinfo/jinfo.vcxproj.user
new file mode 100644
index 0000000000000000000000000000000000000000..88a550947edbc3c5003a41726f0749201fdb6822
--- /dev/null
+++ b/test/jinfo/jinfo.vcxproj.user
@@ -0,0 +1,4 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup />
+</Project>
\ No newline at end of file
diff --git a/test/libjinfo/libjinfo.vcxproj b/test/libjinfo/libjinfo.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..8fc1365e2267ba9a9fab0c3ca4eaa9ea8313c48e
--- /dev/null
+++ b/test/libjinfo/libjinfo.vcxproj
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\jlib\win32\info\baseboard.h" />
+    <ClInclude Include="..\..\jlib\win32\info\cpu.h" />
+    <ClInclude Include="..\..\jlib\win32\info\def.h" />
+    <ClInclude Include="..\..\jlib\win32\info\diskdrive.h" />
+    <ClInclude Include="..\..\jlib\win32\info\gpu.h" />
+    <ClInclude Include="..\..\jlib\win32\info\logicaldrive.h" />
+    <ClInclude Include="..\..\jlib\win32\info\system.h" />
+    <ClInclude Include="..\..\jlib\win32\info\user.h" />
+    <ClInclude Include="..\..\jlib\win32\jinfo.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\jlib\win32\info\baseboard.cpp" />
+    <ClCompile Include="..\..\jlib\win32\info\cpu.cpp" />
+    <ClCompile Include="..\..\jlib\win32\info\diskdrive.cpp" />
+    <ClCompile Include="..\..\jlib\win32\info\gpu.cpp" />
+    <ClCompile Include="..\..\jlib\win32\info\logicaldrive.cpp" />
+    <ClCompile Include="..\..\jlib\win32\info\system.cpp" />
+    <ClCompile Include="..\..\jlib\win32\info\user.cpp" />
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <VCProjectVersion>16.0</VCProjectVersion>
+    <Keyword>Win32Proj</Keyword>
+    <ProjectGuid>{441e6793-7cda-4d51-81bd-7a38520f1c1d}</ProjectGuid>
+    <RootNamespace>libjinfo</RootNamespace>
+    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <SubSystem>
+      </SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <SubSystem>
+      </SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <SubSystem>
+      </SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <SubSystem>
+      </SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/test/libjinfo/libjinfo.vcxproj.filters b/test/libjinfo/libjinfo.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..46aa2397414c60a1e3cb45fc7f007d774e91e64e
--- /dev/null
+++ b/test/libjinfo/libjinfo.vcxproj.filters
@@ -0,0 +1,69 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\jlib\win32\jinfo.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\jlib\win32\info\baseboard.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\jlib\win32\info\cpu.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\jlib\win32\info\def.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\jlib\win32\info\diskdrive.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\jlib\win32\info\gpu.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\jlib\win32\info\logicaldrive.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\jlib\win32\info\system.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\jlib\win32\info\user.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\jlib\win32\info\baseboard.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\jlib\win32\info\cpu.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\jlib\win32\info\diskdrive.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\jlib\win32\info\gpu.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\jlib\win32\info\logicaldrive.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\jlib\win32\info\system.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\jlib\win32\info\user.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/test/libjinfo/libjinfo.vcxproj.user b/test/libjinfo/libjinfo.vcxproj.user
new file mode 100644
index 0000000000000000000000000000000000000000..88a550947edbc3c5003a41726f0749201fdb6822
--- /dev/null
+++ b/test/libjinfo/libjinfo.vcxproj.user
@@ -0,0 +1,4 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup />
+</Project>
\ No newline at end of file
diff --git a/test/libjinfomt/libjinfomt.vcxproj b/test/libjinfomt/libjinfomt.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..4b0a71d6c06f100fd3fd84fb31a4cf957537b0e1
--- /dev/null
+++ b/test/libjinfomt/libjinfomt.vcxproj
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\jlib\win32\info\baseboard.h" />
+    <ClInclude Include="..\..\jlib\win32\info\cpu.h" />
+    <ClInclude Include="..\..\jlib\win32\info\def.h" />
+    <ClInclude Include="..\..\jlib\win32\info\diskdrive.h" />
+    <ClInclude Include="..\..\jlib\win32\info\gpu.h" />
+    <ClInclude Include="..\..\jlib\win32\info\logicaldrive.h" />
+    <ClInclude Include="..\..\jlib\win32\info\system.h" />
+    <ClInclude Include="..\..\jlib\win32\info\user.h" />
+    <ClInclude Include="..\..\jlib\win32\jinfo.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\jlib\win32\info\baseboard.cpp" />
+    <ClCompile Include="..\..\jlib\win32\info\cpu.cpp" />
+    <ClCompile Include="..\..\jlib\win32\info\diskdrive.cpp" />
+    <ClCompile Include="..\..\jlib\win32\info\gpu.cpp" />
+    <ClCompile Include="..\..\jlib\win32\info\logicaldrive.cpp" />
+    <ClCompile Include="..\..\jlib\win32\info\system.cpp" />
+    <ClCompile Include="..\..\jlib\win32\info\user.cpp" />
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <VCProjectVersion>16.0</VCProjectVersion>
+    <Keyword>Win32Proj</Keyword>
+    <ProjectGuid>{e8551db0-274f-493a-88af-7383e47f49fa}</ProjectGuid>
+    <RootNamespace>libjinfomt</RootNamespace>
+    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <SubSystem>
+      </SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <SubSystem>
+      </SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <SubSystem>
+      </SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <SubSystem>
+      </SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/test/libjinfomt/libjinfomt.vcxproj.filters b/test/libjinfomt/libjinfomt.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..46aa2397414c60a1e3cb45fc7f007d774e91e64e
--- /dev/null
+++ b/test/libjinfomt/libjinfomt.vcxproj.filters
@@ -0,0 +1,69 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\jlib\win32\jinfo.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\jlib\win32\info\baseboard.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\jlib\win32\info\cpu.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\jlib\win32\info\def.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\jlib\win32\info\diskdrive.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\jlib\win32\info\gpu.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\jlib\win32\info\logicaldrive.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\jlib\win32\info\system.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\jlib\win32\info\user.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\jlib\win32\info\baseboard.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\jlib\win32\info\cpu.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\jlib\win32\info\diskdrive.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\jlib\win32\info\gpu.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\jlib\win32\info\logicaldrive.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\jlib\win32\info\system.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\jlib\win32\info\user.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/test/libjinfomt/libjinfomt.vcxproj.user b/test/libjinfomt/libjinfomt.vcxproj.user
new file mode 100644
index 0000000000000000000000000000000000000000..88a550947edbc3c5003a41726f0749201fdb6822
--- /dev/null
+++ b/test/libjinfomt/libjinfomt.vcxproj.user
@@ -0,0 +1,4 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup />
+</Project>
\ No newline at end of file
diff --git a/test/simple_libevent_server_md/simple_libevent_server_md.vcxproj b/test/simple_libevent_server_md/simple_libevent_server_md.vcxproj
index 0956314acdb815e0f5a87a762cedc3d3d5aba328..8a066d16dfaa168cca6ca9b982d1636e9f64fbe6 100644
--- a/test/simple_libevent_server_md/simple_libevent_server_md.vcxproj
+++ b/test/simple_libevent_server_md/simple_libevent_server_md.vcxproj
@@ -138,7 +138,7 @@
       <SDLCheck>true</SDLCheck>
       <PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ConformanceMode>true</ConformanceMode>
-      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
       <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
     </ClCompile>
     <Link>
@@ -155,7 +155,7 @@
       <SDLCheck>true</SDLCheck>
       <PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ConformanceMode>true</ConformanceMode>
-      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
       <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
     </ClCompile>
     <Link>
diff --git a/test/test.sln b/test/test.sln
index d35d1607c061c4da30aabbb81c78708e072f1b14..63228c7b8224a4f7b17bdd232fb70c539123a5ea 100644
--- a/test/test.sln
+++ b/test/test.sln
@@ -55,7 +55,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "win32", "win32", "{B5D9E71E
 	ProjectSection(SolutionItems) = preProject
 		..\jlib\win32\clipboard.h = ..\jlib\win32\clipboard.h
 		..\jlib\win32\deviceuniqueidentifier.h = ..\jlib\win32\deviceuniqueidentifier.h
+		..\jlib\win32\duireg.h = ..\jlib\win32\duireg.h
 		..\jlib\win32\file_op.h = ..\jlib\win32\file_op.h
+		..\jlib\win32\jinfo.h = ..\jlib\win32\jinfo.h
 		..\jlib\win32\memory_micros.h = ..\jlib\win32\memory_micros.h
 		..\jlib\win32\monitor.h = ..\jlib\win32\monitor.h
 		..\jlib\win32\MyWSAError.h = ..\jlib\win32\MyWSAError.h
@@ -344,6 +346,33 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simple_libevent_clients_md"
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_id_queue", "test_id_queue\test_id_queue.vcxproj", "{52AF7381-83F5-4425-BED2-AA8F2FE3A085}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_duireg", "test_duireg\test_duireg.vcxproj", "{8A098090-3E08-4A0C-8854-DDFBE9FF17A6}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dynamiclib", "dynamiclib", "{F77FEB9A-854F-4A03-B204-D4C9DB700C35}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "info", "info", "{D2FBAC12-7C05-4632-9A99-3E86147322CB}"
+	ProjectSection(SolutionItems) = preProject
+		..\jlib\win32\info\cpu.cpp = ..\jlib\win32\info\cpu.cpp
+		..\jlib\win32\info\cpu.h = ..\jlib\win32\info\cpu.h
+		..\jlib\win32\info\def.h = ..\jlib\win32\info\def.h
+		..\jlib\win32\info\gpu.cpp = ..\jlib\win32\info\gpu.cpp
+		..\jlib\win32\info\gpu.h = ..\jlib\win32\info\gpu.h
+		..\jlib\win32\info\logicaldrive.cpp = ..\jlib\win32\info\logicaldrive.cpp
+		..\jlib\win32\info\logicaldrive.h = ..\jlib\win32\info\logicaldrive.h
+		..\jlib\win32\info\system.cpp = ..\jlib\win32\info\system.cpp
+		..\jlib\win32\info\system.h = ..\jlib\win32\info\system.h
+		..\jlib\win32\info\user.cpp = ..\jlib\win32\info\user.cpp
+		..\jlib\win32\info\user.h = ..\jlib\win32\info\user.h
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jinfo", "jinfo\jinfo.vcxproj", "{7B505B49-5584-4CF7-A2BB-65CC84303B33}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_jinfo", "test_jinfo\test_jinfo.vcxproj", "{0E83FBE2-4696-41AD-9A5F-55B1401AB77C}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libjinfo", "libjinfo\libjinfo.vcxproj", "{441E6793-7CDA-4D51-81BD-7A38520F1C1D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libjinfomt", "libjinfomt\libjinfomt.vcxproj", "{E8551DB0-274F-493A-88AF-7383E47F49FA}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|ARM = Debug|ARM
@@ -1036,6 +1065,66 @@ Global
 		{52AF7381-83F5-4425-BED2-AA8F2FE3A085}.Release|x64.Build.0 = Release|x64
 		{52AF7381-83F5-4425-BED2-AA8F2FE3A085}.Release|x86.ActiveCfg = Release|Win32
 		{52AF7381-83F5-4425-BED2-AA8F2FE3A085}.Release|x86.Build.0 = Release|Win32
+		{8A098090-3E08-4A0C-8854-DDFBE9FF17A6}.Debug|ARM.ActiveCfg = Debug|Win32
+		{8A098090-3E08-4A0C-8854-DDFBE9FF17A6}.Debug|ARM64.ActiveCfg = Debug|Win32
+		{8A098090-3E08-4A0C-8854-DDFBE9FF17A6}.Debug|x64.ActiveCfg = Debug|x64
+		{8A098090-3E08-4A0C-8854-DDFBE9FF17A6}.Debug|x64.Build.0 = Debug|x64
+		{8A098090-3E08-4A0C-8854-DDFBE9FF17A6}.Debug|x86.ActiveCfg = Debug|Win32
+		{8A098090-3E08-4A0C-8854-DDFBE9FF17A6}.Debug|x86.Build.0 = Debug|Win32
+		{8A098090-3E08-4A0C-8854-DDFBE9FF17A6}.Release|ARM.ActiveCfg = Release|Win32
+		{8A098090-3E08-4A0C-8854-DDFBE9FF17A6}.Release|ARM64.ActiveCfg = Release|Win32
+		{8A098090-3E08-4A0C-8854-DDFBE9FF17A6}.Release|x64.ActiveCfg = Release|x64
+		{8A098090-3E08-4A0C-8854-DDFBE9FF17A6}.Release|x64.Build.0 = Release|x64
+		{8A098090-3E08-4A0C-8854-DDFBE9FF17A6}.Release|x86.ActiveCfg = Release|Win32
+		{8A098090-3E08-4A0C-8854-DDFBE9FF17A6}.Release|x86.Build.0 = Release|Win32
+		{7B505B49-5584-4CF7-A2BB-65CC84303B33}.Debug|ARM.ActiveCfg = Debug|Win32
+		{7B505B49-5584-4CF7-A2BB-65CC84303B33}.Debug|ARM64.ActiveCfg = Debug|Win32
+		{7B505B49-5584-4CF7-A2BB-65CC84303B33}.Debug|x64.ActiveCfg = Debug|x64
+		{7B505B49-5584-4CF7-A2BB-65CC84303B33}.Debug|x64.Build.0 = Debug|x64
+		{7B505B49-5584-4CF7-A2BB-65CC84303B33}.Debug|x86.ActiveCfg = Debug|Win32
+		{7B505B49-5584-4CF7-A2BB-65CC84303B33}.Debug|x86.Build.0 = Debug|Win32
+		{7B505B49-5584-4CF7-A2BB-65CC84303B33}.Release|ARM.ActiveCfg = Release|Win32
+		{7B505B49-5584-4CF7-A2BB-65CC84303B33}.Release|ARM64.ActiveCfg = Release|Win32
+		{7B505B49-5584-4CF7-A2BB-65CC84303B33}.Release|x64.ActiveCfg = Release|x64
+		{7B505B49-5584-4CF7-A2BB-65CC84303B33}.Release|x64.Build.0 = Release|x64
+		{7B505B49-5584-4CF7-A2BB-65CC84303B33}.Release|x86.ActiveCfg = Release|Win32
+		{7B505B49-5584-4CF7-A2BB-65CC84303B33}.Release|x86.Build.0 = Release|Win32
+		{0E83FBE2-4696-41AD-9A5F-55B1401AB77C}.Debug|ARM.ActiveCfg = Debug|Win32
+		{0E83FBE2-4696-41AD-9A5F-55B1401AB77C}.Debug|ARM64.ActiveCfg = Debug|Win32
+		{0E83FBE2-4696-41AD-9A5F-55B1401AB77C}.Debug|x64.ActiveCfg = Debug|x64
+		{0E83FBE2-4696-41AD-9A5F-55B1401AB77C}.Debug|x64.Build.0 = Debug|x64
+		{0E83FBE2-4696-41AD-9A5F-55B1401AB77C}.Debug|x86.ActiveCfg = Debug|Win32
+		{0E83FBE2-4696-41AD-9A5F-55B1401AB77C}.Debug|x86.Build.0 = Debug|Win32
+		{0E83FBE2-4696-41AD-9A5F-55B1401AB77C}.Release|ARM.ActiveCfg = Release|Win32
+		{0E83FBE2-4696-41AD-9A5F-55B1401AB77C}.Release|ARM64.ActiveCfg = Release|Win32
+		{0E83FBE2-4696-41AD-9A5F-55B1401AB77C}.Release|x64.ActiveCfg = Release|x64
+		{0E83FBE2-4696-41AD-9A5F-55B1401AB77C}.Release|x64.Build.0 = Release|x64
+		{0E83FBE2-4696-41AD-9A5F-55B1401AB77C}.Release|x86.ActiveCfg = Release|Win32
+		{0E83FBE2-4696-41AD-9A5F-55B1401AB77C}.Release|x86.Build.0 = Release|Win32
+		{441E6793-7CDA-4D51-81BD-7A38520F1C1D}.Debug|ARM.ActiveCfg = Debug|Win32
+		{441E6793-7CDA-4D51-81BD-7A38520F1C1D}.Debug|ARM64.ActiveCfg = Debug|Win32
+		{441E6793-7CDA-4D51-81BD-7A38520F1C1D}.Debug|x64.ActiveCfg = Debug|x64
+		{441E6793-7CDA-4D51-81BD-7A38520F1C1D}.Debug|x64.Build.0 = Debug|x64
+		{441E6793-7CDA-4D51-81BD-7A38520F1C1D}.Debug|x86.ActiveCfg = Debug|Win32
+		{441E6793-7CDA-4D51-81BD-7A38520F1C1D}.Debug|x86.Build.0 = Debug|Win32
+		{441E6793-7CDA-4D51-81BD-7A38520F1C1D}.Release|ARM.ActiveCfg = Release|Win32
+		{441E6793-7CDA-4D51-81BD-7A38520F1C1D}.Release|ARM64.ActiveCfg = Release|Win32
+		{441E6793-7CDA-4D51-81BD-7A38520F1C1D}.Release|x64.ActiveCfg = Release|x64
+		{441E6793-7CDA-4D51-81BD-7A38520F1C1D}.Release|x64.Build.0 = Release|x64
+		{441E6793-7CDA-4D51-81BD-7A38520F1C1D}.Release|x86.ActiveCfg = Release|Win32
+		{441E6793-7CDA-4D51-81BD-7A38520F1C1D}.Release|x86.Build.0 = Release|Win32
+		{E8551DB0-274F-493A-88AF-7383E47F49FA}.Debug|ARM.ActiveCfg = Debug|Win32
+		{E8551DB0-274F-493A-88AF-7383E47F49FA}.Debug|ARM64.ActiveCfg = Debug|Win32
+		{E8551DB0-274F-493A-88AF-7383E47F49FA}.Debug|x64.ActiveCfg = Debug|x64
+		{E8551DB0-274F-493A-88AF-7383E47F49FA}.Debug|x64.Build.0 = Debug|x64
+		{E8551DB0-274F-493A-88AF-7383E47F49FA}.Debug|x86.ActiveCfg = Debug|Win32
+		{E8551DB0-274F-493A-88AF-7383E47F49FA}.Debug|x86.Build.0 = Debug|Win32
+		{E8551DB0-274F-493A-88AF-7383E47F49FA}.Release|ARM.ActiveCfg = Release|Win32
+		{E8551DB0-274F-493A-88AF-7383E47F49FA}.Release|ARM64.ActiveCfg = Release|Win32
+		{E8551DB0-274F-493A-88AF-7383E47F49FA}.Release|x64.ActiveCfg = Release|x64
+		{E8551DB0-274F-493A-88AF-7383E47F49FA}.Release|x64.Build.0 = Release|x64
+		{E8551DB0-274F-493A-88AF-7383E47F49FA}.Release|x86.ActiveCfg = Release|Win32
+		{E8551DB0-274F-493A-88AF-7383E47F49FA}.Release|x86.Build.0 = Release|Win32
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -1123,6 +1212,12 @@ Global
 		{B87D5885-6846-40E8-ACDC-B0F8798368AE} = {77DBD16D-112C-448D-BA6A-CE566A9331FC}
 		{9A68AAC1-2293-4E85-944E-47356E5313E7} = {729A65CE-3F07-4C2E-ACDC-F9EEC6477F2A}
 		{52AF7381-83F5-4425-BED2-AA8F2FE3A085} = {ABCB8CF8-5E82-4C47-A0FC-E82DF105DF99}
+		{8A098090-3E08-4A0C-8854-DDFBE9FF17A6} = {0E6598D3-602D-4552-97F7-DC5AB458D553}
+		{D2FBAC12-7C05-4632-9A99-3E86147322CB} = {B5D9E71E-2BFE-4D04-A66A-4CB0A103CD77}
+		{7B505B49-5584-4CF7-A2BB-65CC84303B33} = {F77FEB9A-854F-4A03-B204-D4C9DB700C35}
+		{0E83FBE2-4696-41AD-9A5F-55B1401AB77C} = {0E6598D3-602D-4552-97F7-DC5AB458D553}
+		{441E6793-7CDA-4D51-81BD-7A38520F1C1D} = {729A65CE-3F07-4C2E-ACDC-F9EEC6477F2A}
+		{E8551DB0-274F-493A-88AF-7383E47F49FA} = {729A65CE-3F07-4C2E-ACDC-F9EEC6477F2A}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {A8EBEA58-739C-4DED-99C0-239779F57D5D}
diff --git a/test/test_duireg/test_duireg.cpp b/test/test_duireg/test_duireg.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f35633dc69f9bc8cb9b80365a75729d1d77f4215
--- /dev/null
+++ b/test/test_duireg/test_duireg.cpp
@@ -0,0 +1,6 @@
+#include "../../jlib/win32/duireg.h"
+
+int main()
+{
+
+}
diff --git a/test/test_duireg/test_duireg.vcxproj b/test/test_duireg/test_duireg.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..7e413aa701bb9632de0e9968a7f91b1aa7bfe7c8
--- /dev/null
+++ b/test/test_duireg/test_duireg.vcxproj
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <VCProjectVersion>16.0</VCProjectVersion>
+    <Keyword>Win32Proj</Keyword>
+    <ProjectGuid>{8a098090-3e08-4a0c-8854-ddfbe9ff17a6}</ProjectGuid>
+    <RootNamespace>testduireg</RootNamespace>
+    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="test_duireg.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\jlib\win32\duireg.h" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/test/test_duireg/test_duireg.vcxproj.filters b/test/test_duireg/test_duireg.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..3888a131622923abc0bf00b1881bc11fe14b7b57
--- /dev/null
+++ b/test/test_duireg/test_duireg.vcxproj.filters
@@ -0,0 +1,27 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="test_duireg.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\jlib\win32\duireg.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/test/test_duireg/test_duireg.vcxproj.user b/test/test_duireg/test_duireg.vcxproj.user
new file mode 100644
index 0000000000000000000000000000000000000000..88a550947edbc3c5003a41726f0749201fdb6822
--- /dev/null
+++ b/test/test_duireg/test_duireg.vcxproj.user
@@ -0,0 +1,4 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup />
+</Project>
\ No newline at end of file
diff --git a/test/test_jinfo/test_jinfo.cpp b/test/test_jinfo/test_jinfo.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8fc82dd886ebae22240722c5018a0e5d41fd9f01
--- /dev/null
+++ b/test/test_jinfo/test_jinfo.cpp
@@ -0,0 +1,80 @@
+#include "../../jlib/win32/jinfo.h"
+#include "../../jlib/util/space.h"
+#include <iostream>
+#include <stdlib.h>
+
+#ifdef _WIN64
+#pragma comment(lib, "jinfo_x64.lib")
+#else
+#pragma comment(lib, "jinfo.lib")
+#endif // _WIN64
+
+
+
+using namespace std;
+using namespace jlib::win32::info;
+
+int main()
+{
+
+	cout << "cpu\n" 
+		<< "architecture:\t" << cpu::architecture_to_string(cpu::architecture()) << endl
+		<< "cpu_id:\t" << cpu::cpu_id() << endl
+		<< "vendor:\t" << cpu::vendor() << endl
+		<< "brand:\t" << cpu::brand() << endl;
+
+	auto kernal_version = system::kernel_version();
+	auto mem = system::memory();
+	cout << "\nsystem\n"
+		<< "os_name:\t" << system::os_name() << endl
+		<< "computer_name:\t" << system::computer_name() << endl
+		<< "is_64bit_windows:\t" << system::is_64bit_windows() << endl
+		<< "kernel_version:\t" << kernal_version.major << "." << kernal_version.minor << "." << kernal_version.patch << "." << kernal_version.build_number << endl
+		<< "memory:\t" << mem.physical_available << "/" << mem.physical_total << endl
+		<< "display_version:\t" << system::display_version() << endl
+		<< "os_version:\t" << system::os_version() << endl
+		<< "product_id:\t" << system::product_id() << endl
+		<< "uuid:\t" << system::uuid() << endl
+		<< "system_info_string:\t" << system::system_info_string() << endl
+		;
+
+	cout << "\nuser\n";
+	for (auto user : user::users()) {
+		cout << user.name << " "
+			<< user.full_name << " "
+			<< user.privilege << endl;
+	}
+
+	cout << "\ndiskdrive\nindex\tpartitions\tdevice_id\tmodel\tserial\tsize\n";
+	for (auto&& disk : diskdrive::disk_drives()) {
+		cout << disk.index << "\t" 
+			<< disk.partitions << "\t" 
+			<< disk.device_id << "\t" 
+			<< disk.model << "\t" 
+			<< disk.serial << "\t" << 
+			jlib::human_readable_byte_count(disk.size, jlib::PositionalNotation::Decimal) << endl;
+	}
+	cout << "bootable_disk_serial:\t" << diskdrive::bootable_disk_serial() << endl;
+
+	cout << "\nlogicaldrive\ndevice_id\tdrive_type\tfree_space\tsize\tpercent\tvolume_name\n";
+	for (auto&& drive : logicaldrive::logical_drives()) {
+		cout << drive.device_id << "\t"
+			<< logicaldrive::drive_type_to_string(drive.drive_type) << "\t"
+			<< jlib::human_readable_byte_count(drive.free_space, jlib::PositionalNotation::Decimal) << "/"
+			<< jlib::human_readable_byte_count(drive.size, jlib::PositionalNotation::Decimal) << "\t"
+			<< drive.free_space * 100.0 / drive.size << "%\t"
+			<< drive.volume_name << endl;
+	}
+
+	cout << "\ngpu\n";
+	for (auto&& gpu : gpu::gpus()) {
+		cout << gpu.name << " " << jlib::human_readable_byte_count(gpu.memsz) << endl;
+	}
+
+	cout << "\nbaseboard\nmanufacturer:\t" << baseboard::manufacturer() << endl
+		<< "product:\t" << baseboard::product() << endl
+		<< "serial:\t" << baseboard::serial() << endl
+		<< "bios_serial:\t" << baseboard::bios_serial() << endl;
+
+	std::system("pause");
+}
diff --git a/test/test_jinfo/test_jinfo.vcxproj b/test/test_jinfo/test_jinfo.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..2d869e6baa113772afd94e991848f09a6b21dfa2
--- /dev/null
+++ b/test/test_jinfo/test_jinfo.vcxproj
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <VCProjectVersion>16.0</VCProjectVersion>
+    <Keyword>Win32Proj</Keyword>
+    <ProjectGuid>{0e83fbe2-4696-41ad-9a5f-55b1401ab77c}</ProjectGuid>
+    <RootNamespace>testjinfo</RootNamespace>
+    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="test_jinfo.cpp" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/test/test_jinfo/test_jinfo.vcxproj.filters b/test/test_jinfo/test_jinfo.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..354d06d606f5dac6a8fc1709b24fbf5d709b9c16
--- /dev/null
+++ b/test/test_jinfo/test_jinfo.vcxproj.filters
@@ -0,0 +1,22 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="test_jinfo.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/test/test_jinfo/test_jinfo.vcxproj.user b/test/test_jinfo/test_jinfo.vcxproj.user
new file mode 100644
index 0000000000000000000000000000000000000000..88a550947edbc3c5003a41726f0749201fdb6822
--- /dev/null
+++ b/test/test_jinfo/test_jinfo.vcxproj.user
@@ -0,0 +1,4 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup />
+</Project>
\ No newline at end of file