├── .gitignore
├── DeviceIOControl
├── Constant.cs
├── DeviceIOControl.csproj
├── DeviceIOControl.csproj.user
├── DeviceIoControl.cs
├── Disc
│ ├── Disc.cs
│ ├── Perfomance.cs
│ └── Smart
│ │ ├── AttributeThresholds.cs
│ │ ├── IdentifyDma.cs
│ │ └── SmartInfoCollection.cs
├── FileSystem
│ └── FileSystem.cs
├── LogicalDrive.cs
├── Native
│ ├── AtaApi.cs
│ ├── DiscApi.cs
│ ├── FsctlApi.cs
│ ├── Methods.cs
│ ├── StorageApi.cs
│ ├── VolumeApi.cs
│ └── WinApi.cs
├── PinnedBufferReader.cs
├── Properties
│ └── PublishProfiles
│ │ ├── FolderProfile.pubxml
│ │ └── FolderProfile.pubxml.user
├── Storage
│ ├── Properties.cs
│ └── Storage.cs
├── Utils.cs
└── Volume
│ └── Volume.cs
├── Hardware
├── Computer.cs
├── Hardware.csproj
└── Windows
│ ├── DeviceIoInfo
│ ├── Device.cs
│ ├── DeviceInfo.cs
│ └── VendorEnum.cs
│ ├── Network
│ ├── Adapter.cs
│ └── NetworkInfo.cs
│ └── RAM
│ ├── MemoryStatusEx.cs
│ └── NativeMethods.cs
├── LICENSE
├── README.md
├── SysMonAvalonia.sln
├── SysMonAvalonia
├── App.axaml
├── App.axaml.cs
├── Assets
│ ├── Fonts
│ │ └── SegoeUILight.ttf
│ ├── Locale
│ │ ├── en.json
│ │ └── ru.json
│ ├── Styles
│ │ ├── Dark.xaml
│ │ └── Light.xaml
│ ├── WeatherIcons
│ │ ├── Black
│ │ │ ├── 30
│ │ │ │ ├── weather_0.png
│ │ │ │ ├── weather_1.png
│ │ │ │ ├── weather_10.png
│ │ │ │ ├── weather_11.png
│ │ │ │ ├── weather_12.png
│ │ │ │ ├── weather_13.png
│ │ │ │ ├── weather_14.png
│ │ │ │ ├── weather_15.png
│ │ │ │ ├── weather_16.png
│ │ │ │ ├── weather_17.png
│ │ │ │ ├── weather_18.png
│ │ │ │ ├── weather_19.png
│ │ │ │ ├── weather_2.png
│ │ │ │ ├── weather_20.png
│ │ │ │ ├── weather_21.png
│ │ │ │ ├── weather_22.png
│ │ │ │ ├── weather_23.png
│ │ │ │ ├── weather_3.png
│ │ │ │ ├── weather_4.png
│ │ │ │ ├── weather_5.png
│ │ │ │ ├── weather_6.png
│ │ │ │ ├── weather_7.png
│ │ │ │ ├── weather_8.png
│ │ │ │ └── weather_9.png
│ │ │ └── 65
│ │ │ │ ├── weather_0.png
│ │ │ │ ├── weather_1.png
│ │ │ │ ├── weather_10.png
│ │ │ │ ├── weather_11.png
│ │ │ │ ├── weather_12.png
│ │ │ │ ├── weather_13.png
│ │ │ │ ├── weather_14.png
│ │ │ │ ├── weather_15.png
│ │ │ │ ├── weather_16.png
│ │ │ │ ├── weather_17.png
│ │ │ │ ├── weather_18.png
│ │ │ │ ├── weather_19.png
│ │ │ │ ├── weather_2.png
│ │ │ │ ├── weather_20.png
│ │ │ │ ├── weather_21.png
│ │ │ │ ├── weather_22.png
│ │ │ │ ├── weather_23.png
│ │ │ │ ├── weather_3.png
│ │ │ │ ├── weather_4.png
│ │ │ │ ├── weather_5.png
│ │ │ │ ├── weather_6.png
│ │ │ │ ├── weather_7.png
│ │ │ │ ├── weather_8.png
│ │ │ │ └── weather_9.png
│ │ └── White
│ │ │ ├── 30
│ │ │ ├── weather_0.png
│ │ │ ├── weather_1.png
│ │ │ ├── weather_10.png
│ │ │ ├── weather_11.png
│ │ │ ├── weather_12.png
│ │ │ ├── weather_13.png
│ │ │ ├── weather_14.png
│ │ │ ├── weather_15.png
│ │ │ ├── weather_16.png
│ │ │ ├── weather_17.png
│ │ │ ├── weather_18.png
│ │ │ ├── weather_19.png
│ │ │ ├── weather_2.png
│ │ │ ├── weather_20.png
│ │ │ ├── weather_21.png
│ │ │ ├── weather_22.png
│ │ │ ├── weather_23.png
│ │ │ ├── weather_3.png
│ │ │ ├── weather_4.png
│ │ │ ├── weather_5.png
│ │ │ ├── weather_6.png
│ │ │ ├── weather_7.png
│ │ │ ├── weather_8.png
│ │ │ └── weather_9.png
│ │ │ └── 65
│ │ │ ├── weather_0.png
│ │ │ ├── weather_1.png
│ │ │ ├── weather_10.png
│ │ │ ├── weather_11.png
│ │ │ ├── weather_12.png
│ │ │ ├── weather_13.png
│ │ │ ├── weather_14.png
│ │ │ ├── weather_15.png
│ │ │ ├── weather_16.png
│ │ │ ├── weather_17.png
│ │ │ ├── weather_18.png
│ │ │ ├── weather_19.png
│ │ │ ├── weather_2.png
│ │ │ ├── weather_20.png
│ │ │ ├── weather_21.png
│ │ │ ├── weather_22.png
│ │ │ ├── weather_23.png
│ │ │ ├── weather_3.png
│ │ │ ├── weather_4.png
│ │ │ ├── weather_5.png
│ │ │ ├── weather_6.png
│ │ │ ├── weather_7.png
│ │ │ ├── weather_8.png
│ │ │ └── weather_9.png
│ └── icon.ico
├── Converters
│ ├── BitmapValueConverter.cs
│ ├── DataValueConverter.cs
│ ├── DeviceIoValueConverter.cs
│ ├── NetworkValueConvert.cs
│ └── SettingsValueConverter.cs
├── Data
│ ├── ComboData.cs
│ ├── DeviceIoData.cs
│ ├── ForecastData.cs
│ ├── SettingData.cs
│ └── WeatherData.cs
├── Localization
│ └── Language.cs
├── Models
│ ├── ChartModel.cs
│ ├── ComboModel.cs
│ ├── DeviceIoModel.cs
│ ├── ForecastModel.cs
│ ├── SettingModel.cs
│ └── WeatherModel.cs
├── NLog.config
├── Program.cs
├── Services
│ └── AppService.cs
├── SysMonAvalonia.csproj
├── SysMonAvalonia.csproj.user
├── ViewLocator.cs
├── ViewModels
│ ├── ComboWidgetViewModel.cs
│ ├── DeviceIoWidgetViewModel.cs
│ ├── SettingViewModel.cs
│ ├── ViewModelBase.cs
│ └── WeatherWidgetViewModel.cs
├── Views
│ ├── ComboWidgetView.axaml
│ ├── ComboWidgetView.axaml.cs
│ ├── DeviceIoWidgetView.axaml
│ ├── DeviceIoWidgetView.axaml.cs
│ ├── SettingView.axaml
│ ├── SettingView.axaml.cs
│ ├── WeatherWidgetView.axaml
│ └── WeatherWidgetView.axaml.cs
├── app.manifest
└── nuget.config
└── Weather
├── Helper.cs
├── LocationData.cs
├── NLog.config
├── Providers
├── AccuWeather.cs
├── Gismeteo.cs
├── IProvider.cs
├── OpenWeatherMap.cs
├── Providers.cs
├── WorldWeatherOnline.cs
└── Wunderground.cs
├── Weather.csproj
├── WeatherData.cs
└── WindUnitEnum.cs
/.gitignore:
--------------------------------------------------------------------------------
1 | /.git/
2 | /.vs/
3 | /DeviceIOControl/obj/
4 | /DeviceIOControl/bin/
5 | /Hardware/obj/
6 | /Hardware/bin/
7 | /SysMonAvalonia/obj/
8 | /SysMonAvalonia/bin/
9 | /Weather/obj/
10 | /Weather/bin/
11 | /SysMonAvalonia/Properties/
12 |
--------------------------------------------------------------------------------
/DeviceIOControl/DeviceIOControl.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 |
6 |
7 |
8 | AnyCPU
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/DeviceIOControl/DeviceIOControl.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <_LastSelectedProfileId>D:\SourcesCode\DeviceIOControl\DeviceIOControl\Properties\PublishProfiles\FolderProfile.pubxml
5 |
6 |
--------------------------------------------------------------------------------
/DeviceIOControl/Disc/Disc.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using System.ComponentModel;
4 | using DeviceIOControl.Native;
5 | using DeviceIOControl.Disc.Smart;
6 |
7 | namespace DeviceIOControl.Disc
8 | {
9 | public class Disc
10 | {
11 | private readonly DeviceIoControl _device;
12 | private SmartInfoCollection _smart;
13 | private DiscApi.GETVERSIONINPARAMS? _version;
14 | private DiscApi.DISK_GEOMETRY_EX? _driveGeometryEx;
15 | private Boolean? _isWritable;
16 | /// Device
17 | private DeviceIoControl Device { get { return this._device; } }
18 |
19 | /// Returns version information, a capabilities mask, and a bitmask for the device.
20 | /// This IOCTL must be handled by drivers that support Self-Monitoring Analysis and Reporting Technology (SMART).
21 | public DiscApi.GETVERSIONINPARAMS? Version
22 | {
23 | get
24 | {
25 | if (this._version == null)
26 | {
27 | DiscApi.GETVERSIONINPARAMS prms;
28 | if (this.Device.IoControl(Constant.IOCTL_DISC.SMART_GET_VERSION, null, out prms))
29 | this._version = prms;
30 | else
31 | this._version = prms;
32 | }
33 | return this._version.Value.Equals(default(DiscApi.GETVERSIONINPARAMS)) ? (DiscApi.GETVERSIONINPARAMS?)null : this._version.Value;
34 | }
35 | }
36 |
37 | /// Returns information about the physical disk's geometry (media type, number of cylinders, tracks per cylinder, sectors per track, and bytes per sector).
38 | public DiscApi.DISK_GEOMETRY_EX DriveGeometryEx
39 | {
40 | get
41 | {
42 | if (this._driveGeometryEx == null)
43 | this._driveGeometryEx = this.Device.IoControl(
44 | Constant.IOCTL_DISC.GET_DRIVE_GEOMETRY_EX,
45 | null);
46 | return this._driveGeometryEx.Value;
47 | }
48 | }
49 |
50 | /// Self-Monitoring Analysis and Reporting Technology info
51 | /// Smart can be null if SAMRT commands not supported
52 | public SmartInfoCollection Smart
53 | {
54 | get
55 | {
56 | if (this._smart == null && this.Version != null && this.Version.Value.IsSmartSupported)
57 | this._smart = new SmartInfoCollection(this.Device);
58 | return this._smart;
59 | }
60 | }
61 |
62 | /// Determines whether the specified disk is writable.
63 | /// WinAPI operation fails.
64 | public Boolean IsWritable
65 | {
66 | get
67 | {
68 | if (this._isWritable == null)
69 | if (this.Device.IoControl(Constant.IOCTL_DISC.IS_WRITABLE))
70 | this._isWritable = true;
71 | else
72 | {
73 | Int32 error = Marshal.GetLastWin32Error();
74 | if (error == (Int32)Constant.ERROR.WRITE_PROTECT)
75 | this._isWritable = false;
76 | else
77 | throw new Win32Exception(error);
78 | }
79 | return this._isWritable.Value;
80 | }
81 | }
82 |
83 | /// Create instance of disc IO control commands class
84 | /// Device
85 | internal Disc(DeviceIoControl device)
86 | {
87 | this._device = device;
88 | }
89 |
90 | /// Get disc performance managed
91 | /// Perfomance manager
92 | public Performance GetDiscPerformance()
93 | {
94 | return new Performance(this.Device);
95 | }
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/DeviceIOControl/Disc/Perfomance.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using DeviceIOControl.Native;
3 |
4 | namespace DeviceIOControl.Disc
5 | {
6 | /// Collect perfomance counters from HDD
7 | public class Performance : IDisposable
8 | {
9 | private readonly DeviceIoControl _device;
10 | private Boolean _counterIsActive = false;
11 |
12 | /// Device
13 | private DeviceIoControl Device { get { return this._device; } }
14 |
15 | /// Create instance of deviceperfomance counters
16 | /// device
17 | internal Performance(DeviceIoControl device)
18 | {
19 | this._device = device;
20 | }
21 | /// Query performance counters
22 | /// Performance counters
23 | public DiscApi.DISK_PERFORMANCE QueryPerformanceInfo()
24 | {
25 | DiscApi.DISK_PERFORMANCE result = this.Device.IoControl(
26 | Constant.IOCTL_DISC.PERFORMANCE,
27 | null);
28 | this._counterIsActive = true;
29 | return result;
30 | }
31 | /// Close perfomace counters manager
32 | public void Dispose()
33 | {
34 | if (this._counterIsActive)
35 | {
36 | this.Device.IoControl(
37 | Constant.IOCTL_DISC.PERFORMANCE_OFF,
38 | null);
39 | this._counterIsActive = false;
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/DeviceIOControl/Disc/Smart/AttributeThresholds.cs:
--------------------------------------------------------------------------------
1 | using DeviceIOControl.Native;
2 |
3 | namespace DeviceIOControl.Disc.Smart
4 | {
5 | /// S.M.A.R.T. attribute & threshold value
6 | public struct AttributeThresholds
7 | {
8 | private readonly DiscApi.DRIVEATTRIBUTE _attribute;
9 | private readonly DiscApi.ATTRTHRESHOLD _threshold;
10 | /// Attribute value
11 | public DiscApi.DRIVEATTRIBUTE Attribute { get { return this._attribute; } }
12 | /// Threshold value
13 | public DiscApi.ATTRTHRESHOLD Threshold { get { return this._threshold; } }
14 |
15 | internal AttributeThresholds(DiscApi.DRIVEATTRIBUTE attribute, DiscApi.ATTRTHRESHOLD threshold)
16 | : this()
17 | {
18 | this._attribute = attribute;
19 | this._threshold = threshold;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/DeviceIOControl/Disc/Smart/IdentifyDma.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 |
4 | namespace DeviceIOControl.Disc.Smart
5 | {
6 | /// Device DMA/UDMA modes
7 | public struct IdentifyDma
8 | {
9 | /// DMA type
10 | public enum DmaType
11 | {
12 | /// UDMA
13 | UDma = 0,
14 | /// DMA
15 | Dma = 1,
16 | }
17 | private readonly DmaType _type;
18 | private readonly SmartInfoCollection _info;
19 | /// Device info
20 | private SmartInfoCollection Info { get { return this._info; } }
21 | /// Type of DMA
22 | private DmaType Type { get { return this._type; } }
23 | /// DMA/UDMA structure indexes
24 | private static Int32[] DmaIndex = new Int32[] { 88, 63, };
25 | /// DMA/UDMA structure max bit pos
26 | private static Int32[] DmaMaxPos = new Int32[] { 5, 2, };
27 | /// Max DMA/UDMA mode supported
28 | public Int64? Max
29 | {
30 | get
31 | {
32 | Int64 pos = this.GetHighBitPos(false);
33 | return pos != 1 ? pos : (Int64?)null;
34 | }
35 | }
36 | /// DMA/UDMA mode selected
37 | public Int64? Selected
38 | {
39 | get
40 | {
41 | Int64 pos = this.GetHighBitPos(true);
42 | return this.Max.HasValue && pos != -1 ? pos : (Int64?)null;
43 | }
44 | }
45 |
46 | /// Create instance of DMA/UDMA info structure
47 | /// Device info
48 | /// DMA/UDMA
49 | public IdentifyDma(SmartInfoCollection info, DmaType type)
50 | {
51 | this._info = info;
52 | this._type = type;
53 | }
54 | private Int64 GetHighBitPos(Boolean isSelected)
55 | {
56 | return 0;
57 | /*Int32 index = IdentifyDma.DmaIndex[(Int32)this.Type];
58 | Int32 maxPos = IdentifyDma.DmaMaxPos[(Int32)this.Type];
59 | return Utils.HighBitPos(
60 | isSelected ? this.Info.SystemParams[index] >> 8 : this.Info.SystemParams[index],
61 | maxPos);*/
62 | }
63 | /// DMA/UDMA values as string
64 | ///
65 | public override String ToString()
66 | {
67 | Int64? max = this.Max;
68 | Int64? selected = this.Selected;
69 |
70 | String result = String.Empty;
71 | if (max.HasValue)
72 | {
73 | result = String.Format(CultureInfo.CurrentUICulture, "Max {0} mode supported {1}{2}",
74 | this.Type.ToString().ToUpperInvariant(),
75 | max,
76 | max > 0 ? " and below" : String.Empty);
77 | if (selected.HasValue)
78 | result += Environment.NewLine + String.Format(CultureInfo.CurrentUICulture, "{0} mode selected {1}",
79 | this.Type.ToString().ToUpperInvariant(),
80 | selected);
81 | }
82 | return result;
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/DeviceIOControl/FileSystem/FileSystem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Runtime.InteropServices;
4 | using System.ComponentModel;
5 | using DeviceIOControl.Native;
6 |
7 | namespace DeviceIOControl.FileSystem
8 | {
9 | /// File system control commands
10 | public class FileSystem
11 | {
12 | private readonly DeviceIoControl _device;
13 | private FsctlApi.NTFS_VOLUME_DATA_BUFFER? _volumeData;
14 |
15 | /// Device
16 | private DeviceIoControl Device { get { return this._device; } }
17 |
18 | /// Represents volume data.
19 | public FsctlApi.NTFS_VOLUME_DATA_BUFFER VolumeData
20 | {
21 | get
22 | {
23 | return (this._volumeData == null
24 | ? this._volumeData = this.Device.IoControl(
25 | Constant.FSCTL.GET_NTFS_VOLUME_DATA, null)
26 | : this._volumeData).Value;
27 | }
28 | }
29 |
30 | /// Determines whether the specified volume is mounted
31 | public Boolean IsVolumeMounted
32 | {
33 | get { return this.Device.IoControl(Constant.FSCTL.IS_VOLUME_MOUNTED); }
34 | }
35 |
36 | /// Create instance of file system IO commands class
37 | /// Device
38 | public FileSystem(DeviceIoControl device)
39 | {
40 | this._device = device;
41 | }
42 |
43 | /// Retrieves a bitmap of occupied and available clusters on a volume.
44 | /// Represents the occupied and available clusters on a disk.
45 | public IEnumerable GetVolumeBitmap()
46 | {
47 | UInt64 startingLcn = 0;
48 | UInt32 bytesReturned;
49 | Boolean moreDataAvailable = false;
50 |
51 | do
52 | {
53 | FsctlApi.VOLUME_BITMAP_BUFFER part = this.GetVolumeBitmap(startingLcn, out bytesReturned, out moreDataAvailable);
54 | if (moreDataAvailable)
55 | startingLcn = bytesReturned;
56 | yield return part;
57 | } while (moreDataAvailable);
58 | }
59 |
60 | /// Метод не работает и вываливается по: 0x00000057 - The parameter is incorrect
61 | ///
62 | ///
63 | public FsctlApi.FIND_BY_SID_OUTPUT FindFilesBySid(String accountName)
64 | {
65 | if (String.IsNullOrEmpty(accountName))
66 | throw new ArgumentNullException("accountName");
67 |
68 | FsctlApi.FIND_BY_SID_DATA fsInParams = new FsctlApi.FIND_BY_SID_DATA();
69 | fsInParams.Restart = 1;
70 | fsInParams.Sid = Methods.LookupAccountName(accountName);
71 |
72 | //var currentIdentity = System.Security.Principal.WindowsIdentity.GetCurrent();
73 | //System.Security.Principal.SecurityIdentifier managedSid = new System.Security.Principal.SecurityIdentifier(fsInParams.Sid, 0);
74 |
75 | UInt32 bytesReturned;
76 | FsctlApi.FIND_BY_SID_OUTPUT result;
77 | Boolean resultCode = this.Device.IoControl(
78 | Constant.FSCTL.FIND_FILES_BY_SID,
79 | fsInParams,
80 | out bytesReturned,
81 | out result);
82 |
83 | if (resultCode)
84 | return result;
85 | else
86 | {
87 | Int32 error = Marshal.GetLastWin32Error();
88 | throw new Win32Exception(error);
89 | }
90 | }
91 |
92 | /// Retrieves a bitmap of occupied and available clusters on a volume.
93 | ///
94 | /// The LCN from which the operation should start when describing a bitmap.
95 | /// This member will be rounded down to a file-system-dependent rounding boundary, and that value will be returned.
96 | /// Its value should be an integral multiple of eight.
97 | ///
98 | /// Returned length of bytes
99 | /// Not all data readed
100 | /// Win32 Exception occured. See winerror.h for details
101 | /// Represents the occupied and available clusters on a disk.
102 | public FsctlApi.VOLUME_BITMAP_BUFFER GetVolumeBitmap(UInt64 startingLcn, out UInt32 bytesReturned, out Boolean moreDataAvailable)
103 | {
104 | FsctlApi.STARTING_LCN_INPUT_BUFFER fsInParams = new FsctlApi.STARTING_LCN_INPUT_BUFFER();
105 | fsInParams.StartingLcn = startingLcn;//0xA000;
106 |
107 | FsctlApi.VOLUME_BITMAP_BUFFER result;
108 | Boolean resultCode = this.Device.IoControl(
109 | Constant.FSCTL.GET_VOLUME_BITMAP,
110 | fsInParams,
111 | out bytesReturned,
112 | out result);
113 |
114 | if (resultCode)
115 | moreDataAvailable = false;
116 | else
117 | {
118 | Int32 error = Marshal.GetLastWin32Error();
119 | if (error == (Int32)Constant.ERROR.MORE_DATA)
120 | moreDataAvailable = true;
121 | else
122 | throw new Win32Exception(error);
123 | }
124 | return result;
125 | }
126 |
127 | /// Retrieves the information from various file system performance counters.
128 | /// Contains statistical information from the file system.
129 | public FsctlApi.FILESYSTEM_STATISTICS GetStatistics()
130 | {
131 | UInt32 bytesReturned;
132 | FsctlApi.FILESYSTEM_STATISTICS result = this.Device.IoControl(
133 | Constant.FSCTL.FILESYSTEM_GET_STATISTICS,
134 | null,
135 | out bytesReturned);
136 |
137 | /*const UInt32 SizeOfFileSystemStat = 56;
138 | using(BytesReader reader = new BytesReader(result.Data))
139 | {
140 | UInt32 padding = 0;
141 | switch(result.FileSystemType)
142 | {
143 | case FsctlAPI.FILESYSTEM_STATISTICS.FILESYSTEM_STATISTICS_TYPE.NTFS:
144 | FsctlAPI.NTFS_STATISTICS ntfsStat = reader.BytesToStructure(ref padding);
145 | break;
146 | case FsctlAPI.FILESYSTEM_STATISTICS.FILESYSTEM_STATISTICS_TYPE.FAT:
147 | FsctlAPI.FAT_STATISTICS fatStat = reader.BytesToStructure(ref padding);
148 | break;
149 | case FsctlAPI.FILESYSTEM_STATISTICS.FILESYSTEM_STATISTICS_TYPE.EXFAT:
150 | FsctlAPI.EXFAT_STATISTICS exFatStat = reader.BytesToStructure(ref padding);
151 | break;
152 | }
153 | }*/
154 | return result;
155 | }
156 |
157 | /// Retrieves the information from various file system performance counters
158 | /// Support for this structure started with Windows 10
159 | /// Contains statistical information from the file system
160 | public FsctlApi.FILESYSTEM_STATISTICS_EX GetStatisticsEx()
161 | {
162 | UInt32 bytesReturned;
163 | FsctlApi.FILESYSTEM_STATISTICS_EX result = this.Device.IoControl(
164 | Constant.FSCTL.FILESYSTEM_GET_STATISTICS,
165 | null,
166 | out bytesReturned);
167 |
168 | return result;
169 | }
170 |
171 | ///
172 | /// Locks a volume if it is not in use.
173 | /// A locked volume can be accessed only through handles to the file object (*hDevice) that locks the volume.
174 | ///
175 | /// Device exception
176 | /// Lock action status
177 | public void LockVolume()
178 | {
179 | this.Device.IoControl(Constant.FSCTL.LOCK_VOLUME, null);
180 | }
181 |
182 | /// Unlocks a volume.
183 | /// Device exception
184 | /// Unlock action status
185 | public void UnlockVolume()
186 | {
187 | this.Device.IoControl(Constant.FSCTL.UNLOCK_VOLUME, null);
188 | }
189 |
190 | /// Dismounts a volume regardless of whether or not the volume is currently in use.
191 | /// Device exception
192 | /// Dismount action status
193 | public void DismountVolume()
194 | {
195 | this.Device.IoControl(Constant.FSCTL.DISMOUNT_VOLUME, null);
196 | }
197 | }
198 | }
199 |
--------------------------------------------------------------------------------
/DeviceIOControl/LogicalDrive.cs:
--------------------------------------------------------------------------------
1 | using DeviceIOControl.Native;
2 |
3 | namespace DeviceIOControl
4 | {
5 | public struct LogicalDrive
6 | {
7 | private readonly string _name;
8 |
9 | private readonly WinApi.DRIVE _type;
10 |
11 | public string Name => _name;
12 |
13 | public WinApi.DRIVE Type => _type;
14 |
15 | internal LogicalDrive(string name, WinApi.DRIVE type)
16 | {
17 | this = default(LogicalDrive);
18 | _name = name;
19 | _type = type;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/DeviceIOControl/Native/AtaApi.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace DeviceIOControl.Native
5 | {
6 | /// ATA IOCTL structures
7 | public struct AtaApi
8 | {
9 | /// The ATA_PASS_THROUGH_EX structure is used in conjunction with an request to instruct the port driver to send an embedded ATA command to the target device.
10 | [StructLayout(LayoutKind.Sequential)]
11 | public struct ATA_PASS_THROUGH_EX
12 | {
13 | /// Indicates the direction of data transfer and specifies the kind of operation to be performed.
14 | [Flags]
15 | public enum AtaPassThroughFlags : ushort
16 | {
17 | /// Wait for DRDY status from the device before sending the command to the device.
18 | DRDY_REQUIRED = 1 << 0,
19 | /// Read data from the device.
20 | DATA_IN = 1 << 1,
21 | /// Write data to the device.
22 | DATA_OUT = 1 << 2,
23 | /// The ATA command to be sent uses the 48-bit logical block address (LBA) feature set.
24 | /// When this flag is set, the contents of the PreviousTaskFile member in the ATA_PASS_THROUGH_EX structure should be valid.
25 | _48BIT_COMMAND = 1 << 3,
26 | /// Set the transfer mode to DMA.
27 | USE_DMA = 1 << 4,
28 | /// Read single sector only.
29 | NO_MULTIPLE = 1 << 5,
30 | }
31 | /// Specifies the length in bytes of the ATA_PASS_THROUGH_EX structure.
32 | public UInt16 Length;
33 | /// Indicates the direction of data transfer and specifies the kind of operation to be performed.
34 | public AtaPassThroughFlags AtaFlags;
35 | /// Contains an integer that indicates the IDE port or bus for the request. This value is set by the port driver.
36 | public Byte PathId;
37 | /// Contains an integer that indicates the target device on the bus. This value is set by the port driver.
38 | public Byte TargetId;
39 | /// Indicates the logical unit number of the device. This value is set by the port driver.
40 | public Byte Lun;
41 | /// Reserved for future use.
42 | public Byte ReservedAsUchar;
43 | ///
44 | /// Indicates the size, in bytes, of the data buffer.
45 | /// If an underrun occurs, the miniport driver must update this member to the number of bytes that were actually transferred.
46 | ///
47 | public UInt32 DataTransferLength;
48 | /// Indicates the number of seconds that are allowed for the request to execute before the OS-specific port driver determines that the request has timed out.
49 | public UInt32 TimeOutValue;
50 | /// Reserved for future use.
51 | public UInt32 ReservedAsUlong;
52 | /// Specifies the offset, in bytes, from the beginning of this structure to the data buffer.
53 | public UInt32 DataBufferOffset;
54 | /// Specifies the contents of the task file input registers prior to the current pass-through command.
55 | /// This member is not used when the ATA_FLAGS_48BIT_COMMAND flag is not set.
56 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
57 | public Byte[] PreviousTaskFile;
58 | /// Specifies the content of the task file register on both input and output.
59 | /// http://msdn.microsoft.com/en-us/library/windows/hardware/ff551323%28v=vs.85%29.aspx
60 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
61 | public Byte[] CurrentTaskFile;
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/DeviceIOControl/Native/VolumeApi.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace DeviceIOControl.Native
5 | {
6 | /// Volume IOCTL structures
7 | public struct VolumeApi
8 | {
9 | /// Represents a physical location on a disk. It is the output buffer for the control code.
10 | /// http://msdn.microsoft.com/en-us/library/windows/desktop/aa365727%28v=vs.85%29.aspx
11 | [StructLayout(LayoutKind.Sequential)]
12 | public struct VOLUME_DISK_EXTENTS
13 | {
14 | /// Represents a disk extent.
15 | [StructLayout(LayoutKind.Sequential)]
16 | public struct DISK_EXTENT
17 | {
18 | /// The number of the disk that contains this extent.
19 | /// This is the same number that is used to construct the name of the disk, for example, the X in "\\?\PhysicalDriveX" or "\\?\HarddiskX".
20 | public UInt32 DiskNumber;
21 | /// The offset from the beginning of the disk to the extent, in bytes.
22 | public UInt64 StartingOffset;
23 | /// The number of bytes in this extent.
24 | public UInt64 ExtentLength;
25 | }
26 | /// The number of disks in the volume (a volume can span multiple disks).
27 | ///
28 | /// An extent is a contiguous run of sectors on one disk.
29 | /// When the number of extents returned is greater than one (1), the error code ERROR_MORE_DATA is returned.
30 | /// You should call DeviceIoControl again, allocating enough buffer space based on the value of NumberOfDiskExtents after the first DeviceIoControl call.
31 | ///
32 | public UInt32 NumberOfDiskExtents;
33 | /// An array of DISK_EXTENT structures.
34 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
35 | public DISK_EXTENT[] Extents;//TODO: Если дисков больше 10, то метод DeviceIoControl вернёт ERROR_MORE_DATA.
36 | }
37 |
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/DeviceIOControl/Native/WinApi.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace DeviceIOControl.Native
4 | {
5 | /// Native structures
6 | public struct WinApi
7 | {
8 | /// The MEDIA_TYPE enumerators are used in conjunction with the IOCTL_DISK_FORMAT_TRACKS request to format the specified set of contiguous tracks on the disk.
9 | /// Removable disks include zip drivers, jaz drives, magneto-optical (MO) drives, and LS-120 floppies as well as regular floppies.
10 | public enum MEDIA_TYPE
11 | {
12 | /// Format is unknown
13 | Unknown,
14 | /// 5.25", 1.2MB, 512 bytes/sector
15 | F5_1Pt2_512,
16 | /// 3.5", 1.44MB, 512 bytes/sector
17 | F3_1Pt44_512,
18 | /// 3.5", 2.88MB, 512 bytes/sector
19 | F3_2Pt88_512,
20 | /// 3.5", 20.8MB, 512 bytes/sector
21 | F3_20Pt8_512,
22 | /// 3.5", 720KB, 512 bytes/sector
23 | F3_720_512,
24 | /// 5.25", 360KB, 512 bytes/sector
25 | F5_360_512,
26 | /// 5.25", 320KB, 512 bytes/sector
27 | F5_320_512,
28 | /// 5.25", 320KB, 1024 bytes/sector
29 | F5_320_1024,
30 | /// 5.25", 180KB, 512 bytes/sector
31 | F5_180_512,
32 | /// 5.25", 160KB, 512 bytes/sector
33 | F5_160_512,
34 | /// Removable media other than floppy
35 | RemovableMedia,
36 | /// Fixed hard disk media
37 | FixedMedia,
38 | /// 3.5", 120M Floppy
39 | F3_120M_512,
40 | /// 3.5" , 640KB, 512 bytes/sector
41 | F3_640_512,
42 | /// 5.25", 640KB, 512 bytes/sector
43 | F5_640_512,
44 | /// 5.25", 720KB, 512 bytes/sector
45 | F5_720_512,
46 | /// 3.5" , 1.2Mb, 512 bytes/sector
47 | F3_1Pt2_512,
48 | /// 3.5" , 1.23Mb, 1024 bytes/sector
49 | F3_1Pt23_1024,
50 | /// 5.25", 1.23MB, 1024 bytes/sector
51 | F5_1Pt23_1024,
52 | /// 3.5" MO 128Mb 512 bytes/sector
53 | F3_128Mb_512,
54 | /// 3.5" MO 230Mb 512 bytes/sector
55 | F3_230Mb_512,
56 | /// 8", 256KB, 128 bytes/sector
57 | F8_256_128,
58 | /// 3.5", 200M Floppy (HiFD)
59 | F3_200Mb_512,
60 | /// 3.5", 240Mb Floppy (HiFD)
61 | F3_240M_512,
62 | /// 3.5", 32Mb Floppy
63 | F3_32M_512,
64 | }
65 |
66 | /// Define the method codes for how buffers are passed for I/O and FS controls
67 | public enum METHOD : byte
68 | {
69 | /// Specifies the buffered I/O method, which is typically used for transferring small amounts of data per request.
70 | BUFFERED = 0,
71 | /// Specifies the direct I/O method, which is typically used for reading or writing large amounts of data, using DMA or PIO, that must be transferred quickly.
72 | IN_DIRECT = 1,
73 | /// Specifies the direct I/O method, which is typically used for reading or writing large amounts of data, using DMA or PIO, that must be transferred quickly.
74 | OUT_DIRECT = 2,
75 | ///
76 | /// Specifies neither buffered nor direct I/O.
77 | /// The I/O manager does not provide any system buffers or MDLs.
78 | /// The IRP supplies the user-mode virtual addresses of the input and output buffers that were specified to DeviceIoControl or IoBuildDeviceIoControlRequest, without validating or mapping them.
79 | ///
80 | NEITHER = 3,
81 | }
82 |
83 | /// The SID_NAME_USE enumeration contains values that specify the type of a security identifier (SID).
84 | public enum SID_NAME_USE
85 | {
86 | /// A user SID.
87 | SidTypeUser = 1,
88 | /// A group SID.
89 | SidTypeGroup,
90 | /// A domain SID.
91 | SidTypeDomain,
92 | /// An alias SID.
93 | SidTypeAlias,
94 | /// A SID for a well-known group.
95 | SidTypeWellKnownGroup,
96 | /// A SID for a deleted account.
97 | SidTypeDeletedAccount,
98 | /// A SID that is not valid.
99 | SidTypeInvalid,
100 | /// A SID of unknown type.
101 | SidTypeUnknown,
102 | /// A SID for a computer.
103 | SidTypeComputer,
104 | /// A mandatory integrity label SID.
105 | SidTypeLabel,
106 | }
107 |
108 | /// Access flags
109 | [Flags]
110 | public enum FILE_ACCESS_FLAGS : uint
111 | {
112 | /// Read
113 | GENERIC_READ = 0x80000000,
114 | /// Write
115 | GENERIC_WRITE = 0x40000000,
116 | /// Execute
117 | GENERIC_EXECUTE = 0x20000000,
118 | /// All
119 | GENERIC_ALL = 0x10000000,
120 | }
121 |
122 | /// Share
123 | [Flags]
124 | public enum FILE_SHARE : uint
125 | {
126 | ///
127 | /// Enables subsequent open operations on a file or device to request read access.
128 | /// Otherwise, other processes cannot open the file or device if they request read access.
129 | ///
130 | READ = 0x00000001,
131 | ///
132 | /// Enables subsequent open operations on a file or device to request write access.
133 | /// Otherwise, other processes cannot open the file or device if they request write access.
134 | ///
135 | WRITE = 0x00000002,
136 | ///
137 | /// Enables subsequent open operations on a file or device to request delete access.
138 | /// Otherwise, other processes cannot open the file or device if they request delete access.
139 | /// If this flag is not specified, but the file or device has been opened for delete access, the function fails.
140 | ///
141 | DELETE = 0x00000004,
142 | }
143 |
144 | /// Defines the access check value for any access.
145 | [Flags]
146 | public enum FILE_ACCESS : ushort
147 | {
148 | /// Request all access.
149 | ANY_ACCESS = 0,
150 | /// Request read access.
151 | /// Can be used with FILE_WRITE_ACCESS.
152 | READ_ACCESS = 0x0001,
153 | /// Request write access.
154 | /// Can be used with FILE_READ_ACCESS.
155 | WRITE_ACCESS = 0x0002,
156 | }
157 |
158 | /// Disposition
159 | public enum CreateDisposition : uint
160 | {
161 | /// Create new
162 | CREATE_NEW = 1,
163 | /// Create always
164 | CREATE_ALWAYS = 2,
165 | /// Open exising
166 | OPEN_EXISTING = 3,
167 | /// Open always
168 | OPEN_ALWAYS = 4,
169 | /// Truncate existing
170 | TRUNCATE_EXISTING = 5,
171 | }
172 |
173 | /// Drive types
174 | public enum DRIVE : uint
175 | {
176 | /// The drive type cannot be determined.
177 | UNKNOWN = 0,
178 | /// The root directory does not exist.
179 | NO_ROOT_DIR = 1,
180 | /// The drive can be removed from the drive.
181 | REMOVABLE = 2,
182 | /// The disk cannot be removed from the drive.
183 | FIXED = 3,
184 | /// The drive is a remote (network) drive.
185 | REMOTE = 4,
186 | /// The drive is a CD-ROM drive.
187 | CDROM = 5,
188 | /// The drive is a RAM disk.
189 | RAMDISK = 6,
190 | }
191 | }
192 | }
193 |
--------------------------------------------------------------------------------
/DeviceIOControl/PinnedBufferReader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Runtime.InteropServices;
4 | using System.Security.Permissions;
5 |
6 | namespace DeviceIOControl
7 | {
8 | [DefaultProperty("Length")]
9 | public class PinnedBufferReader : IDisposable
10 | {
11 | private GCHandle _gcHandle;
12 |
13 | private IntPtr _gcPointer;
14 |
15 | private readonly byte[] _buffer;
16 |
17 | private byte[] Buffer => _buffer;
18 |
19 | private IntPtr Handle => _gcPointer;
20 |
21 | public byte this[uint index] => Buffer[index];
22 |
23 | public int Length => Buffer.Length;
24 |
25 | //[EnvironmentPermission(SecurityAction.LinkDemand, Unrestricted = true)]
26 | public PinnedBufferReader(byte[] buffer)
27 | {
28 | _buffer = buffer;
29 | _gcHandle = GCHandle.Alloc(_buffer, GCHandleType.Pinned);
30 | _gcPointer = _gcHandle.AddrOfPinnedObject();
31 | }
32 |
33 | //[EnvironmentPermission(SecurityAction.LinkDemand, Unrestricted = true)]
34 | public T BytesToStructure(ref uint padding) where T : struct
35 | {
36 | int length;
37 | T result = BytesToStructure(padding, out length);
38 | padding += (uint)length;
39 | return result;
40 | }
41 |
42 | //[EnvironmentPermission(SecurityAction.LinkDemand, Unrestricted = true)]
43 | public T BytesToStructure(uint padding) where T : struct
44 | {
45 | int length;
46 | return BytesToStructure(padding, out length);
47 | }
48 |
49 | //[EnvironmentPermission(SecurityAction.LinkDemand, Unrestricted = true)]
50 | public T BytesToStructure(uint padding, out int length) where T : struct
51 | {
52 | length = Marshal.SizeOf(typeof(T));
53 | if (length + padding > Buffer.Length)
54 | {
55 | throw new ArgumentOutOfRangeException("padding");
56 | }
57 | IntPtr ptr = ((padding == 0) ? Handle : new IntPtr(Handle.ToInt64() + padding));
58 | return (T)Marshal.PtrToStructure(ptr, typeof(T));
59 | }
60 |
61 | public string BytesToStringUni(uint padding)
62 | {
63 | int length;
64 | return BytesToStringUni(padding, out length);
65 | }
66 |
67 | public string BytesToStringUni(ref uint padding)
68 | {
69 | int length;
70 | string result = BytesToStringUni(padding, out length);
71 | padding += (uint)length;
72 | return result;
73 | }
74 |
75 | public string BytesToStringUni(uint padding, out int length)
76 | {
77 | if (padding > Buffer.Length)
78 | {
79 | throw new ArgumentOutOfRangeException("padding");
80 | }
81 | IntPtr ptr = ((padding == 0) ? Handle : new IntPtr(Handle.ToInt64() + padding));
82 | string text = Marshal.PtrToStringUni(ptr);
83 | length = (text.Length + 1) * Marshal.SystemDefaultCharSize;
84 | return text;
85 | }
86 |
87 | public string BytesToStringAnsi(uint padding)
88 | {
89 | int length;
90 | return BytesToStringAnsi(padding, out length);
91 | }
92 |
93 | public string BytesToStringAnsi(ref uint padding)
94 | {
95 | int length;
96 | string result = BytesToStringAnsi(padding, out length);
97 | padding += (uint)length;
98 | return result;
99 | }
100 |
101 | public string BytesToStringAnsi(uint padding, out int length)
102 | {
103 | if (padding > Buffer.Length)
104 | {
105 | throw new ArgumentOutOfRangeException("padding");
106 | }
107 | IntPtr ptr = ((padding == 0) ? Handle : new IntPtr(Handle.ToInt64() + padding));
108 | string text = Marshal.PtrToStringAnsi(ptr);
109 | length = text.Length + 1;
110 | return text;
111 | }
112 |
113 | public byte[] GetBytes(uint padding, uint length)
114 | {
115 | if (padding + length > Buffer.Length)
116 | {
117 | throw new ArgumentOutOfRangeException("padding");
118 | }
119 | byte[] array = new byte[length];
120 | Array.Copy(Buffer, padding, array, 0L, array.Length);
121 | return array;
122 | }
123 |
124 | public static T BytesToStructure(byte[] buffer, ref uint padding) where T : struct
125 | {
126 | int length;
127 | T result = BytesToStructure(buffer, padding, out length);
128 | padding += (uint)length;
129 | return result;
130 | }
131 |
132 | public static T BytesToStructure(byte[] buffer, uint padding) where T : struct
133 | {
134 | int length;
135 | return BytesToStructure(buffer, padding, out length);
136 | }
137 |
138 | public static T BytesToStructure(byte[] buffer, uint padding, out int length) where T : struct
139 | {
140 | using PinnedBufferReader pinnedBufferReader = new PinnedBufferReader(buffer);
141 | return pinnedBufferReader.BytesToStructure(padding, out length);
142 | }
143 |
144 | public static string BytesToStringUni(byte[] buffer, uint padding, out int length)
145 | {
146 | using PinnedBufferReader pinnedBufferReader = new PinnedBufferReader(buffer);
147 | return pinnedBufferReader.BytesToStringUni(padding, out length);
148 | }
149 |
150 | public static string BytesToStringAnsi(byte[] buffer, uint padding, out int length)
151 | {
152 | using PinnedBufferReader pinnedBufferReader = new PinnedBufferReader(buffer);
153 | return pinnedBufferReader.BytesToStringAnsi(padding, out length);
154 | }
155 |
156 | public static byte[] StructureToArray(T structure) where T : struct
157 | {
158 | int num = Marshal.SizeOf((object)structure);
159 | byte[] array = new byte[num];
160 | IntPtr intPtr = Marshal.AllocHGlobal(num);
161 | try
162 | {
163 | Marshal.StructureToPtr((object)structure, intPtr, fDeleteOld: true);
164 | Marshal.Copy(intPtr, array, 0, num);
165 | return array;
166 | }
167 | finally
168 | {
169 | Marshal.FreeHGlobal(intPtr);
170 | }
171 | }
172 |
173 | public void Dispose()
174 | {
175 | Dispose(disposing: true);
176 | GC.SuppressFinalize(this);
177 | }
178 |
179 | protected virtual void Dispose(bool disposing)
180 | {
181 | if (disposing && _gcHandle.IsAllocated)
182 | {
183 | _gcHandle.Free();
184 | }
185 | }
186 | }
187 | }
188 |
--------------------------------------------------------------------------------
/DeviceIOControl/Properties/PublishProfiles/FolderProfile.pubxml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | Release
8 | Any CPU
9 | bin\Release\net5.0\publish\
10 | FileSystem
11 | net5.0
12 | win-x64
13 | true
14 | False
15 | False
16 | False
17 |
18 |
--------------------------------------------------------------------------------
/DeviceIOControl/Properties/PublishProfiles/FolderProfile.pubxml.user:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | True|2021-05-19T13:09:37.2377369Z;
8 |
9 |
--------------------------------------------------------------------------------
/DeviceIOControl/Storage/Storage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using System.ComponentModel;
4 | using DeviceIOControl.Native;
5 |
6 | namespace DeviceIOControl.Storage
7 | {
8 | /// Storage IO control commands
9 | public class Storage
10 | {
11 | #region Fields
12 | private readonly DeviceIoControl _device;
13 | private Properties _properties;
14 | private StorageApi.STORAGE_DEVICE_NUMBER? _deviceNumber;
15 | private StorageApi.GET_MEDIA_TYPES? _mediaTypesEx;
16 | private StorageApi.MEDIA_SERIAL_NUMBER_DATA? _serialNumber;
17 | private StorageApi.STORAGE_READ_CAPACITY? _readCapacity;
18 | #endregion Fields
19 |
20 | /// Device
21 | private DeviceIoControl Device { get { return this._device; } }
22 |
23 | /// Device descriptors
24 | public Properties Properties
25 | {
26 | get
27 | {
28 | return this._properties == null
29 | ? this._properties = new Properties(this.Device)
30 | : this._properties;
31 | }
32 | }
33 |
34 | /// Contains information about a device.
35 | public StorageApi.STORAGE_DEVICE_NUMBER DeviceNumber
36 | {
37 | get
38 | {
39 | return (this._deviceNumber == null
40 | ? this._deviceNumber = this.Device.IoControl(
41 | Constant.IOCTL_STORAGE.GET_DEVICE_NUMBER,
42 | null)
43 | : this._deviceNumber).Value;
44 | }
45 | }
46 | /// Queries the USB generic parent driver for the serial number of a USB device.
47 | ///
48 | /// If a USB device has a CSM-1 content security interface, a USB client driver can query for its serial number using this request.
49 | /// USB client drivers that help implement a digital rights management (DRM) system can use this information to ensure that only legitimate customers have access to digitized intellectual property.
50 | ///
51 | public StorageApi.MEDIA_SERIAL_NUMBER_DATA SerialNumber
52 | {
53 | get
54 | {
55 | return (this._serialNumber == null
56 | ? this._serialNumber = this.Device.IoControl(
57 | Constant.IOCTL_STORAGE.GET_MEDIA_SERIAL_NUMBER,
58 | null)
59 | : this._serialNumber).Value;
60 | }
61 | }
62 |
63 | /// Contains information about the media types supported by a device.
64 | public StorageApi.GET_MEDIA_TYPES MediaTypesEx
65 | {
66 | get
67 | {
68 | return (this._mediaTypesEx == null
69 | ? this._mediaTypesEx = this.Device.IoControl(
70 | Constant.IOCTL_STORAGE.GET_MEDIA_TYPES_EX,
71 | null)
72 | : this._mediaTypesEx).Value;
73 | }
74 | }
75 |
76 | /// Retrieves the geometry information for the device.
77 | public StorageApi.STORAGE_READ_CAPACITY ReadCapacity
78 | {
79 | get
80 | {
81 | return (this._readCapacity == null
82 | ? this._readCapacity = this.Device.IoControl(
83 | Constant.IOCTL_STORAGE.READ_CAPACITY, null)
84 | : this._readCapacity).Value;
85 | }
86 | }
87 |
88 | /// Determines whether the media has changed on a removable-media device that the caller has opened for read or write access.
89 | public Boolean CheckVerify
90 | {
91 | get
92 | {
93 | Boolean result = this.Device.IoControl(Constant.IOCTL_STORAGE.CHECK_VERIFY);
94 | if (result)
95 | return true;
96 | else
97 | {
98 | Int32 error = Marshal.GetLastWin32Error();
99 | if (error == (Int32)Constant.ERROR.NOT_READY)
100 | return false;
101 | else throw new Win32Exception(error);
102 | }
103 | }
104 | }
105 | /// Determines whether the media has changed on a removable-media device - the caller has opened with FILE_READ_ATTRIBUTES.
106 | public Boolean CheckVerify2
107 | {
108 | get
109 | {
110 | Boolean result = this.Device.IoControl(Constant.IOCTL_STORAGE.CHECK_VERIFY2);
111 | if (result)
112 | return true;
113 | else
114 | {
115 | Int32 error = Marshal.GetLastWin32Error();
116 | if (error == (Int32)Constant.ERROR.NOT_READY)
117 | return false;
118 | else throw new Win32Exception(error);
119 | }
120 | }
121 | }
122 |
123 | /// Create instance of storage IO commands class
124 | /// Device
125 | internal Storage(DeviceIoControl device)
126 | {
127 | this._device = device;
128 | }
129 |
130 | /// Enables or disables the mechanism that ejects media, for those devices possessing that locking capability.
131 | /// Prevent device to eject media
132 | public void PreventMediaRemoval(Boolean prevent)
133 | {
134 | this.Device.IoControl(Constant.IOCTL_STORAGE.MEDIA_REMOVAL, prevent);
135 | }
136 |
137 | /// Causes the device to eject the media if the device supports ejection capabilities.
138 | /// Device exception
139 | public void EjectMedia()
140 | {
141 | this.Device.IoControl(Constant.IOCTL_STORAGE.EJECT_MEDIA, null);
142 | }
143 |
144 | /// Retrieves the hotplug configuration of the specified device.
145 | /// Hotplug information for a device.
146 | public StorageApi.STORAGE_HOTPLUG_INFO GetHotPlugInfo()
147 | {
148 | return this.Device.IoControl(
149 | Constant.IOCTL_STORAGE.GET_HOTPLUG_INFO,
150 | null);
151 | }
152 |
153 | /// Polls for a prediction of device failure.
154 | /// Report whether a device is currently predicting a failure.
155 | public StorageApi.STORAGE_PREDICT_FAILURE PredictFailure()
156 | {
157 | return this.Device.IoControl(
158 | Constant.IOCTL_STORAGE.PREDICT_FAILURE,
159 | null);
160 | }
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/DeviceIOControl/Utils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using System.Globalization;
4 |
5 | namespace DeviceIOControl
6 | {
7 | /// Utils
8 | public struct Utils
9 | {
10 | private const Int64 FileSize = 1024;
11 | private static String[] FileSizeType = new String[] { "bytes", "Kb", "Mb", "Gb", };
12 | /// Swap odd/even bytes in array of USHORTS
13 | /// Buffer
14 | /// Start position
15 | /// Count
16 | /// buffer is null
17 | /// buffer length is less than start index
18 | /// String
19 | public static String SwapBytes(UInt16[] buffer, UInt64 start, UInt64 count)
20 | {
21 | if (buffer == null)
22 | throw new ArgumentNullException("buffer");
23 | if ((UInt64)buffer.LongLength < start)
24 | throw new ArgumentException("Start index less than buffer length.");
25 |
26 | StringBuilder result = new StringBuilder();
27 | for (UInt64 loop = start; loop < start + count; loop++)
28 | {
29 | Byte[] part = BitConverter.GetBytes((buffer[loop] << 8 | buffer[loop] >> 8));
30 | String zz = Encoding.ASCII.GetString(part, 0, part.Length - 2);
31 | result.Append(zz);
32 | }
33 |
34 | return result.ToString();
35 | }
36 | /// Swap chars in IDREGS array
37 | /// Char buffer
38 | /// buffer is null
39 | /// Swapped string
40 | public static String SwapChars(Char[] buffer)
41 | {
42 | if (buffer == null)
43 | throw new ArgumentNullException("buffer");
44 |
45 | StringBuilder result = new StringBuilder();
46 | for (Int32 loop = 0; loop < buffer.Length; loop += 2)
47 | {
48 | result.Append(buffer[loop + 1]);
49 | result.Append(buffer[loop]);
50 | }
51 | return result.ToString();
52 | }
53 | /// Find highest non-zero bit position
54 | /// Value
55 | /// highest non-zero bit position
56 | /// Bit position
57 | public static Int64 HighBitPos(Int64 value, Int32 maxPos)
58 | {
59 | Int32 pos;
60 | for (pos = maxPos; !(pos < 0 || ((value >> pos) & 1) == 1); pos--) ;
61 | return pos;
62 | }
63 | /// Makes a 32 bit integer from two 16 bit shorts
64 | /// The low order value.
65 | /// The high order value.
66 | ///
67 | public static Int32 MakeDword(UInt16 low, UInt16 high)
68 | {
69 | return (low + (high << 16));
70 | }
71 | /// Convert file size in bytes to string with dimention
72 | /// size in bytes
73 | /// Size with dimention
74 | public static String FileSizeToString(UInt64 length)
75 | {
76 | UInt64 constSize = 1;
77 | Int32 sizePosition = 0;
78 | while (length > constSize * FileSize && sizePosition + 1 < Utils.FileSizeType.Length)
79 | {
80 | constSize *= Utils.FileSize;
81 | sizePosition++;
82 | }
83 | return String.Format(CultureInfo.CurrentUICulture, "{0:n0} {1}", length / constSize, Utils.FileSizeType[sizePosition]);
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/DeviceIOControl/Volume/Volume.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using System.ComponentModel;
4 | using DeviceIOControl.Native;
5 |
6 | namespace DeviceIOControl.Volume
7 | {
8 | /// Volume IO control commands
9 | public class Volume
10 | {
11 | #region Fields
12 | private readonly DeviceIoControl _device;
13 | private Boolean? _isClustered;
14 | private VolumeApi.VOLUME_DISK_EXTENTS? _diskExtents;
15 | #endregion Fields
16 |
17 | /// Device
18 | private DeviceIoControl Device { get { return this._device; } }
19 |
20 | /// Represents a physical location on a disk.
21 | /// Вызов не работает в Windows 7
22 | public VolumeApi.VOLUME_DISK_EXTENTS DiskExtents
23 | {
24 | get
25 | {
26 | if (this._diskExtents == null)
27 | this._diskExtents = this.Device.IoControl(
28 | Constant.IOCTL_VOLUME.GET_VOLUME_DISK_EXTENTS,
29 | null);
30 | return this._diskExtents.Value;
31 | }
32 | }
33 |
34 | /// Determines whether the specified volume is clustered.
35 | /// The volume is offline or Cluster service is not installed.
36 | public Boolean IsClustered
37 | {
38 | get
39 | {
40 | if (this._isClustered == null)
41 | if (this.Device.IoControl(Constant.IOCTL_VOLUME.IS_CLUSTERED)) this._isClustered = true;
42 | else
43 | {
44 | Int32 error = Marshal.GetLastWin32Error();
45 | if (error == (Int32)Constant.ERROR.NO_ERROR)
46 | this._isClustered = false;
47 | else
48 | throw new Win32Exception(error);
49 | }
50 | return this._isClustered.Value;
51 | }
52 | }
53 |
54 | /// Create instance of Volume IO control commands
55 | /// Device
56 | internal Volume(DeviceIoControl device)
57 | {
58 | this._device = device;
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Hardware/Computer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using LibreHardwareMonitor.Hardware;
3 | using Hardware.Windows.RAM;
4 |
5 | namespace Hardware
6 | {
7 | public static class Computer
8 | {
9 | private static LibreHardwareMonitor.Hardware.Computer pc;
10 |
11 | private static ISensor CpuPercentSensor;
12 | private static ISensor CpuTempSensor;
13 |
14 | private static ISensor GpuPercentSensor;
15 | private static ISensor GpuTempSensor;
16 |
17 | private static ISensor GpuRamUsedSensor;
18 |
19 | public static float CPUPercent { get; private set; }
20 | public static float CPUTemp { get; private set; }
21 |
22 | public static float GPUPercent { get; private set; }
23 | public static float GPUTemp { get; private set; }
24 |
25 | public static float GPUTotalRam { get; private set; }
26 | public static float GPUUsedRam { get; private set; }
27 | public static float GPUPercentRam { get; private set; }
28 |
29 | public static double RamTotal { get; private set; }
30 | public static double RamUsed { get; private set; }
31 | public static double RamFree { get; private set; }
32 | public static byte RamPercent { get; private set; }
33 |
34 | static Computer()
35 | {
36 | CPUPercent = 0;
37 | CPUTemp = 0;
38 | GPUPercent = 0;
39 | GPUTemp = 0;
40 | GPUPercentRam = 0;
41 | GPUUsedRam = 0;
42 | }
43 |
44 | private static void SetSensors()
45 | {
46 | foreach (IHardware hardware in pc.Hardware)
47 | {
48 | hardware.Update();
49 |
50 | if (hardware.HardwareType == HardwareType.Motherboard)
51 | {
52 | foreach (IHardware sub in hardware.SubHardware)
53 | {
54 | sub.Update();
55 |
56 | if (sub.HardwareType == HardwareType.SuperIO)
57 | {
58 | foreach (ISensor sensor in sub.Sensors)
59 | {
60 | if (sensor.SensorType == SensorType.Temperature && sensor.Index == 0)
61 | {
62 | CpuTempSensor = sensor;
63 | CpuTempSensor.ValuesTimeWindow = TimeSpan.Zero;
64 | break;
65 | }
66 | }
67 |
68 | break;
69 | }
70 | }
71 | }
72 |
73 | if (hardware.HardwareType == HardwareType.Cpu)
74 | {
75 | foreach (ISensor sensor in hardware.Sensors)
76 | {
77 | if (sensor.SensorType == SensorType.Load && sensor.Index == 0)
78 | {
79 | CpuPercentSensor = sensor;
80 | CpuPercentSensor.ValuesTimeWindow = TimeSpan.Zero;
81 | break;
82 | }
83 | }
84 | }
85 |
86 | if (hardware.HardwareType == HardwareType.GpuNvidia || hardware.HardwareType == HardwareType.GpuAmd)
87 | {
88 | foreach (ISensor sensor in hardware.Sensors)
89 | {
90 | if (sensor.SensorType == SensorType.Load && sensor.Index == 0)
91 | {
92 | GpuPercentSensor = sensor;
93 | GpuPercentSensor.ValuesTimeWindow = TimeSpan.Zero;
94 | }
95 | if (sensor.SensorType == SensorType.Temperature)
96 | {
97 | GpuTempSensor = sensor;
98 | GpuTempSensor.ValuesTimeWindow = TimeSpan.Zero;
99 | }
100 | if (sensor.SensorType == SensorType.SmallData && sensor.Index == 2) GPUTotalRam = sensor.Value.Value;
101 | if (sensor.SensorType == SensorType.SmallData && sensor.Index == 1)
102 | {
103 | GpuRamUsedSensor = sensor;
104 | GpuRamUsedSensor.ValuesTimeWindow = TimeSpan.Zero;
105 | }
106 | }
107 | }
108 | }
109 | }
110 |
111 | public static void Open()
112 | {
113 | if (pc == null)
114 | {
115 | pc = new();
116 | pc.IsCpuEnabled = true;
117 | pc.IsMotherboardEnabled = true;
118 | pc.IsGpuEnabled = true;
119 | pc.Open();
120 | }
121 |
122 | SetSensors();
123 |
124 | RamUpdate();
125 | }
126 |
127 | private static void RamUpdate()
128 | {
129 | double devider = 1073741824;
130 |
131 | MemoryStatusEx msu = new();
132 |
133 | try
134 | { NativeMethods.GlobalMemoryStatusEx(msu); }
135 | catch { return; }
136 |
137 | RamTotal = msu.TotalPhys / devider;
138 | RamFree = msu.AvailPhys / devider;
139 | RamUsed = (msu.TotalPhys - msu.AvailPhys) / devider;
140 | RamPercent = (byte)((msu.TotalPhys - msu.AvailPhys) / (msu.TotalPhys / 100));
141 | }
142 |
143 | public static void Update()
144 | {
145 | try
146 | {
147 | CpuPercentSensor.Hardware.Update();
148 | CPUPercent = CpuPercentSensor.Value.Value;
149 | }
150 | catch { /* ignored */ }
151 |
152 | try
153 | {
154 | CpuTempSensor.Hardware.Update();
155 | CPUTemp = CpuTempSensor.Value.Value;
156 | }
157 | catch { /* ignored */ }
158 |
159 | try
160 | {
161 | GpuPercentSensor.Hardware.Update();
162 | GPUPercent = GpuPercentSensor.Value.Value;
163 | }
164 | catch { /* ignored */ }
165 |
166 | try
167 | {
168 | GpuTempSensor.Hardware.Update();
169 | GPUTemp = GpuTempSensor.Value.Value;
170 | }
171 | catch { /* ignored */ }
172 |
173 | try
174 | {
175 | GpuRamUsedSensor.Hardware.Update();
176 | GPUUsedRam = GpuRamUsedSensor.Value.Value;
177 | }
178 | catch { /* ignored */ }
179 |
180 | GPUPercentRam = GPUUsedRam / (GPUTotalRam / 100);
181 |
182 | RamUpdate();
183 | }
184 |
185 | public static void Close()
186 | {
187 | pc.Close();
188 | }
189 | }
190 | }
191 |
--------------------------------------------------------------------------------
/Hardware/Hardware.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 |
6 |
7 |
8 | AnyCPU
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Hardware/Windows/DeviceIoInfo/Device.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using DeviceIOControl;
3 | using DeviceIOControl.Disc;
4 |
5 | namespace Hardware.Windows.DeviceIoInfo
6 | {
7 | public class Device : IDisposable
8 | {
9 | public short Index { get; set; }
10 | public string Letter { get; set; }
11 | public VendorEnum Vendor;
12 | public string Model { get; set; }
13 | public long TotalSpace { get; set; }
14 | public long FreeSpace { get; set; }
15 | public long UsedSpace { get; set; }
16 | public byte PercentUsedSpace { get; set; }
17 | public float TotalWrite { get; set; }
18 | public byte Health { get; set; }
19 | public bool IsSmart { get; set; }
20 | public float PrevReadIo { get; set; }
21 | public float PrevWriteIo { get; set; }
22 | public DeviceIoControl DeviceControl { get; set; }
23 | public Performance DevicePerformance { get; set; }
24 |
25 | public Device()
26 | {
27 | IsSmart = true;
28 | }
29 |
30 | public void Dispose()
31 | {
32 | DevicePerformance?.Dispose();
33 | DeviceControl?.Dispose();
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Hardware/Windows/DeviceIoInfo/DeviceInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.IO;
5 | using DeviceIOControl;
6 | using DeviceIOControl.Native;
7 | using DeviceIOControl.Disc.Smart;
8 |
9 | namespace Hardware.Windows.DeviceIoInfo
10 | {
11 | public static class DeviceInfo
12 | {
13 | public static float ReadIo { get; private set; }
14 | public static float WriteIo { get; private set; }
15 |
16 | public static List LogicalDrives { get; }
17 |
18 | static DeviceInfo()
19 | {
20 | LogicalDrives = new();
21 | }
22 |
23 | private static void SetDiscCollection()
24 | {
25 | Close();
26 |
27 | IEnumerable logicalDevicesIo = DeviceIoControl.GetLogicalDrives();
28 |
29 | short devIndex = 0;
30 |
31 | foreach (LogicalDrive logical in logicalDevicesIo)
32 | {
33 | if (logical.Type != WinApi.DRIVE.FIXED)
34 | continue;
35 |
36 | Device device = new()
37 | {
38 | Index = devIndex,
39 | Letter = logical.Name,
40 | DeviceControl = new DeviceIoControl(logical.Name)
41 | };
42 |
43 | device.Model = device.DeviceControl.Disc.Smart == null ? new DriveInfo(logical.Name).VolumeLabel :
44 | device.DeviceControl.Disc.Smart.SystemParams.ModelNumber.Trim(' ');
45 |
46 | if (device.Model.Contains("samsung", StringComparison.OrdinalIgnoreCase))
47 | device.Vendor = VendorEnum.Samsung;
48 | else if (device.Model.Contains("kingston", StringComparison.OrdinalIgnoreCase))
49 | device.Vendor = VendorEnum.Kingston;
50 | else if (device.Model.Contains("wdc", StringComparison.OrdinalIgnoreCase))
51 | device.Vendor = VendorEnum.WDC;
52 | else
53 | device.Vendor = VendorEnum.Other;
54 |
55 | device.DevicePerformance = device.DeviceControl.Disc.GetDiscPerformance();
56 | device.PrevReadIo = device.DevicePerformance.QueryPerformanceInfo().BytesRead;
57 | device.PrevWriteIo = device.DevicePerformance.QueryPerformanceInfo().BytesWritten;
58 | device.TotalSpace = new DriveInfo(logical.Name).TotalSize;
59 |
60 | LogicalDrives.Add(device);
61 |
62 | devIndex++;
63 | }
64 | }
65 |
66 | public static bool IsUpdateDiscs()
67 | {
68 | if (LogicalDrives.Count == DeviceIoControl.GetLogicalDrives().Count()) return false;
69 |
70 | SetDiscCollection();
71 |
72 | return true;
73 |
74 | }
75 |
76 | public static void UpdateSizeOfDiscs()
77 | {
78 | if (LogicalDrives == null) SetDiscCollection();
79 |
80 | foreach (Device logic in LogicalDrives)
81 | {
82 | DriveInfo drive = new(logic.Letter);
83 | try
84 | {
85 | logic.TotalSpace = drive.TotalSize;
86 | logic.FreeSpace = drive.TotalFreeSpace;
87 | logic.UsedSpace = drive.TotalSize - drive.AvailableFreeSpace;
88 | logic.PercentUsedSpace = Convert.ToByte(logic.UsedSpace / (logic.TotalSpace / 100));
89 | }
90 | catch (DriveNotFoundException)
91 | {
92 | throw new DriveNotFoundException();
93 | }
94 | }
95 | }
96 |
97 | public static void UpdateInfoOfDiscs()
98 | {
99 | if (LogicalDrives == null) SetDiscCollection();
100 |
101 | foreach (Device dev in LogicalDrives)
102 | {
103 | SmartInfoCollection smart = dev.DeviceControl.Disc.Smart;
104 |
105 | if (smart == null) continue;
106 |
107 | DiscApi.DRIVEATTRIBUTE[] driveAttributes = smart.GetAttributes();
108 |
109 | foreach (DiscApi.DRIVEATTRIBUTE attribute in driveAttributes)
110 | {
111 | if (dev.Vendor == VendorEnum.Samsung)
112 | {
113 | if (attribute.bAttrID == 177) dev.Health = attribute.bAttrValue;
114 | if (attribute.bAttrID == 241) dev.TotalWrite = attribute.RawValue / (float)int.MaxValue;
115 | }
116 |
117 | if (dev.Vendor == VendorEnum.Kingston)
118 | {
119 | if (attribute.bAttrID == 231) dev.Health = attribute.bAttrValue;
120 | if (attribute.bAttrID == 241) dev.TotalWrite = attribute.RawValue / 1024f;
121 | }
122 | }
123 | }
124 | }
125 |
126 | public static void PerfomanceDiskUpdate(short index)
127 | {
128 | DiscApi.DISK_PERFORMANCE dIskPerformance = LogicalDrives[index].DevicePerformance.QueryPerformanceInfo();
129 |
130 | ReadIo = (dIskPerformance.BytesRead - LogicalDrives[index].PrevReadIo) / 1000000;
131 | WriteIo = (dIskPerformance.BytesWritten - LogicalDrives[index].PrevWriteIo) / 1000000;
132 |
133 | LogicalDrives[index].PrevReadIo = dIskPerformance.BytesRead;
134 | LogicalDrives[index].PrevWriteIo = dIskPerformance.BytesWritten;
135 | }
136 |
137 | public static void Close()
138 | {
139 | foreach (Device dev in LogicalDrives)
140 | {
141 | dev.Dispose();
142 | }
143 |
144 | LogicalDrives.Clear();
145 | }
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/Hardware/Windows/DeviceIoInfo/VendorEnum.cs:
--------------------------------------------------------------------------------
1 | namespace Hardware.Windows.DeviceIoInfo
2 | {
3 | public enum VendorEnum : byte
4 | {
5 | Samsung,
6 | Kingston,
7 | WDC,
8 | Other
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Hardware/Windows/Network/Adapter.cs:
--------------------------------------------------------------------------------
1 | namespace Hardware.Windows.Network
2 | {
3 | public class Adapter
4 | {
5 | public string Name { get; set; }
6 | public string ID { get; set; }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/Hardware/Windows/Network/NetworkInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Net.NetworkInformation;
4 |
5 | namespace Hardware.Windows.Network
6 | {
7 | public static class NetworkInfo
8 | {
9 | private static int InterfaceIndex;
10 | private static string ID;
11 |
12 | public static string InterfaceID
13 | {
14 | get { return ID; }
15 | set
16 | {
17 | GetInterfaceIndex(value);
18 | ID = value;
19 | }
20 | }
21 | public static long ByteReceived { get; set; }
22 | public static long ByteSend { get; set; }
23 |
24 | public static List GetInterface()
25 | {
26 | List adapters = new List();
27 |
28 | NetworkInterface[] networks = NetworkInterface.GetAllNetworkInterfaces();
29 |
30 | foreach (NetworkInterface net in networks)
31 | {
32 | if (net.Speed != 0)
33 | {
34 | Adapter adapter = new Adapter();
35 | adapter.Name = net.Name;
36 | adapter.ID = net.Id;
37 |
38 | adapters.Add(adapter);
39 | }
40 | }
41 |
42 | return adapters;
43 | }
44 |
45 | private static void GetInterfaceIndex(string id)
46 | {
47 | if (id == null) return;
48 |
49 | NetworkInterface[] networks = NetworkInterface.GetAllNetworkInterfaces();
50 |
51 | for (byte b = 0; b < networks.Length; b++)
52 | {
53 | if (networks[b].Id.Contains(id))
54 | {
55 | InterfaceIndex = b;
56 | break;
57 | }
58 | }
59 | }
60 |
61 | public static void SpeedUpdate()
62 | {
63 | IPv4InterfaceStatistics statistics = NetworkInterface.GetAllNetworkInterfaces()[InterfaceIndex].GetIPv4Statistics();
64 |
65 | ByteReceived = statistics.BytesReceived;
66 | ByteSend = statistics.BytesSent;
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Hardware/Windows/RAM/MemoryStatusEx.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace Hardware.Windows.RAM
4 | {
5 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
6 | class MemoryStatusEx
7 | {
8 | public uint dwLength;
9 | public uint dwMemoryLoad;
10 | public ulong TotalPhys;
11 | public ulong AvailPhys;
12 | public ulong TotalPageFile;
13 | public ulong AvailPageFile;
14 | public ulong TotalVirtual;
15 | public ulong AvailVirtual;
16 | public ulong AvailExtendedVirtual;
17 |
18 | public MemoryStatusEx()
19 | {
20 | dwLength = (uint)Marshal.SizeOf(typeof(MemoryStatusEx));
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Hardware/Windows/RAM/NativeMethods.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace Hardware.Windows.RAM
4 | {
5 | static class NativeMethods
6 | {
7 | const string KernelDll = "kernel32.dll";
8 |
9 | [return: MarshalAs(UnmanagedType.Bool)]
10 | [DllImport(KernelDll, CharSet = CharSet.Auto, SetLastError = true)]
11 | public static extern bool GlobalMemoryStatusEx([In, Out] MemoryStatusEx lpBuffer);
12 |
13 | [return: MarshalAs(UnmanagedType.Bool)]
14 | [DllImport(KernelDll)]
15 | public static extern bool GetPhysicallyInstalledSystemMemory(out ulong totalMemoryInKilobytes);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 FanIT
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SysMonAvalonia
2 | SysMonAvalonia - 3 desktop widgets for Windows.
3 | - Disks widgets - Showing a list of logical disks in Windows with informations about total/used size, model, speed read/write and health, total write for ssd.
4 | - Combo widgets - Showing system informations cpu, ram, video and network.
5 | - Weather widgets - Showing a current, forecast hours and forecast days weather. The widget have 4 weather providers.
6 |
7 |  
8 |
9 | ## What use for the GUI?
10 | The widgets use Avalonia project for the GUI.
11 |
12 | ## What side projects does the project use?
13 | - [LibreHardwareMonitorLib](https://github.com/LibreHardwareMonitor/LibreHardwareMonitor) for showing cpu, gpu load and temperatures.
14 | - [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json) for work with json.
15 | - [DeviceIoControl assembly](https://github.com/DKorablin/DeviceIoControl#deviceiocontrol-assembly) for getting SMART date and speed read/write a disks.
16 | - [LiveCharts2](https://github.com/beto-rodriguez/LiveCharts2) display real time charts for cpu, ram, gpu, network and device io.
17 |
--------------------------------------------------------------------------------
/SysMonAvalonia.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.31515.178
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SysMonAvalonia", "SysMonAvalonia\SysMonAvalonia.csproj", "{8BF3DB5F-1B8B-44DC-BEBA-F5AD0A830724}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hardware", "Hardware\Hardware.csproj", "{A7EF0D95-5A28-4A0A-9EA0-E5965B228ABF}"
9 | EndProject
10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DeviceIOControl", "DeviceIOControl\DeviceIOControl.csproj", "{2517850D-ACC6-4005-BC06-9E380D2D4066}"
11 | EndProject
12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Weather", "Weather\Weather.csproj", "{B4D05221-FCE1-4C7C-9484-B5F41AB8DD2D}"
13 | EndProject
14 | Global
15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
16 | Debug|Any CPU = Debug|Any CPU
17 | Release|Any CPU = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
20 | {8BF3DB5F-1B8B-44DC-BEBA-F5AD0A830724}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {8BF3DB5F-1B8B-44DC-BEBA-F5AD0A830724}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {8BF3DB5F-1B8B-44DC-BEBA-F5AD0A830724}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {8BF3DB5F-1B8B-44DC-BEBA-F5AD0A830724}.Release|Any CPU.Build.0 = Release|Any CPU
24 | {A7EF0D95-5A28-4A0A-9EA0-E5965B228ABF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25 | {A7EF0D95-5A28-4A0A-9EA0-E5965B228ABF}.Debug|Any CPU.Build.0 = Debug|Any CPU
26 | {A7EF0D95-5A28-4A0A-9EA0-E5965B228ABF}.Release|Any CPU.ActiveCfg = Release|Any CPU
27 | {A7EF0D95-5A28-4A0A-9EA0-E5965B228ABF}.Release|Any CPU.Build.0 = Release|Any CPU
28 | {2517850D-ACC6-4005-BC06-9E380D2D4066}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
29 | {2517850D-ACC6-4005-BC06-9E380D2D4066}.Debug|Any CPU.Build.0 = Debug|Any CPU
30 | {2517850D-ACC6-4005-BC06-9E380D2D4066}.Release|Any CPU.ActiveCfg = Release|Any CPU
31 | {2517850D-ACC6-4005-BC06-9E380D2D4066}.Release|Any CPU.Build.0 = Release|Any CPU
32 | {B4D05221-FCE1-4C7C-9484-B5F41AB8DD2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
33 | {B4D05221-FCE1-4C7C-9484-B5F41AB8DD2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
34 | {B4D05221-FCE1-4C7C-9484-B5F41AB8DD2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
35 | {B4D05221-FCE1-4C7C-9484-B5F41AB8DD2D}.Release|Any CPU.Build.0 = Release|Any CPU
36 | EndGlobalSection
37 | GlobalSection(SolutionProperties) = preSolution
38 | HideSolutionNode = FALSE
39 | EndGlobalSection
40 | GlobalSection(ExtensibilityGlobals) = postSolution
41 | SolutionGuid = {920ACC45-0FCC-42B8-A052-9666687C2277}
42 | EndGlobalSection
43 | EndGlobal
44 |
--------------------------------------------------------------------------------
/SysMonAvalonia/App.axaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/SysMonAvalonia/App.axaml.cs:
--------------------------------------------------------------------------------
1 | using Avalonia;
2 | using Avalonia.Controls.ApplicationLifetimes;
3 | using Avalonia.Markup.Xaml;
4 | using SysMonAvalonia.Localization;
5 | using SysMonAvalonia.Data;
6 | using SysMonAvalonia.Models;
7 | using SysMonAvalonia.Services;
8 |
9 | namespace SysMonAvalonia
10 | {
11 | public class App : Application
12 | {
13 | public override void Initialize()
14 | {
15 | AvaloniaXamlLoader.Load(this);
16 |
17 | SettingModel.Load();
18 |
19 | Language.Load(SettingData.CurrentSetting.Culture);
20 |
21 | AppService.ChangeStyles();
22 | }
23 |
24 | public override void OnFrameworkInitializationCompleted()
25 | {
26 | if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
27 | {
28 | desktop.Exit += (sender, args) => SettingModel.Save();
29 |
30 | AppService.ShowWidgets(desktop);
31 | }
32 |
33 | base.OnFrameworkInitializationCompleted();
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/Fonts/SegoeUILight.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/Fonts/SegoeUILight.ttf
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/Locale/en.json:
--------------------------------------------------------------------------------
1 | { "Close":"Close",
2 | "Settings":"Settings",
3 | "Mb":"Mb",
4 | "Gb":"Gb",
5 | "Tb":"Tb",
6 | "Mbit":"Mbit/s",
7 | "Mbyte":"MB/s",
8 | "Health":"Health",
9 | "Write":"Write",
10 | "ReadIO":"Read",
11 | "WriteIO":"Write",
12 | "CpuHeader":"CPU",
13 | "GpuHeader":"GPU",
14 | "RamHeader":"RAM",
15 | "Download":"Network (Down)",
16 | "Upload":"Network (Up)",
17 | "Adapters":"Adapters",
18 | "ApparTempDesc":"Feel like",
19 | "WindSpeedDesc":"Wind",
20 | "CloudCoverDesc":"Cloudy",
21 | "ChanceOfRain":"Probability of precip",
22 | "HumidityDesc":"Humidity",
23 | "Pressure":"mm Hg",
24 | "PressureDesc":"Pressure",
25 | "UVIndexDesc":"UV-Index",
26 | "UVIndexLow":"Low",
27 | "UVIndexMedium":"Medium",
28 | "UVIndexHigh":"High",
29 | "UVIndexVeryHigh":"Very high",
30 | "UVIndexExtrem":"Extrem",
31 | "WindUnitKmH":"km/h",
32 | "WindUnitMH":"m/h",
33 | "WindUnitMS":"m/s",
34 | "WindDirDesc0":"N",
35 | "WindDirDesc22":"NNE",
36 | "WindDirDesc45":"NE",
37 | "WindDirDesc67":"ENE",
38 | "WindDirDesc90":"E",
39 | "WindDirDesc112":"ESE",
40 | "WindDirDesc135":"SE",
41 | "WindDirDesc157":"SSE",
42 | "WindDirDesc180":"S",
43 | "WindDirDesc202":"SSW",
44 | "WindDirDesc225":"SW",
45 | "WindDirDesc247":"WSW",
46 | "WindDirDesc270":"W",
47 | "WindDirDesc292":"WNW",
48 | "WindDirDesc315":"NW",
49 | "WindDirDesc337":"NNW",
50 | "WaterTempDesc":"Water",
51 | "SunsetDesc":"Sunset",
52 | "SunriseDesc":"Sunrise",
53 | "CityDesc":"City",
54 | "LastUpdateDesc":"Update at",
55 | "Hourly":"Hourly",
56 | "Daily":"Daily",
57 | "Update":"Update",
58 | "Providers":"Providers of weather",
59 | "Time":"Time",
60 | "GenTabSetting":"General",
61 | "Network":"Network",
62 | "LangSetting":"Language",
63 | "Russia":"Russian",
64 | "English":"English",
65 | "WidgSetting":"Widgets",
66 | "DiscsSetting":"Discs",
67 | "ComboSetting":"Combo",
68 | "WeatherSetting":"Weather",
69 | "ApiKeySettings":"API key",
70 | "EnterCityWM":"Enter name of city",
71 | "AutostartHeaderSetting":"Autostart",
72 | "AutostartTogle":"Autostart with Windows",
73 | "LocationSetting":"Location",
74 | "Themes":"Themes",
75 | "Dark":"Dark",
76 | "Light":"Light",
77 | "NetUnit":"Network units",
78 | "MbitSettings":"Megabits per second (Mbit/s)",
79 | "MbyteSettings":"Megabyts per second (MByte/s)",
80 | "Cancel":"Cancel",
81 | }
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/Locale/ru.json:
--------------------------------------------------------------------------------
1 | { "Close":"Закрыть",
2 | "Settings":"Настройки",
3 | "Mb":"Мб",
4 | "Gb":"Гб",
5 | "Tb":"Тб",
6 | "Mbit":"Мбит/с",
7 | "Mbyte":"МБ/с",
8 | "Health":"Здоровье",
9 | "Write":"Записано",
10 | "ReadIO":"Чтение",
11 | "WriteIO":"Запись",
12 | "CpuHeader":"ЦП",
13 | "GpuHeader":"ГПУ",
14 | "RamHeader":"ОЗУ",
15 | "Adapters":"Адаптеры",
16 | "ApparTempDesc":"По ощущению",
17 | "WindSpeedDesc":"Ветер",
18 | "CloudCoverDesc":"Облачность",
19 | "ChanceOfRain":"Вероятность осадков",
20 | "HumidityDesc":"Влажность",
21 | "Pressure":"мм. рт. ст",
22 | "PressureDesc":"Давление",
23 | "UVIndexDesc":"УФ-индекс",
24 | "UVIndexLow":"Низкий",
25 | "UVIndexMedium":"Умеренный",
26 | "UVIndexHigh":"Высокий",
27 | "UVIndexVeryHigh":"Очень высокий",
28 | "UVIndexExtrem":"Экстримальный",
29 | "WindUnitKmH":"км/ч",
30 | "WindUnitMH":"м/ч",
31 | "WindUnitMS":"м/с",
32 | "WindDirDesc0":"С",
33 | "WindDirDesc22":"ССВ",
34 | "WindDirDesc45":"СВ",
35 | "WindDirDesc67":"ВСВ",
36 | "WindDirDesc90":"В",
37 | "WindDirDesc112":"ВЮВ",
38 | "WindDirDesc135":"ЮВ",
39 | "WindDirDesc157":"ЮЮВ",
40 | "WindDirDesc180":"Ю",
41 | "WindDirDesc202":"ЮЮЗ",
42 | "WindDirDesc225":"ЮЗ",
43 | "WindDirDesc247":"ЗЮЗ",
44 | "WindDirDesc270":"З",
45 | "WindDirDesc292":"ЗСЗ",
46 | "WindDirDesc315":"СЗ",
47 | "WindDirDesc337":"ССЗ",
48 | "WaterTempDesc":"Вода",
49 | "SunsetDesc":"Закат",
50 | "SunriseDesc":"Рассвет",
51 | "CityDesc":"Город",
52 | "LastUpdateDesc":"Обновлено",
53 | "Hourly":"По часам",
54 | "Daily":"По дням",
55 | "Update":"Обновить",
56 | "Providers":"Провайдеры погоды",
57 | "Time":"Время",
58 | "GenTabSetting":"Общие",
59 | "Network":"Сеть",
60 | "LangSetting":"Язык",
61 | "Russia":"Русский",
62 | "English":"Английский",
63 | "WidgSetting":"Виджеты",
64 | "DiscsSetting":"Диски",
65 | "ComboSetting":"Комбо",
66 | "WeatherSetting":"Погода",
67 | "ApiKeySettings":"Ключ API",
68 | "EnterCityWM":"Введите название города",
69 | "AutostartHeaderSetting":"Автозапуск",
70 | "AutostartTogle":"Запускать вместе с Windows",
71 | "LocationSetting":"Местоположение",
72 | "Themes":"Темы",
73 | "Dark":"Темная",
74 | "Light":"Светлая",
75 | "NetUnit":"Единицы измерение",
76 | "MbitSettings":"Мегабит в секунду (Мбит/с)",
77 | "MbyteSettings":"Мегабайт в секунду (Мбайт/с)",
78 | "Cancel":"Отмена",
79 | }
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/Styles/Dark.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 | #117dbb
9 |
10 | #117dbb
11 |
12 | #632d8b
13 |
14 | #FF0000
15 |
16 | #4f9847
17 |
18 | #d3772e
19 |
20 | /Assets/Fonts/SegoeUILight.ttf#Segoe UI
21 |
22 |
27 |
28 |
33 |
37 |
42 |
46 |
50 |
54 |
59 |
64 |
69 |
74 |
75 |
80 |
87 |
92 |
96 |
97 |
103 |
109 |
110 |
114 |
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/Styles/Light.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 | #117dbb
9 |
10 | #117dbb
11 |
12 | #632d8b
13 |
14 | #FF0000
15 |
16 | #4f9847
17 |
18 | #d3772e
19 |
20 | /Assets/Fonts/SegoeUILight.ttf#Segoe UI
21 |
22 |
27 |
28 |
33 |
37 |
42 |
46 |
50 |
54 |
59 |
64 |
69 |
74 |
75 |
80 |
87 |
92 |
96 |
97 |
102 |
107 |
108 |
112 |
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_0.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_1.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_10.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_11.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_12.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_13.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_14.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_15.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_16.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_17.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_17.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_18.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_18.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_19.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_2.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_20.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_21.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_21.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_22.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_22.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_23.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_23.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_3.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_4.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_5.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_6.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_7.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_8.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/30/weather_9.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_0.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_1.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_10.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_11.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_12.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_13.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_14.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_15.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_16.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_17.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_17.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_18.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_18.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_19.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_2.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_20.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_21.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_21.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_22.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_22.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_23.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_23.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_3.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_4.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_5.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_6.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_7.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_8.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/Black/65/weather_9.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_0.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_1.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_10.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_11.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_12.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_13.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_14.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_15.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_16.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_17.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_17.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_18.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_18.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_19.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_2.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_20.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_21.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_21.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_22.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_22.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_23.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_23.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_3.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_4.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_5.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_6.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_7.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_8.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/30/weather_9.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_0.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_1.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_10.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_11.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_12.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_13.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_14.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_15.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_16.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_17.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_17.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_18.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_18.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_19.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_2.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_20.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_21.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_21.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_22.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_22.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_23.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_23.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_3.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_4.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_5.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_6.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_7.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_8.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/WeatherIcons/White/65/weather_9.png
--------------------------------------------------------------------------------
/SysMonAvalonia/Assets/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FanIT/SysMonAvalonia/49c7969314f02f1ef9ef24e7b91ddf953e6fe469/SysMonAvalonia/Assets/icon.ico
--------------------------------------------------------------------------------
/SysMonAvalonia/Converters/BitmapValueConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 | using System.Globalization;
4 | using Avalonia;
5 | using Avalonia.Platform;
6 | using Avalonia.Media.Imaging;
7 | using Avalonia.Data.Converters;
8 |
9 | namespace SysMonAvalonia.Converters
10 | {
11 | class BitmapValueConverter : IValueConverter
12 | {
13 | public static BitmapValueConverter Instance = new BitmapValueConverter();
14 |
15 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
16 | {
17 | if (value == null)
18 | return null;
19 |
20 | if (value is string rawUri && targetType.IsAssignableFrom(typeof(Bitmap)))
21 | {
22 | Uri uri;
23 |
24 | // Allow for assembly overrides
25 | if (rawUri.StartsWith("avares://"))
26 | {
27 | uri = new Uri(rawUri);
28 | }
29 | else
30 | {
31 | string assemblyName = Assembly.GetEntryAssembly().GetName().Name;
32 | uri = new Uri($"avares://{assemblyName}{rawUri}");
33 | }
34 |
35 | var assets = AvaloniaLocator.Current.GetService();
36 | var asset = assets.Open(uri);
37 |
38 | return new Bitmap(asset);
39 | }
40 |
41 | throw new NotSupportedException();
42 | }
43 |
44 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
45 | {
46 | throw new NotSupportedException();
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/SysMonAvalonia/Converters/DataValueConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using Avalonia.Data.Converters;
4 | using SysMonAvalonia.Localization;
5 |
6 | namespace SysMonAvalonia.Converters
7 | {
8 | class DataValueConverter : IValueConverter
9 | {
10 | public static DataValueConverter Instance = new DataValueConverter();
11 |
12 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
13 | {
14 | string param = (string)parameter;
15 |
16 | if (param.Contains("temp"))
17 | {
18 | if (value is sbyte)
19 | {
20 | sbyte temp = (sbyte)value;
21 |
22 | if (temp == -100) return "--";
23 |
24 | if (temp >= 0) return $"+{temp}°";
25 | else return $"{temp}°";
26 | }
27 | }
28 |
29 | if (param.Contains("percent")) return $"{value}%";
30 | if (param.Contains("pressure")) return $"{value} {Language.Locale.Pressure}";
31 | if (param.Contains("uvindex")) return $"{GetNameUVIndex((byte)value)} ({value})";
32 |
33 | return null;
34 | }
35 |
36 | private string GetNameUVIndex(byte index)
37 | {
38 | if (index < 3) return Language.Locale.UVIndexLow;
39 | else if (index > 2 && index < 6) return Language.Locale.UVIndexMedium;
40 | else if (index > 5 && index < 8) return Language.Locale.UVIndexHigh;
41 | else if (index > 7 && index < 11) return Language.Locale.UVIndexVeryHigh;
42 | else return Language.Locale.UVIndexExtrem;
43 | }
44 |
45 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
46 | {
47 | throw new NotImplementedException();
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/SysMonAvalonia/Converters/DeviceIoValueConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using Avalonia.Data.Converters;
4 |
5 | namespace SysMonAvalonia.Converters
6 | {
7 | public class DeviceIoValueConverter : IValueConverter
8 | {
9 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
10 | {
11 | if (value is long)
12 | return ((long)value / 1073741824.0).ToString("0.#");
13 |
14 | return null;
15 | }
16 |
17 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
18 | {
19 | throw new NotImplementedException();
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/SysMonAvalonia/Converters/NetworkValueConvert.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using Avalonia.Data.Converters;
4 | using SysMonAvalonia.Data;
5 |
6 | namespace SysMonAvalonia.Converters
7 | {
8 | public class NetworkValueConvert : IValueConverter
9 | {
10 | public static NetworkValueConvert Instange = new();
11 |
12 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
13 | {
14 | if (parameter is string and "gb")
15 | return (long)value / 1073741824.0;
16 |
17 | if (SettingData.CurrentSetting.NetworkUnit == SettingData.NetUnit.Megabits)
18 | return (long)value / 125000.0;
19 | else
20 | return (long)value / 1048576.0;
21 | }
22 |
23 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
24 | {
25 | throw new NotImplementedException();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/SysMonAvalonia/Converters/SettingsValueConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using Avalonia.Data.Converters;
5 | using Weather.Providers;
6 | using Hardware.Windows.Network;
7 | using SysMonAvalonia.Data;
8 |
9 | namespace SysMonAvalonia.Converters
10 | {
11 | public class SettingsValueConverter : IValueConverter
12 | {
13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
14 | {
15 | if (parameter as string == "lang" && value is string lang)
16 | {
17 | if (lang == "en-US") return 0;
18 | if (lang == "ru-RU") return 1;
19 | }
20 |
21 | if (parameter as string == "theme")
22 | return (int)value;
23 |
24 | if (parameter as string == "wprovider")
25 | return (int)SettingData.CurrentSetting.Provider;
26 |
27 | if (parameter as string == "apikey")
28 | {
29 | int val = (int)value;
30 |
31 | if (val == 2 || val == 3) return true;
32 | else return false;
33 | }
34 |
35 | if (parameter as string == "netadapter" && value is string adapterID)
36 | {
37 | List adapterList = NetworkInfo.GetInterface();
38 |
39 | for (int i = 0; i < adapterList.Count; i++)
40 | {
41 | if (adapterList[i].ID.Contains(adapterID)) return i;
42 | }
43 | }
44 |
45 | if (parameter as string == "netunit" && value is SettingData.NetUnit)
46 | return (int)value;
47 |
48 | return null;
49 | }
50 |
51 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
52 | {
53 | if (parameter as string == "lang" && value is int lang)
54 | {
55 | if (lang == 0) return "en-US";
56 | if (lang == 1) return "ru-RU";
57 | }
58 |
59 | if (parameter as string == "theme" && value is int theme)
60 | return (SettingData.Theme)theme;
61 |
62 | if (parameter as string == "wprovider" && value is int provider)
63 | return (Providers)provider;
64 |
65 | if (parameter as string == "netadapter" && value is int adapter)
66 | return NetworkInfo.GetInterface()[adapter].ID;
67 |
68 | if (parameter as string == "netunit" && value is int unit)
69 | return (SettingData.NetUnit)unit;
70 |
71 | return null;
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/SysMonAvalonia/Data/ComboData.cs:
--------------------------------------------------------------------------------
1 | using ReactiveUI;
2 |
3 | namespace SysMonAvalonia.Data
4 | {
5 | public class ComboData : ReactiveObject
6 | {
7 | private double _ramTotal;
8 | private double _ramUsed;
9 | private byte _ramPercent;
10 |
11 | private float _cpuUsedPercent;
12 | private float _cpuTemp;
13 |
14 | private float _gpuUsedPercent;
15 | private float _gpuTemp;
16 |
17 | private float _gpuTotalRam;
18 | private float _gpuUsedRam;
19 | private float _gpuUsedPercentRam;
20 |
21 | private long _netByteReceived;
22 | private long _netByteSend;
23 | private long _netTotalByteReceived;
24 | private long _netTotalByteSend;
25 |
26 | private string _netUnit;
27 |
28 | public double RamTotal
29 | {
30 | get => _ramTotal;
31 | set => this.RaiseAndSetIfChanged(ref _ramTotal, value);
32 | }
33 | public double RamUsed
34 | {
35 | get => _ramUsed;
36 | set => this.RaiseAndSetIfChanged(ref _ramUsed, value);
37 | }
38 | public byte RamPercent
39 | {
40 | get => _ramPercent;
41 | set => this.RaiseAndSetIfChanged(ref _ramPercent, value);
42 | }
43 | public float CpuUsedPercent
44 | {
45 | get => _cpuUsedPercent;
46 | set => this.RaiseAndSetIfChanged(ref _cpuUsedPercent, value);
47 | }
48 | public float CpuTemp
49 | {
50 | get => _cpuTemp;
51 | set => this.RaiseAndSetIfChanged(ref _cpuTemp, value);
52 | }
53 | public float GpuUsedPercent
54 | {
55 | get => _gpuUsedPercent;
56 | set => this.RaiseAndSetIfChanged(ref _gpuUsedPercent, value);
57 | }
58 | public float GpuTemp
59 | {
60 | get => _gpuTemp;
61 | set => this.RaiseAndSetIfChanged(ref _gpuTemp, value);
62 | }
63 | public float GpuTotalRam
64 | {
65 | get => _gpuTotalRam;
66 | set => this.RaiseAndSetIfChanged(ref _gpuTotalRam, value);
67 | }
68 | public float GpuUsedRam
69 | {
70 | get => _gpuUsedRam;
71 | set => this.RaiseAndSetIfChanged(ref _gpuUsedRam, value);
72 | }
73 | public float GpuUsedPercentRam
74 | {
75 | get => _gpuUsedPercentRam;
76 | set => this.RaiseAndSetIfChanged(ref _gpuUsedPercentRam, value);
77 | }
78 | public long GetByteNet
79 | {
80 | get => _netByteReceived;
81 | set => this.RaiseAndSetIfChanged(ref _netByteReceived, value);
82 | }
83 | public long GetTotalByteNet
84 | {
85 | get => _netTotalByteReceived;
86 | set => this.RaiseAndSetIfChanged(ref _netTotalByteReceived, value);
87 | }
88 | public long SentByteNet
89 | {
90 | get => _netByteSend;
91 | set => this.RaiseAndSetIfChanged(ref _netByteSend, value);
92 | }
93 | public long SentTotalByteNet
94 | {
95 | get => _netTotalByteSend;
96 | set => this.RaiseAndSetIfChanged(ref _netTotalByteSend, value);
97 | }
98 | public string NetUnit
99 | {
100 | get => _netUnit;
101 | set => this.RaiseAndSetIfChanged(ref _netUnit, value);
102 | }
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/SysMonAvalonia/Data/DeviceIoData.cs:
--------------------------------------------------------------------------------
1 | using ReactiveUI;
2 | using SysMonAvalonia.Models;
3 |
4 | namespace SysMonAvalonia.Data
5 | {
6 | public class DeviceIoData : ReactiveObject
7 | {
8 | private string _model;
9 | private string _letter;
10 | private long _totalSize;
11 | private long _usedSize;
12 | private byte _percentUsed;
13 | private byte _health;
14 | private bool _isHealth;
15 | private float _totalWrite;
16 | private bool _isTotalWrite;
17 | private float _writeIO;
18 | private float _readIO;
19 | private readonly ChartModel _chartModel = new();
20 |
21 | public short Index { get; set; }
22 |
23 | public string Model
24 | {
25 | get => _model;
26 | set => this.RaiseAndSetIfChanged(ref _model, value);
27 | }
28 | public string Letter
29 | {
30 | get => _letter;
31 | set => this.RaiseAndSetIfChanged(ref _letter, value);
32 | }
33 | public long TotalSize
34 | {
35 | get => _totalSize;
36 | set => this.RaiseAndSetIfChanged(ref _totalSize, value);
37 | }
38 | public long UsedSize
39 | {
40 | get => _usedSize;
41 | set => this.RaiseAndSetIfChanged(ref _usedSize, value);
42 | }
43 | public byte PercentUsed
44 | {
45 | get => _percentUsed;
46 | set => this.RaiseAndSetIfChanged(ref _percentUsed, value);
47 | }
48 | public byte Health
49 | {
50 | get => _health;
51 | set => this.RaiseAndSetIfChanged(ref _health, value);
52 | }
53 | public bool IsHealth
54 | {
55 | get => _isHealth;
56 | set => this.RaiseAndSetIfChanged(ref _isHealth, value);
57 | }
58 | public float TotalWrite
59 | {
60 | get => _totalWrite;
61 | set => this.RaiseAndSetIfChanged(ref _totalWrite, value);
62 | }
63 | public bool IsTotalWrite
64 | {
65 | get => _isTotalWrite;
66 | set => this.RaiseAndSetIfChanged(ref _isTotalWrite, value);
67 | }
68 | public float WriteIO
69 | {
70 | get => _writeIO;
71 | set => this.RaiseAndSetIfChanged(ref _writeIO, value);
72 | }
73 | public float ReadIO
74 | {
75 | get => _readIO;
76 | set => this.RaiseAndSetIfChanged(ref _readIO, value);
77 | }
78 |
79 | public ChartModel DeviceChart
80 | {
81 | get => _chartModel;
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/SysMonAvalonia/Data/ForecastData.cs:
--------------------------------------------------------------------------------
1 | using ReactiveUI;
2 |
3 | namespace SysMonAvalonia.Data
4 | {
5 | public class ForecastData : ReactiveObject
6 | {
7 | private string _dateTime;
8 | private string _icon;
9 | private sbyte _tempMin;
10 | private sbyte _tempMax;
11 | private string _phase;
12 |
13 | public string DateTime
14 | {
15 | get => _dateTime;
16 | set => this.RaiseAndSetIfChanged(ref _dateTime, value);
17 | }
18 | public string Icon
19 | {
20 | get => _icon;
21 | set => this.RaiseAndSetIfChanged(ref _icon, value);
22 | }
23 | public sbyte TempMin
24 | {
25 | get => _tempMin;
26 | set => this.RaiseAndSetIfChanged(ref _tempMin, value);
27 | }
28 | public sbyte TempMax
29 | {
30 | get => _tempMax;
31 | set => this.RaiseAndSetIfChanged(ref _tempMax, value);
32 | }
33 | public string Phase
34 | {
35 | get => _phase;
36 | set => this.RaiseAndSetIfChanged(ref _phase, value);
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/SysMonAvalonia/Data/SettingData.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using Newtonsoft.Json;
4 | using Weather.Providers;
5 |
6 | namespace SysMonAvalonia.Data
7 | {
8 | [JsonObject(MemberSerialization.OptIn)]
9 | public class SettingData
10 | {
11 | public enum NetUnit : int
12 | {
13 | Megabits = 0,
14 | Megabytes = 1
15 | }
16 | public enum Theme : int
17 | {
18 | Dark = 0,
19 | Light = 1
20 | }
21 | [JsonObject(MemberSerialization.OptIn)]
22 | public class WidgetProperties
23 | {
24 | [JsonProperty("IsStartup")]
25 | public bool IsStartup { get; set; }
26 | [JsonProperty("X")]
27 | public int X { get; set; }
28 | [JsonProperty("Y")]
29 | public int Y { get; set; }
30 |
31 | public WidgetProperties()
32 | {
33 | IsStartup = false;
34 | X = 0;
35 | Y = 0;
36 | }
37 | }
38 |
39 | private readonly string SettingFile;
40 | [JsonProperty("Language")]
41 | public string Language { get; set; }
42 | public CultureInfo Culture { get; set; }
43 | [JsonProperty("Theme")]
44 | public Theme Style { get; set; }
45 | [JsonProperty("WeatherProvider")]
46 | public Providers Provider { get; set; }
47 | [JsonProperty("WeatherWidget")]
48 | public WidgetProperties WeatherWidget { get; set; } = new();
49 | [JsonProperty("DeviceIoWidget")]
50 | public WidgetProperties DeviceIoWidget { get; set; } = new();
51 | [JsonProperty("ComboWidget")]
52 | public WidgetProperties ComboWidget { get; set; } = new();
53 | [JsonProperty("WeatherInterval")]
54 | public int WeatherInterval { get; set; }
55 | [JsonProperty("WeatherLastUpdate")]
56 | public DateTime WeatherLastUpdate { get; set; }
57 | [JsonProperty("WeatherApiKey")]
58 | public string WeatherApiKey { get; set; }
59 | [JsonProperty("WeatherID")]
60 | public string WeatherID { get; set; }
61 | [JsonProperty("WeatherCity")]
62 | public string WeatherCity { get; set; }
63 | [JsonProperty("NetworkAdapter")]
64 | public string AdapterName { get; set; }
65 | public string AdapterID { get; set; }
66 | [JsonProperty("NetworkUnit")]
67 | public NetUnit NetworkUnit { get; set; }
68 | public static SettingData CurrentSetting { get; set; }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/SysMonAvalonia/Data/WeatherData.cs:
--------------------------------------------------------------------------------
1 | using ReactiveUI;
2 |
3 | namespace SysMonAvalonia.Data
4 | {
5 | public class WeatherData : ReactiveObject
6 | {
7 | private string _currentIcon;
8 | private string _currentPhase;
9 | private sbyte _currentTemp;
10 | private sbyte _minTemp;
11 | private sbyte _maxTemp;
12 | private sbyte _apparTemp;
13 | private string _windAbbr;
14 | private short _windSpeed;
15 | private double _windDegree;
16 | private string _windUnit;
17 | private byte _cloudCover;
18 | private bool _isCloudyCover;
19 | private byte _precipitation;
20 | private bool _isPreciptation;
21 | private byte _humidity;
22 | private short _pressure;
23 | private byte _uvIndex;
24 | private string _sunset;
25 | private string _sunrise;
26 | private string _city;
27 | private string _lastUpdate;
28 |
29 | public string CurrentIcon
30 | {
31 | get => _currentIcon;
32 | set => this.RaiseAndSetIfChanged(ref _currentIcon, value);
33 | }
34 | public string CurrentPhase
35 | {
36 | get => _currentPhase;
37 | set => this.RaiseAndSetIfChanged(ref _currentPhase, value);
38 | }
39 | public sbyte CurrentTemp
40 | {
41 | get => _currentTemp;
42 | set => this.RaiseAndSetIfChanged(ref _currentTemp, value);
43 | }
44 | public sbyte MinTemp
45 | {
46 | get => _minTemp;
47 | set => this.RaiseAndSetIfChanged(ref _minTemp, value);
48 | }
49 | public sbyte MaxTemp
50 | {
51 | get => _maxTemp;
52 | set => this.RaiseAndSetIfChanged(ref _maxTemp, value);
53 | }
54 | public sbyte ApparTemp
55 | {
56 | get => _apparTemp;
57 | set => this.RaiseAndSetIfChanged(ref _apparTemp, value);
58 | }
59 | public string WindAbbr
60 | {
61 | get => _windAbbr;
62 | set => this.RaiseAndSetIfChanged(ref _windAbbr, value);
63 | }
64 | public short WindSpeed
65 | {
66 | get => _windSpeed;
67 | set => this.RaiseAndSetIfChanged(ref _windSpeed, value);
68 | }
69 | public double WindDegree
70 | {
71 | get => _windDegree;
72 | set => this.RaiseAndSetIfChanged(ref _windDegree, value);
73 | }
74 | public string WindUnit
75 | {
76 | get => _windUnit;
77 | set => this.RaiseAndSetIfChanged(ref _windUnit, value);
78 | }
79 | public byte CloudCover
80 | {
81 | get => _cloudCover;
82 | set => this.RaiseAndSetIfChanged(ref _cloudCover, value);
83 | }
84 | public bool IsCloudyCover
85 | {
86 | get => _isCloudyCover;
87 | set => this.RaiseAndSetIfChanged(ref _isCloudyCover, value);
88 | }
89 | public byte Precipitation
90 | {
91 | get => _precipitation;
92 | set => this.RaiseAndSetIfChanged(ref _precipitation, value);
93 | }
94 | public bool IsPreciptation
95 | {
96 | get => _isPreciptation;
97 | set => this.RaiseAndSetIfChanged(ref _isPreciptation, value);
98 | }
99 | public byte Humidity
100 | {
101 | get => _humidity;
102 | set => this.RaiseAndSetIfChanged(ref _humidity, value);
103 | }
104 | public short Pressure
105 | {
106 | get => _pressure;
107 | set => this.RaiseAndSetIfChanged(ref _pressure, value);
108 | }
109 | public byte UVIndex
110 | {
111 | get => _uvIndex;
112 | set => this.RaiseAndSetIfChanged(ref _uvIndex, value);
113 | }
114 | public string Sunset
115 | {
116 | get => _sunset;
117 | set => this.RaiseAndSetIfChanged(ref _sunset, value);
118 | }
119 | public string Sunrise
120 | {
121 | get => _sunrise;
122 | set => this.RaiseAndSetIfChanged(ref _sunrise, value);
123 | }
124 | public string City
125 | {
126 | get => _city;
127 | set => this.RaiseAndSetIfChanged(ref _city, value);
128 | }
129 | public string LastUpdate
130 | {
131 | get => _lastUpdate;
132 | set => this.RaiseAndSetIfChanged(ref _lastUpdate, value);
133 | }
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/SysMonAvalonia/Localization/Language.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.IO;
4 | using Avalonia;
5 | using Avalonia.Platform;
6 | using Newtonsoft.Json;
7 |
8 | namespace SysMonAvalonia.Localization
9 | {
10 | public class Language
11 | {
12 | public string Close { get; set; }
13 | public string Settings { get; set; }
14 | public string Mb { get; set; }
15 | public string Gb { get; set; }
16 | public string Tb { get; set; }
17 | public string Mbit { get; set; }
18 | public string Mbyte { get; set; }
19 | public string Health { get; set; }
20 | public string Write { get; set; }
21 | public string ReadIO { get; set; }
22 | public string WriteIO { get; set; }
23 | public string CpuHeader { get; set; }
24 | public string GpuHeader { get; set; }
25 | public string RamHeader { get; set; }
26 | public string Adapters { get; set; }
27 | public string ApparTempDesc { get; set; }
28 | public string WindSpeedDesc { get; set; }
29 | public string CloudCoverDesc { get; set; }
30 | public string ChanceOfRain { get; set; }
31 | public string HumidityDesc { get; set; }
32 | public string Pressure { get; set; }
33 | public string PressureDesc { get; set; }
34 | public string UVIndexDesc { get; set; }
35 | public string UVIndexLow { get; set; }
36 | public string UVIndexMedium { get; set; }
37 | public string UVIndexHigh { get; set; }
38 | public string UVIndexVeryHigh { get; set; }
39 | public string UVIndexExtrem { get; set; }
40 | public string WindUnitKmH { get; set; }
41 | public string WindUnitMH { get; set; }
42 | public string WindUnitMS { get; set; }
43 | public string WindDirDesc0 { get; set; }
44 | public string WindDirDesc22 { get; set; }
45 | public string WindDirDesc45 { get; set; }
46 | public string WindDirDesc67 { get; set; }
47 | public string WindDirDesc90 { get; set; }
48 | public string WindDirDesc112 { get; set; }
49 | public string WindDirDesc135 { get; set; }
50 | public string WindDirDesc157 { get; set; }
51 | public string WindDirDesc180 { get; set; }
52 | public string WindDirDesc202 { get; set; }
53 | public string WindDirDesc225 { get; set; }
54 | public string WindDirDesc247 { get; set; }
55 | public string WindDirDesc270 { get; set; }
56 | public string WindDirDesc292 { get; set; }
57 | public string WindDirDesc315 { get; set; }
58 | public string WindDirDesc337 { get; set; }
59 | public string WaterTempDesc { get; set; }
60 | public string SunsetDesc { get; set; }
61 | public string SunriseDesc { get; set; }
62 | public string CityDesc { get; set; }
63 | public string LastUpdateDesc { get; set; }
64 | public string Hourly { get; set; }
65 | public string Daily { get; set; }
66 | public string Update { get; set; }
67 | public string Providers { get; set; }
68 | public string Time { get; set; }
69 | public string GenTabSetting { get; set; }
70 | public string Network { get; set; }
71 | public string LangSetting { get; set; }
72 | public string Russia { get; set; }
73 | public string English { get; set; }
74 | public string WidgSetting { get; set; }
75 | public string DiscsSetting { get; set; }
76 | public string ComboSetting { get; set; }
77 | public string WeatherSetting { get; set; }
78 | public string ApiKeySettings { get; set; }
79 | public string EnterCityWM { get; set; }
80 | public string AutostartHeaderSetting { get; set; }
81 | public string AutostartTogle { get; set; }
82 | public string LocationSetting { get; set; }
83 | public string Themes { get; set; }
84 | public string Dark { get; set; }
85 | public string Light { get; set; }
86 | public string NetUnit { get; set; }
87 | public string MbitSettings { get; set; }
88 | public string MbyteSettings { get; set; }
89 | public string Cancel { get; set; }
90 | public static Language Locale { get; set; }
91 |
92 | public static void Load(CultureInfo culture)
93 | {
94 | IAssetLoader asset = AvaloniaLocator.Current.GetService();
95 |
96 | string lngFile = culture.ThreeLetterISOLanguageName.ToLower() == "rus" ? "ru.json" : "en.json";
97 |
98 | using (StreamReader reader =
99 | new StreamReader(asset.Open(new Uri($"avares://SysMonAvalonia/Assets/Locale/{lngFile}"))))
100 | {
101 | try
102 | {
103 | Locale = JsonConvert.DeserializeObject(reader.ReadToEnd());
104 | }
105 | catch
106 | {
107 | Locale = new();
108 | }
109 | }
110 | }
111 | }
112 | }
--------------------------------------------------------------------------------
/SysMonAvalonia/Models/ChartModel.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.ObjectModel;
2 | using LiveChartsCore;
3 | using LiveChartsCore.Defaults;
4 | using LiveChartsCore.Drawing;
5 | using LiveChartsCore.SkiaSharpView;
6 | using LiveChartsCore.SkiaSharpView.Painting;
7 |
8 | namespace SysMonAvalonia.Models
9 | {
10 | public class ChartModel
11 | {
12 | private ObservableCollection _observablePoints;
13 | private LineSeries _lineSeries;
14 |
15 | public ISeries[] Series { get; set; }
16 | public Axis[] XAxis { get; set; }
17 | public Axis[] YAxis { get; set; }
18 | public SolidColorPaint? Fill {
19 | set => _lineSeries.Fill = value;
20 | }
21 | public double Value
22 | {
23 | set => AddPoint(value);
24 | }
25 |
26 | public ChartModel()
27 | {
28 | _observablePoints = new();
29 |
30 | FillPoints();
31 |
32 | _lineSeries = new LineSeries
33 | {
34 | Values = _observablePoints,
35 | Stroke = null,
36 | GeometryFill = null,
37 | GeometryStroke = null,
38 | GeometrySize = 0,
39 | DataPadding = new LvcPoint(0, 0)
40 | };
41 |
42 | Series = new[] { _lineSeries };
43 |
44 | XAxis = new[]
45 | {
46 | new Axis { IsVisible = false }
47 | };
48 |
49 | YAxis = new[]
50 | {
51 | new Axis
52 | {
53 | IsVisible = false,
54 | MinLimit = 0,
55 | MaxLimit = 100
56 | }
57 | };
58 | }
59 |
60 | private void AddPoint(double point)
61 | {
62 | if (point > YAxis[0].MaxLimit) YAxis[0].MaxLimit = point;
63 |
64 | _observablePoints.Add(new ObservableValue(point));
65 | _observablePoints.RemoveAt(0);
66 | }
67 |
68 | public void ClearPoints()
69 | {
70 | _observablePoints.Clear();
71 | }
72 |
73 | public void FillPoints(double point = 0)
74 | {
75 | for (byte b = 0; b < 60; b++)
76 | {
77 | _observablePoints.Add(new ObservableValue(point));
78 | }
79 | }
80 | }
81 | }
--------------------------------------------------------------------------------
/SysMonAvalonia/Models/ComboModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using SysMonAvalonia.Data;
3 | using Hardware;
4 | using Hardware.Windows.Network;
5 | using SysMonAvalonia.Localization;
6 |
7 | namespace SysMonAvalonia.Models
8 | {
9 | public class ComboModel : IDisposable
10 | {
11 | public ComboData ComboData { get; }
12 |
13 | public ComboModel()
14 | {
15 | this.ComboData = new();
16 |
17 | Computer.Open();
18 |
19 | NetworkInfo.SpeedUpdate();
20 |
21 | ComboData.GetTotalByteNet = NetworkInfo.ByteReceived;
22 | ComboData.SentTotalByteNet = NetworkInfo.ByteSend;
23 |
24 | ComboData.NetUnit = SettingData.CurrentSetting.NetworkUnit == SettingData.NetUnit.Megabits
25 | ? Language.Locale.Mbit
26 | : Language.Locale.Mbyte;
27 | }
28 |
29 | public void ComputerDataUpdate()
30 | {
31 | Computer.Update();
32 |
33 | ComboData.CpuUsedPercent = Computer.CPUPercent;
34 | ComboData.CpuTemp = Computer.CPUTemp;
35 |
36 | ComboData.GpuUsedPercent = Computer.GPUPercent;
37 | ComboData.GpuTemp = Computer.GPUTemp;
38 | ComboData.GpuTotalRam = Computer.GPUTotalRam;
39 | ComboData.GpuUsedRam = Computer.GPUUsedRam;
40 | ComboData.GpuUsedPercentRam = Computer.GPUPercentRam;
41 |
42 | ComboData.RamTotal = Computer.RamTotal;
43 | ComboData.RamUsed = Computer.RamUsed;
44 | ComboData.RamPercent = Computer.RamPercent;
45 |
46 | NetworkInfo.SpeedUpdate();
47 |
48 | ComboData.GetByteNet = NetworkInfo.ByteReceived - ComboData.GetTotalByteNet;
49 | ComboData.SentByteNet = NetworkInfo.ByteSend - ComboData.SentTotalByteNet;
50 |
51 | ComboData.GetTotalByteNet = NetworkInfo.ByteReceived;
52 | ComboData.SentTotalByteNet = NetworkInfo.ByteSend;
53 | }
54 |
55 | public void Dispose()
56 | {
57 | Computer.Close();
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/SysMonAvalonia/Models/DeviceIoModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.ObjectModel;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Reactive.Linq;
7 | using Avalonia;
8 | using Avalonia.Controls;
9 | using DynamicData;
10 | using Hardware.Windows.DeviceIoInfo;
11 | using LiveChartsCore.SkiaSharpView.Painting;
12 | using ReactiveUI;
13 | using SysMonAvalonia.Data;
14 |
15 | namespace SysMonAvalonia.Models
16 | {
17 | public class DeviceIoModel : IDisposable
18 | {
19 | private readonly SourceList _deviceList;
20 | public ReadOnlyObservableCollection DeviceCollection;
21 |
22 | public DeviceIoModel()
23 | {
24 | _deviceList = new();
25 | _deviceList.Connect().ObserveOn(RxApp.MainThreadScheduler).Bind(out DeviceCollection).Subscribe();
26 | }
27 |
28 | public void UpdateDeviceCollection()
29 | {
30 | if (DeviceInfo.IsUpdateDiscs())
31 | {
32 | List devices = DeviceInfo.LogicalDrives;
33 |
34 | if (_deviceList.Count > devices.Count)
35 | RemoveOldDeviceInCollection(devices);
36 |
37 | foreach (Device dev in devices)
38 | {
39 | if (ExistDeviceInCollection(dev)) continue;
40 |
41 | DeviceIoData device = new();
42 | device.Index = dev.Index;
43 | device.Model = dev.Model;
44 | device.Letter = dev.Letter;
45 | device.DeviceChart.Fill = Application.Current.FindResource("DeviceChartFill") as SolidColorPaint;
46 |
47 | _deviceList.Add(device);
48 | }
49 | }
50 | }
51 |
52 | public void UpdateDeviceSpace()
53 | {
54 | try
55 | {
56 | DeviceInfo.UpdateSizeOfDiscs();
57 | }
58 | catch (DriveNotFoundException)
59 | {
60 | UpdateDeviceCollection();
61 | DeviceInfo.UpdateSizeOfDiscs();
62 | }
63 |
64 | foreach (DeviceIoData devData in _deviceList.Items)
65 | {
66 | devData.TotalSize = DeviceInfo.LogicalDrives[devData.Index].TotalSpace;
67 | devData.UsedSize = DeviceInfo.LogicalDrives[devData.Index].UsedSpace;
68 | devData.PercentUsed = DeviceInfo.LogicalDrives[devData.Index].PercentUsedSpace;
69 | }
70 | }
71 |
72 | public void UpdateDeviceInfo()
73 | {
74 | DeviceInfo.UpdateInfoOfDiscs();
75 |
76 | foreach (DeviceIoData devData in _deviceList.Items)
77 | {
78 | devData.Health = DeviceInfo.LogicalDrives[devData.Index].Health;
79 | devData.TotalWrite = DeviceInfo.LogicalDrives[devData.Index].TotalWrite;
80 |
81 | devData.IsHealth = devData.Health != 0;
82 | devData.IsTotalWrite = devData.TotalWrite != 0;
83 | }
84 | }
85 |
86 | public void UpdatePerformance()
87 | {
88 | foreach (DeviceIoData dId in _deviceList.Items)
89 | {
90 | DeviceInfo.PerfomanceDiskUpdate(dId.Index);
91 |
92 | dId.ReadIO = DeviceInfo.ReadIo;
93 | dId.WriteIO = DeviceInfo.WriteIo;
94 | dId.DeviceChart.Value = DeviceInfo.ReadIo + DeviceInfo.WriteIo;
95 | }
96 | }
97 |
98 | private bool ExistDeviceInCollection(Device device)
99 | {
100 | return _deviceList.Items.Any(did => did.Model.Contains(device.Model) && did.TotalSize == device.TotalSpace);
101 | }
102 |
103 | private void RemoveOldDeviceInCollection(IReadOnlyCollection device)
104 | {
105 | short index = 0;
106 |
107 | foreach (DeviceIoData item in _deviceList.Items)
108 | {
109 | if (!device.Any(dev => dev.Model.Contains(item.Model) && dev.TotalSpace == item.TotalSize))
110 | _deviceList.RemoveAt(index);
111 |
112 | item.Index = index;
113 |
114 | index++;
115 | }
116 | }
117 |
118 | public void Dispose()
119 | {
120 | _deviceList.Dispose();
121 | DeviceInfo.Close();
122 | }
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/SysMonAvalonia/Models/ForecastModel.cs:
--------------------------------------------------------------------------------
1 | namespace SysMonAvalonia.Models
2 | {
3 | public class ForecastModel
4 | {
5 | public string DateTime { get; set; }
6 | public string Icon { get; set; }
7 | public sbyte TempMax { get; set; }
8 | public sbyte TempMin { get; set; }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/SysMonAvalonia/Models/SettingModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.IO;
5 | using Newtonsoft.Json;
6 | using Newtonsoft.Json.Linq;
7 | using SysMonAvalonia.Data;
8 | using SysMonAvalonia.Services;
9 | using Weather;
10 | using Weather.Providers;
11 | using Hardware.Windows.Network;
12 |
13 | namespace SysMonAvalonia.Models
14 | {
15 | public class SettingModel
16 | {
17 | public List NetworkAdapters
18 | {
19 | get => NetworkInfo.GetInterface();
20 | }
21 |
22 | public bool AutostartEnable
23 | {
24 | get => AppService.FindTaskService(AppDomain.CurrentDomain.FriendlyName);
25 | set
26 | {
27 | if (value)
28 | AppService.CreateTaskService($"{AppContext.BaseDirectory}{AppDomain.CurrentDomain.FriendlyName}.exe");
29 | else
30 | AppService.DeleteTaskService(AppDomain.CurrentDomain.FriendlyName);
31 | }
32 | }
33 |
34 | public static List FindCities(string query)
35 | {
36 | if (query == String.Empty) return null;
37 |
38 | IProvider _weatherProvider;
39 |
40 | List cityList = new();
41 |
42 | switch (SettingData.CurrentSetting.Provider)
43 | {
44 | case Providers.AccuWeather: _weatherProvider = new AccuWeather(); break;
45 | case Providers.Gismeteo: _weatherProvider = new Gismeteo(); break;
46 | case Providers.OpenWeatherMap: _weatherProvider = new OpenWeatherMap(); break;
47 | case Providers.WorldWeatherOnline: _weatherProvider = new WorldWeatherOnline(); break;
48 | case Providers.Wunderground: _weatherProvider = new Wunderground(); break;
49 | default: return cityList;
50 | }
51 |
52 | return _weatherProvider.GetLocation(query, SettingData.CurrentSetting.Culture, SettingData.CurrentSetting.WeatherApiKey);
53 | }
54 |
55 | public static void Load()
56 | {
57 | if (SettingData.CurrentSetting != null) return;
58 |
59 | string settingFile;
60 | /*#if DEBUG
61 | settingFile = AppContext.BaseDirectory + @"\Settings.json";
62 | #else*/
63 | settingFile = Path.GetDirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName) + @"\Settings.json";
64 | //#endif
65 |
66 | string settingStr;
67 |
68 | try
69 | {
70 | settingStr = File.ReadAllText(settingFile);
71 | }
72 | catch
73 | {
74 | SettingData.CurrentSetting = new();
75 | SettingData.CurrentSetting.Culture = CultureInfo.CurrentCulture;
76 | SettingData.CurrentSetting.Language =
77 | CultureInfo.CurrentCulture.ThreeLetterISOLanguageName.Contains("rus") ? "ru-RU" : "en-US";
78 |
79 | return;
80 | }
81 |
82 | SettingData.CurrentSetting = JsonConvert.DeserializeObject(settingStr);
83 | SettingData.CurrentSetting.Culture = SettingData.CurrentSetting.Language != null
84 | ? CultureInfo.GetCultureInfo(SettingData.CurrentSetting.Language)
85 | : CultureInfo.CurrentCulture;
86 | }
87 |
88 | public static void Save()
89 | {
90 | string settingFile;
91 | /*#if DEBUG
92 | settingFile = AppContext.BaseDirectory + @"\Settings.json";
93 | #else*/
94 | settingFile = Path.GetDirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName) + @"\Settings.json";
95 | //#endif
96 | File.WriteAllText(settingFile, JsonConvert.SerializeObject(JObject.FromObject(SettingData.CurrentSetting)));
97 | }
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/SysMonAvalonia/NLog.config:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/SysMonAvalonia/Program.cs:
--------------------------------------------------------------------------------
1 | using Avalonia;
2 | using Avalonia.ReactiveUI;
3 | using NLog;
4 | using Projektanker.Icons.Avalonia;
5 | using Projektanker.Icons.Avalonia.FontAwesome;
6 |
7 | namespace SysMonAvalonia
8 | {
9 | class Program
10 | {
11 | // Initialization code. Don't use any Avalonia, third-party APIs or any
12 | // SynchronizationContext-reliant code before AppMain is called: things aren't initialized
13 | // yet and stuff might break.
14 | public static void Main(string[] args) => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
15 |
16 | // Avalonia configuration, don't remove; also used by visual designer.
17 | public static AppBuilder BuildAvaloniaApp()
18 | => AppBuilder.Configure()
19 | .UsePlatformDetect()
20 | .LogToTrace()
21 | .WithIcons(container => container.Register())
22 | .UseReactiveUI();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/SysMonAvalonia/Services/AppService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using Avalonia.Controls;
5 | using Avalonia.Controls.ApplicationLifetimes;
6 | using Avalonia.Markup.Xaml.Styling;
7 | using SysMonAvalonia.Views;
8 | using SysMonAvalonia.Data;
9 | using Microsoft.Win32.TaskScheduler;
10 | using SysMonAvalonia.Models;
11 |
12 | namespace SysMonAvalonia.Services
13 | {
14 | public static class AppService
15 | {
16 | private static SettingView _settingWindow;
17 |
18 | public static void ShowSettings()
19 | {
20 | _settingWindow = new SettingView();
21 | _settingWindow.Show();
22 | }
23 |
24 | public static void CloseSettings()
25 | {
26 | if (_settingWindow != null) _settingWindow.Close();
27 | }
28 |
29 | public static bool CreateTaskService(string path)
30 | {
31 | bool isActive = false;
32 |
33 | TaskService task = TaskService.Instance;
34 | LogonTrigger logonTrigger = new();
35 | TaskDefinition taskDefinition = task.NewTask();
36 |
37 | try
38 | {
39 | logonTrigger.Delay = TimeSpan.FromSeconds(15);
40 |
41 | taskDefinition.RegistrationInfo.Description = "Auto start " + Path.GetFileNameWithoutExtension(path);
42 | taskDefinition.Principal.RunLevel = TaskRunLevel.Highest;
43 | taskDefinition.Triggers.Add(logonTrigger);
44 | taskDefinition.Actions.Add(new ExecAction(path));
45 |
46 | isActive = task.RootFolder
47 | .RegisterTaskDefinition(Path.GetFileNameWithoutExtension(path), taskDefinition).IsActive;
48 | }
49 | catch { }
50 | finally
51 | {
52 | taskDefinition.Dispose();
53 | logonTrigger.Dispose();
54 | task.Dispose();
55 | }
56 |
57 | return isActive;
58 | }
59 |
60 | public static void DeleteTaskService(string name)
61 | {
62 | TaskService task = TaskService.Instance;
63 |
64 | task.RootFolder.DeleteFolder(name, false);
65 |
66 | task.Dispose();
67 | }
68 |
69 | public static bool FindTaskService(string name)
70 | {
71 | bool isExist = false;
72 |
73 | TaskService task = TaskService.Instance;
74 |
75 | try
76 | {
77 | isExist = task.FindTask(name) != null;
78 | }
79 | catch
80 | {
81 | }
82 | finally
83 | {
84 | task.Dispose();
85 | }
86 |
87 | return isExist;
88 | }
89 |
90 | public static void ShutdownApp()
91 | {
92 | if (App.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
93 | desktop.Shutdown();
94 | }
95 |
96 | public static void ChangeStyles()
97 | {
98 | string localStyle = SettingData.CurrentSetting.Style == SettingData.Theme.Dark ? "Dark.xaml" : "Light.xaml";
99 | string fluentStyle = SettingData.CurrentSetting.Style == SettingData.Theme.Dark ? "FluentDark.xaml" : "FluentLight.xaml";
100 |
101 | StyleInclude fluentStyleInclude = new(baseUri: new Uri("avares://Avalonia.Themes.Fluent"));
102 | fluentStyleInclude.Source = new Uri(fluentStyle, UriKind.Relative);
103 |
104 | App.Current.Styles.Add(fluentStyleInclude);
105 |
106 | StyleInclude localStyleInclude = new(baseUri: new Uri("avares://SysMonAvalonia/Assets/Styles/"));
107 | localStyleInclude.Source = new Uri(localStyle, UriKind.Relative);
108 |
109 | App.Current.Styles.Add(localStyleInclude);
110 | }
111 |
112 | public static void ShowWidgets(IClassicDesktopStyleApplicationLifetime desktop)
113 | {
114 | desktop.Exit += (sender, args) => SettingModel.Save();
115 |
116 | List widgetList = new();
117 |
118 | if (SettingData.CurrentSetting.DeviceIoWidget.IsStartup)
119 | {
120 | DeviceIoWidgetView deviceIoWidget = new();
121 | deviceIoWidget.WindowStartupLocation = WindowStartupLocation.Manual;
122 | deviceIoWidget.Position = new(SettingData.CurrentSetting.DeviceIoWidget.X,
123 | SettingData.CurrentSetting.DeviceIoWidget.Y);
124 |
125 | widgetList.Add(deviceIoWidget);
126 | }
127 |
128 | if (SettingData.CurrentSetting.WeatherWidget.IsStartup)
129 | {
130 | WeatherWidgetView weatherWidget = new();
131 | weatherWidget.WindowStartupLocation = WindowStartupLocation.Manual;
132 | weatherWidget.Position = new(SettingData.CurrentSetting.WeatherWidget.X,
133 | SettingData.CurrentSetting.WeatherWidget.Y);
134 |
135 | widgetList.Add(weatherWidget);
136 | }
137 |
138 | if (SettingData.CurrentSetting.ComboWidget.IsStartup)
139 | {
140 | ComboWidgetView comboWidget = new();
141 | comboWidget.WindowStartupLocation = WindowStartupLocation.Manual;
142 | comboWidget.Position = new(SettingData.CurrentSetting.ComboWidget.X,
143 | SettingData.CurrentSetting.ComboWidget.Y);
144 |
145 | widgetList.Add(comboWidget);
146 | }
147 |
148 | foreach (Window widget in widgetList)
149 | {
150 | if (desktop.MainWindow == null)
151 | {
152 | desktop.MainWindow = widget;
153 | continue;
154 | }
155 |
156 | widget.Show();
157 | }
158 |
159 | if (desktop.MainWindow == null)
160 | {
161 | desktop.MainWindow = new DeviceIoWidgetView();
162 | SettingData.CurrentSetting.DeviceIoWidget.IsStartup = true;
163 | }
164 | }
165 | }
166 | }
--------------------------------------------------------------------------------
/SysMonAvalonia/SysMonAvalonia.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | WinExe
4 | net6.0
5 | enable
6 | app.manifest
7 | true
8 | true
9 | Assets\icon.ico
10 | SysMonAvalonia
11 | SysMonAvalonia
12 | true
13 |
14 |
15 | AnyCPU
16 | false
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | Always
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | MSBuild:Compile
49 |
50 |
51 | MSBuild:Compile
52 |
53 |
54 |
55 |
56 | WeatherWidgetView.axaml
57 |
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/SysMonAvalonia/SysMonAvalonia.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <_LastSelectedProfileId>D:\GitHub\SysMonAvalonia\SysMonAvalonia\Properties\PublishProfiles\FolderProfile.pubxml
5 | false
6 |
7 |
8 |
9 | Designer
10 |
11 |
12 |
--------------------------------------------------------------------------------
/SysMonAvalonia/ViewLocator.cs:
--------------------------------------------------------------------------------
1 | using Avalonia.Controls;
2 | using Avalonia.Controls.Templates;
3 | using SysMonAvalonia.ViewModels;
4 | using System;
5 |
6 | namespace SysMonAvalonia
7 | {
8 | public class ViewLocator : IDataTemplate
9 | {
10 | public bool SupportsRecycling => false;
11 |
12 | public IControl Build(object data)
13 | {
14 | var name = data.GetType().FullName!.Replace("ViewModel", "View");
15 | var type = Type.GetType(name);
16 |
17 | if (type != null)
18 | {
19 | return (Control)Activator.CreateInstance(type)!;
20 | }
21 | else
22 | {
23 | return new TextBlock { Text = "Not Found: " + name };
24 | }
25 | }
26 |
27 | public bool Match(object data)
28 | {
29 | return data is ViewModelBase;
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/SysMonAvalonia/ViewModels/ComboWidgetViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reactive;
3 | using System.Reactive.Linq;
4 | using Avalonia.Controls;
5 | using LiveChartsCore.SkiaSharpView.Painting;
6 | using ReactiveUI;
7 | using SysMonAvalonia.Models;
8 | using SysMonAvalonia.Data;
9 | using SysMonAvalonia.Services;
10 | using NLog;
11 |
12 | namespace SysMonAvalonia.ViewModels
13 | {
14 | public class ComboWidgetViewModel
15 | {
16 | private ComboModel _comboModel;
17 | private ComboData _comboData;
18 | private IDisposable _timer;
19 |
20 | public ComboData ComboData
21 | {
22 | get => _comboData;
23 | }
24 | public ChartModel CpuChartModel { get; }
25 | public ChartModel RamChartModel { get; }
26 | public ChartModel GpuChartModel { get; }
27 | public ChartModel NetDownChartModel { get; }
28 | public ChartModel NetUpChartModel { get; }
29 |
30 | public ReactiveCommand ShowSettingsCommand { get; } =
31 | ReactiveCommand.Create(() => AppService.ShowSettings());
32 |
33 | public ReactiveCommand ShutdownCommand { get; } = ReactiveCommand.Create(() => AppService.ShutdownApp() );
34 |
35 | public ReactiveCommand ClosingCommand { get; }
36 |
37 | public ReactiveCommand MoveWidgetCommand { get; } = ReactiveCommand.Create(e =>
38 | {
39 | if (e != null)
40 | {
41 | SettingData.CurrentSetting.ComboWidget.X = e.Point.X;
42 | SettingData.CurrentSetting.ComboWidget.Y = e.Point.Y;
43 | }
44 | });
45 |
46 | public ComboWidgetViewModel()
47 | {
48 | _comboModel = new();
49 | _comboData = _comboModel.ComboData;
50 | _comboModel.ComputerDataUpdate();
51 |
52 | CpuChartModel = new();
53 | CpuChartModel.Fill = App.Current.FindResource("CpuChartFill") as SolidColorPaint;
54 |
55 | RamChartModel = new();
56 | RamChartModel.Fill = App.Current.FindResource("RamChartFill") as SolidColorPaint;
57 | RamChartModel.ClearPoints();
58 | RamChartModel.FillPoints(_comboData.RamPercent);
59 |
60 | GpuChartModel = new();
61 | GpuChartModel.Fill = App.Current.FindResource("GpuChartFill") as SolidColorPaint;
62 |
63 | NetDownChartModel = new();
64 | NetDownChartModel.Fill = App.Current.FindResource("NetDownChartFill") as SolidColorPaint;
65 |
66 | NetUpChartModel = new();
67 | NetUpChartModel.Fill = App.Current.FindResource("NetUpChartFill") as SolidColorPaint;
68 |
69 | _comboData.WhenAnyValue(x => x.CpuUsedPercent).Subscribe(percent => CpuChartModel.Value = percent);
70 | _comboData.WhenAnyValue(x => x.RamPercent).Subscribe(percent => RamChartModel.Value = percent);
71 | _comboData.WhenAnyValue(x => x.GpuUsedPercent).Subscribe(percent => GpuChartModel.Value = percent);
72 | _comboData.WhenAnyValue(x => x.GetByteNet).Subscribe(getByte => NetDownChartModel.Value = getByte);
73 | _comboData.WhenAnyValue(x => x.SentByteNet).Subscribe(sentByte => NetUpChartModel.Value = sentByte);
74 |
75 | _timer = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(1))
76 | .Subscribe(x => _comboModel.ComputerDataUpdate());
77 |
78 | ClosingCommand = ReactiveCommand.Create(e =>
79 | {
80 | _timer.Dispose();
81 | _comboModel.Dispose();
82 | });
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/SysMonAvalonia/ViewModels/DeviceIoWidgetViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.ObjectModel;
3 | using System.Reactive;
4 | using System.Reactive.Linq;
5 | using Avalonia.Controls;
6 | using LiveChartsCore;
7 | using LiveChartsCore.SkiaSharpView;
8 | using ReactiveUI;
9 | using SysMonAvalonia.Models;
10 | using SysMonAvalonia.Data;
11 | using SysMonAvalonia.Services;
12 |
13 | namespace SysMonAvalonia.ViewModels
14 | {
15 | public class DeviceIoWidgetViewModel : ViewModelBase
16 | {
17 | private readonly DeviceIoModel _deviceIoModel;
18 | private readonly ChartModel _chartModel;
19 | private IDisposable _timer;
20 |
21 | private byte _updCountCollection;
22 | private byte _updCountSpace;
23 | private byte _updCountInfo;
24 |
25 | public ReactiveCommand ShutdownCommand { get; } = ReactiveCommand.Create(() => AppService.ShutdownApp());
26 |
27 | public ReactiveCommand ShowSettingsCommand { get; } =
28 | ReactiveCommand.Create(() => AppService.ShowSettings());
29 |
30 | public ReactiveCommand ClosingCommand { get; }
31 | public ReactiveCommand MoveWidgetCommand { get; }
32 |
33 | public ReadOnlyObservableCollection DeviceCollection => _deviceIoModel.DeviceCollection;
34 |
35 | public ISeries[] Series
36 | {
37 | get => _chartModel.Series;
38 | }
39 | public Axis[] XAxis
40 | {
41 | get => _chartModel.XAxis;
42 | }
43 | public Axis[] YAxis
44 | {
45 | get => _chartModel.YAxis;
46 | }
47 |
48 | public double ChartValue
49 | {
50 | set => _chartModel.Value = value;
51 | }
52 |
53 | public DeviceIoWidgetViewModel()
54 | {
55 | _updCountCollection = 0;
56 | _updCountInfo = 0;
57 | _updCountSpace = 0;
58 |
59 | _deviceIoModel = new();
60 | _chartModel = new();
61 |
62 | MoveWidgetCommand = ReactiveCommand.Create(e =>
63 | {
64 | if (e != null)
65 | {
66 | SettingData.CurrentSetting.DeviceIoWidget.X = e.Point.X;
67 | SettingData.CurrentSetting.DeviceIoWidget.Y = e.Point.Y;
68 | }
69 | });
70 |
71 | ClosingCommand = ReactiveCommand.Create(e =>
72 | {
73 | _timer?.Dispose();
74 | _deviceIoModel.Dispose();
75 | return Unit.Default;
76 | });
77 |
78 | _timer = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(1)).Subscribe(x => UpdateTimer());
79 | }
80 |
81 | private void UpdateTimer()
82 | {
83 | if (_updCountCollection == 0)
84 | {
85 | _deviceIoModel.UpdateDeviceCollection();
86 |
87 | _updCountCollection = 180;
88 | }
89 |
90 | _deviceIoModel.UpdatePerformance();
91 |
92 | if (_updCountSpace == 0)
93 | {
94 | _deviceIoModel.UpdateDeviceSpace();
95 | _updCountSpace = 60;
96 | }
97 |
98 | if (_updCountInfo == 0)
99 | {
100 | _deviceIoModel.UpdateDeviceInfo();
101 | _updCountInfo = 120;
102 | }
103 |
104 | _updCountCollection--;
105 | _updCountSpace--;
106 | _updCountInfo--;
107 | }
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/SysMonAvalonia/ViewModels/SettingViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Reactive;
4 | using ReactiveUI;
5 | using SysMonAvalonia.Data;
6 | using SysMonAvalonia.Models;
7 | using SysMonAvalonia.Localization;
8 | using Weather;
9 | using Hardware.Windows.Network;
10 | using SysMonAvalonia.Services;
11 |
12 | namespace SysMonAvalonia.ViewModels
13 | {
14 | public class SettingViewModel : ViewModelBase
15 | {
16 | private SettingModel _settingModel;
17 | private List _cityCollection;
18 | private string _textFind;
19 | private bool _isOpenPopup;
20 | private int _selectCity;
21 | private int _selectNetworkAdapter;
22 |
23 | public SettingData CurrentSettingData { get; }
24 | public string[] LanguageList { get; }
25 | public string[] ThemeList { get; }
26 | public string[] WeatherProviderList { get; }
27 | public string[] NetworkUnitList { get; }
28 | public List CityCollection
29 | {
30 | get => _cityCollection;
31 | set => this.RaiseAndSetIfChanged(ref _cityCollection, value);
32 | }
33 | public List NetworkAdapterCollection
34 | {
35 | get => _settingModel.NetworkAdapters;
36 | }
37 | public string TextFind
38 | {
39 | get => _textFind;
40 | set => this.RaiseAndSetIfChanged(ref _textFind, value);
41 | }
42 | public bool IsOpenPopup
43 | {
44 | get => _isOpenPopup;
45 | set => this.RaiseAndSetIfChanged(ref _isOpenPopup, value);
46 | }
47 | public int SelectCity
48 | {
49 | get => _selectCity;
50 | set => this.RaiseAndSetIfChanged(ref _selectCity, value);
51 | }
52 | public int SelectNetworkAdapter
53 | {
54 | get => _selectNetworkAdapter;
55 | set => this.RaiseAndSetIfChanged(ref _selectNetworkAdapter, value);
56 | }
57 |
58 | public bool IsAutoStart
59 | {
60 | get => _settingModel.AutostartEnable;
61 | set => _settingModel.AutostartEnable = value;
62 | }
63 |
64 | public ReactiveCommand CloseCommand { get; } = ReactiveCommand.Create(() =>
65 | {
66 | SettingModel.Save();
67 | AppService.CloseSettings();
68 | });
69 |
70 | public SettingViewModel()
71 | {
72 | _settingModel = new();
73 |
74 | CurrentSettingData = SettingData.CurrentSetting;
75 | LanguageList = new[] { Language.Locale.English, Language.Locale.Russia };
76 | ThemeList = new[] { Language.Locale.Dark, Language.Locale.Light };
77 | WeatherProviderList = new[] { "AccuWeather", "Gismeteo", "OpenWeatherMap", "WorldWeatherOnline", "Weather.com" };
78 | NetworkUnitList = new[] { Language.Locale.MbitSettings, Language.Locale.MbyteSettings };
79 | IsOpenPopup = false;
80 |
81 | this.WhenAnyValue(x => x.TextFind).Subscribe(text =>
82 | {
83 | if (text != null && text.Length > 3) CityCollection = SettingModel.FindCities(text);
84 |
85 | if (CityCollection == null || CityCollection.Count == 0) IsOpenPopup = false;
86 | else IsOpenPopup = true;
87 | });
88 |
89 | this.WhenAnyValue(x => x.SelectCity).Subscribe(index =>
90 | {
91 | if (CityCollection == null) return;
92 |
93 | SettingData.CurrentSetting.WeatherCity = CityCollection[index].City;
94 | SettingData.CurrentSetting.WeatherID = CityCollection[index].ID;
95 |
96 | IsOpenPopup = false;
97 | });
98 |
99 | this.WhenAnyValue(x => x.SelectNetworkAdapter).Subscribe(index =>
100 | {
101 | List adapterList = NetworkAdapterCollection;
102 |
103 | if (adapterList == null) return;
104 |
105 | SettingData.CurrentSetting.AdapterID = adapterList[index].ID;
106 | SettingData.CurrentSetting.AdapterName = adapterList[index].Name;
107 | });
108 | }
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/SysMonAvalonia/ViewModels/ViewModelBase.cs:
--------------------------------------------------------------------------------
1 | using ReactiveUI;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace SysMonAvalonia.ViewModels
7 | {
8 | public class ViewModelBase : ReactiveObject
9 | {
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/SysMonAvalonia/ViewModels/WeatherWidgetViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.ObjectModel;
3 | using System.ComponentModel;
4 | using System.Reactive;
5 | using System.Reactive.Linq;
6 | using System.Threading.Tasks;
7 | using Avalonia.Controls;
8 | using ReactiveUI;
9 | using SysMonAvalonia.Models;
10 | using SysMonAvalonia.Data;
11 | using SysMonAvalonia.Services;
12 |
13 | namespace SysMonAvalonia.ViewModels
14 | {
15 | public class WeatherWidgetViewModel : ViewModelBase
16 | {
17 | private readonly WeatherModel _weatherModel;
18 |
19 | public ReactiveCommand ShutdownCommand { get; } = ReactiveCommand.Create(() => AppService.ShutdownApp());
20 | public ReactiveCommand ShowSettingsCommand { get; } = ReactiveCommand.Create(() => AppService.ShowSettings());
21 | public ReactiveCommand UpdateCommand { get; }
22 | public ReactiveCommand MoveCommand { get; }
23 | public ReactiveCommand ClosingCommand { get; }
24 |
25 | public WeatherData? CurrentWeather => _weatherModel.CurrentWeather;
26 | public ReadOnlyObservableCollection ForecastHourlyCollection => _weatherModel.HourlyForecasts;
27 | public ReadOnlyObservableCollection ForecastDailyCollection => _weatherModel.DailyForecasts;
28 |
29 | private IDisposable _timer;
30 |
31 | public WeatherWidgetViewModel()
32 | {
33 | UpdateCommand = ReactiveCommand.Create(WeatherRefresh);
34 | MoveCommand = ReactiveCommand.Create(e =>
35 | {
36 | if (e != null)
37 | {
38 | SettingData.CurrentSetting.WeatherWidget.X = e.Point.X;
39 | SettingData.CurrentSetting.WeatherWidget.Y = e.Point.Y;
40 | }
41 | });
42 | ClosingCommand = ReactiveCommand.Create(e =>
43 | {
44 | _timer?.Dispose();
45 | return Unit.Default;
46 | });
47 |
48 | _weatherModel = new();
49 |
50 | _timer = Observable.Timer(TimeSpan.Zero, TimeSpan.FromMinutes(SettingData.CurrentSetting.WeatherInterval))
51 | .Subscribe(x => _weatherModel.WeatherRefresh());
52 | }
53 |
54 | private async void WeatherRefresh()
55 | {
56 | await Task.Run(() => _weatherModel.WeatherRefresh());
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/SysMonAvalonia/Views/ComboWidgetView.axaml.cs:
--------------------------------------------------------------------------------
1 | using Avalonia;
2 | using Avalonia.Controls;
3 | using Avalonia.Input;
4 | using Avalonia.Markup.Xaml;
5 |
6 | namespace SysMonAvalonia.Views
7 | {
8 | public partial class ComboWidgetView : Window
9 | {
10 | public ComboWidgetView()
11 | {
12 | InitializeComponent();
13 | #if DEBUG
14 | this.AttachDevTools();
15 | #endif
16 | }
17 |
18 | private void InitializeComponent()
19 | {
20 | AvaloniaXamlLoader.Load(this);
21 | }
22 |
23 | private void InputElement_OnPointerPressed(object? sender, PointerPressedEventArgs e)
24 | {
25 | if (e.GetCurrentPoint(null).Properties.IsLeftButtonPressed) this.BeginMoveDrag(e);
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/SysMonAvalonia/Views/DeviceIoWidgetView.axaml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
27 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
70 |
78 |
87 |
96 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/SysMonAvalonia/Views/DeviceIoWidgetView.axaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Avalonia;
3 | using Avalonia.Controls;
4 | using Avalonia.Controls.ApplicationLifetimes;
5 | using Avalonia.Input;
6 | using Avalonia.Interactivity;
7 | using Avalonia.Markup.Xaml;
8 |
9 | namespace SysMonAvalonia.Views
10 | {
11 | public partial class DeviceIoWidgetView : Window
12 | {
13 | public DeviceIoWidgetView()
14 | {
15 | InitializeComponent();
16 | #if DEBUG
17 | this.AttachDevTools();
18 | #endif
19 | }
20 |
21 | private void InitializeComponent()
22 | {
23 | AvaloniaXamlLoader.Load(this);
24 | }
25 |
26 | private void Widget_OnPointerPressed(object? sender, PointerPressedEventArgs e)
27 | {
28 | if (e.GetCurrentPoint(null).Properties.IsLeftButtonPressed)
29 | this.BeginMoveDrag(e);
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/SysMonAvalonia/Views/SettingView.axaml.cs:
--------------------------------------------------------------------------------
1 | using Avalonia;
2 | using Avalonia.Controls;
3 | using Avalonia.Markup.Xaml;
4 |
5 | namespace SysMonAvalonia.Views
6 | {
7 | public partial class SettingView : Window
8 | {
9 | public SettingView()
10 | {
11 | InitializeComponent();
12 | #if DEBUG
13 | this.AttachDevTools();
14 | #endif
15 | }
16 |
17 | private void InitializeComponent()
18 | {
19 | AvaloniaXamlLoader.Load(this);
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/SysMonAvalonia/Views/WeatherWidgetView.axaml.cs:
--------------------------------------------------------------------------------
1 | using Avalonia;
2 | using Avalonia.Controls;
3 | using Avalonia.Input;
4 | using Avalonia.Markup.Xaml;
5 |
6 | namespace SysMonAvalonia.Views
7 | {
8 | public partial class WeatherWidgetView : Window
9 | {
10 | public WeatherWidgetView()
11 | {
12 | InitializeComponent();
13 | #if DEBUG
14 | this.AttachDevTools();
15 | #endif
16 | }
17 |
18 | private void InitializeComponent()
19 | {
20 | AvaloniaXamlLoader.Load(this);
21 | }
22 |
23 | private void Widget_OnPointerPressed(object? sender, PointerPressedEventArgs e)
24 | {
25 | if (e.GetCurrentPoint(null).Properties.IsLeftButtonPressed)
26 | this.BeginMoveDrag(e);
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/SysMonAvalonia/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
54 |
62 |
63 |
64 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/SysMonAvalonia/nuget.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Weather/Helper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 | using System.Net.Http;
4 | using System.Threading.Tasks;
5 | using NLog;
6 |
7 | namespace Weather
8 | {
9 | static class Helper
10 | {
11 | private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
12 |
13 | public static async Task GetNetContent(string url)
14 | {
15 | string content = null;
16 |
17 | using (HttpClientHandler handler = new())
18 | {
19 | if (handler.SupportsAutomaticDecompression) handler.AutomaticDecompression = DecompressionMethods.GZip |
20 | DecompressionMethods.Deflate;
21 |
22 | using (HttpClient client = new(handler))
23 | {
24 | client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.102 Safari/537.36");
25 | client.Timeout = TimeSpan.FromSeconds(6);
26 | client.DefaultRequestHeaders.AcceptEncoding.ParseAdd("gzip");
27 |
28 | try { content = await client.GetStringAsync(url); }
29 | catch (Exception ex)
30 | { Logger.Error(ex, $"HttpClient: {ex.Message}"); }
31 | }
32 | }
33 |
34 | return content;
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Weather/LocationData.cs:
--------------------------------------------------------------------------------
1 | namespace Weather
2 | {
3 | public class LocationData
4 | {
5 | public string ID { get; set; }
6 | public string City { get; set; }
7 | public string Country { get; set; }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Weather/NLog.config:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Weather/Providers/IProvider.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Globalization;
3 |
4 | namespace Weather.Providers
5 | {
6 | public interface IProvider
7 | {
8 | public List GetLocation(string query, CultureInfo culture, string apiKey);
9 | public WeatherData GetCurrentWeatherData(string id, CultureInfo culture, string apiKey);
10 | }
11 | }
--------------------------------------------------------------------------------
/Weather/Providers/Providers.cs:
--------------------------------------------------------------------------------
1 | namespace Weather.Providers
2 | {
3 | public enum Providers : int
4 | {
5 | None = -1,
6 | AccuWeather = 0,
7 | Gismeteo = 1,
8 | OpenWeatherMap = 2,
9 | WorldWeatherOnline = 3,
10 | Wunderground = 4
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Weather/Weather.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | PreserveNewest
14 |
15 |
16 |
17 |
18 | Always
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/Weather/WeatherData.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Collections.Generic;
4 | using Newtonsoft.Json;
5 | using Newtonsoft.Json.Linq;
6 |
7 | namespace Weather
8 | {
9 | public class WeatherData
10 | {
11 | public sbyte Temperature { set; get; }
12 | public sbyte ApparentTemperature { set; get; }
13 | public sbyte HighTemperature { set; get; }
14 | public sbyte LowTemperature { set; get; }
15 | public short WindSpeed { set; get; }
16 | public double WindDirection { set; get; }
17 | public byte CloudCover { set; get; }
18 | public byte PrecipChange { set; get; }
19 | public WindUnitEnum WindUnit { set; get; }
20 | public byte Humidity { set; get; }
21 | public short Pressure { set; get; }
22 | public byte UVIndex { set; get; }
23 | public byte SkyCode { set; get; }
24 | public string Text { set; get; }
25 | public DateTime Date { set; get; }
26 | public DateTime Sunrise { set; get; }
27 | public DateTime Sunset { set; get; }
28 | public string City { get; set; }
29 | public List ForecastDaily { set; get; }
30 | public List ForecastHourly { set; get; }
31 |
32 | private readonly string _serializePath;
33 |
34 | public WeatherData()
35 | {
36 | #if DEBUG
37 | _serializePath = AppContext.BaseDirectory + @"\WeatherData.json";
38 | #else
39 | _serializePath = Path.GetDirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName) + @"\WeatherData.json";
40 | #endif
41 |
42 | Temperature = 0;
43 | ApparentTemperature = 0;
44 | HighTemperature = 0;
45 | LowTemperature = 0;
46 | WindSpeed = 0;
47 | WindDirection = 0;
48 | CloudCover = 120;
49 | PrecipChange = 120;
50 | WindUnit = WindUnitEnum.Ms;
51 | Humidity = 0;
52 | Pressure = 0;
53 | UVIndex = 0;
54 | SkyCode = 0;
55 | Text = null;
56 | ForecastDaily = null;
57 | ForecastHourly = null;
58 | }
59 |
60 | public void Serialize()
61 | {
62 | dynamic jObject = new JObject();
63 | jObject.Temperature = Temperature;
64 | jObject.ApparentTemperature = ApparentTemperature;
65 | jObject.HightTemperature = HighTemperature;
66 | jObject.LowTemperature = LowTemperature;
67 | jObject.WindSpeed = WindSpeed;
68 | jObject.CloudCover = CloudCover;
69 | jObject.PrecipChange = PrecipChange;
70 | jObject.WindUnit = WindUnit;
71 | jObject.WindDirection = WindDirection;
72 | jObject.Humidity = Humidity;
73 | jObject.Pressure = Pressure;
74 | jObject.UVIndex = UVIndex;
75 | jObject.SkyCode = SkyCode;
76 | jObject.Text = Text;
77 | jObject.Date = Date;
78 | jObject.Sunrise = Sunrise;
79 | jObject.Sunset = Sunset;
80 | jObject.City = City;
81 | jObject.ForecastHourly = JArray.FromObject(ForecastHourly);
82 | jObject.ForecastDaily = JArray.FromObject(ForecastDaily);
83 |
84 | try
85 | {
86 | string json = JsonConvert.SerializeObject(jObject);
87 |
88 | File.WriteAllText(_serializePath, json);
89 | }
90 | catch
91 | {
92 |
93 | }
94 | }
95 |
96 | public static WeatherData Deserialize()
97 | {
98 | dynamic jObject;
99 |
100 | try
101 | {
102 | jObject = JsonConvert.DeserializeObject(File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + @"\WeatherData.json"));
103 | }
104 | catch
105 | {
106 | return null;
107 | }
108 |
109 | WeatherData weatherData = new WeatherData();
110 |
111 | try { weatherData.Temperature = jObject.Temperature.ToObject(); } catch { /* ignored */ }
112 | try { weatherData.ApparentTemperature = jObject.ApparentTemperature.ToObject(); } catch { /* ignored */ }
113 | try { weatherData.HighTemperature = jObject.HightTemperature.ToObject(); } catch { /* ignored */ }
114 | try { weatherData.LowTemperature = jObject.LowTemperature.ToObject(); } catch { /* ignored */ }
115 | try { weatherData.WindSpeed = jObject.WindSpeed.ToObject(); } catch { /* ignored */ }
116 | try { weatherData.WindUnit = jObject.WindUnit.ToObject(); } catch { /* ignored */ }
117 | try { weatherData.WindDirection = jObject.WindDirection.ToObject(); } catch { /* ignored */ }
118 | try { weatherData.CloudCover = jObject.CloudCover.ToObject(); } catch { /* ignored */ }
119 | try { weatherData.PrecipChange = jObject.PrecipChange.ToObject(); } catch { /* ignored */ }
120 | try { weatherData.Humidity = jObject.Humidity.ToObject(); } catch { /* ignored */ }
121 | try { weatherData.Pressure = jObject.Pressure.ToObject(); } catch { /* ignored */ }
122 | try { weatherData.UVIndex = jObject.UVIndex.ToObject(); } catch { /* ignored */ }
123 | try { weatherData.SkyCode = jObject.SkyCode.ToObject(); } catch { /* ignored */ }
124 | try { weatherData.Text = jObject.Text.ToObject(); } catch { /* ignored */ }
125 | try { weatherData.Date = jObject.Date.ToObject(); } catch { /* ignored */ }
126 | try { weatherData.Sunrise = jObject.Sunrise.ToObject(); } catch { /* ignored */ }
127 | try { weatherData.Sunset = jObject.Sunset.ToObject(); } catch { /* ignored */ }
128 | try { weatherData.City = jObject.City.ToObject(); } catch { /* ignored */ }
129 | try { weatherData.ForecastHourly = ((JArray)jObject.ForecastHourly).ToObject>(); } catch { /* ignored */ }
130 | try { weatherData.ForecastDaily = ((JArray)jObject.ForecastDaily).ToObject>(); } catch { /* ignored */ }
131 |
132 | return weatherData;
133 | }
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/Weather/WindUnitEnum.cs:
--------------------------------------------------------------------------------
1 | namespace Weather
2 | {
3 | public enum WindUnitEnum : byte
4 | {
5 | Mh = 0,
6 | KmH = 1,
7 | Ms = 2
8 | }
9 | }
--------------------------------------------------------------------------------