├── .editorconfig
├── .github
└── lockdown.yml
├── .gitignore
├── CHANGELOG
├── CONTRIBUTING.md
├── JuisCheck.sln
├── JuisCheck
├── .editorconfig
├── .vs
│ └── JuisCheck.csproj.dtbcache.json
├── AVM
│ ├── JUIS.cs
│ ├── JUIS.wsdl
│ ├── JUIS_http.wsdl
│ └── JUIS_https.wsdl
├── App.xaml
├── App.xaml.cs
├── CollectionSettings.cs
├── ComboBoxEx.cs
├── ComboBoxValue.cs
├── ComboBoxValueComparer.cs
├── ContextMenuHelper.cs
├── DectDevice.cs
├── DectDeviceDialog.xaml
├── DectDeviceDialog.xaml.cs
├── Device.cs
├── DeviceCollection.cs
├── DeviceComparer.cs
├── DeviceProperty.cs
├── DownloadDialog.xaml
├── DownloadDialog.xaml.cs
├── ExtensionMethods.cs
├── FindUpdatesDialog.xaml
├── FindUpdatesDialog.xaml.cs
├── FodyWeavers.xml
├── FodyWeavers.xsd
├── GlobalSuppressions.cs
├── JUIS.cs
├── Jason
│ └── BoxInfo.cs
├── JuisCheck.csproj
├── JuisDevice.cs
├── JuisDeviceDialog.xaml
├── JuisDeviceDialog.xaml.cs
├── Lang
│ ├── JCstring.Designer.cs
│ ├── JCstring.de.resx
│ ├── JCstring.it.resx
│ └── JCstring.resx
├── MainWindow.Backstage.cs
├── MainWindow.Devices.cs
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── MessageBoxEx.xaml
├── MessageBoxEx.xaml.cs
├── MultiSelectDataGrid.cs
├── NaturalStringComparer.cs
├── Properties
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ ├── Resources.resx
│ ├── Settings.Designer.cs
│ └── Settings.settings
├── RecentFileButton.cs
├── RecentItemsCollection.cs
├── Resources
│ ├── Converters
│ │ ├── BoolToVisibilityConverter.cs
│ │ ├── InverseBooleanConverter.cs
│ │ └── NullableDateTimeToStringConverter.cs
│ ├── Images
│ │ ├── 16x16
│ │ │ ├── oxygen-application-exit.png
│ │ │ ├── oxygen-dialog-warning.png
│ │ │ ├── oxygen-document-close.png
│ │ │ ├── oxygen-document-open-recent.png
│ │ │ ├── oxygen-document-open.png
│ │ │ ├── oxygen-document-save-as.png
│ │ │ ├── oxygen-document-save.png
│ │ │ ├── oxygen-help-about.png
│ │ │ └── oxygen-preferences-system.png
│ │ ├── 32x32
│ │ │ ├── oxygen-dialog-information.png
│ │ │ ├── oxygen-dialog-ok-apply.png
│ │ │ ├── oxygen-document-close.png
│ │ │ ├── oxygen-document-edit.png
│ │ │ ├── oxygen-document-new.png
│ │ │ ├── oxygen-document-open-recent.png
│ │ │ ├── oxygen-download.png
│ │ │ ├── oxygen-edit-clear-list.png
│ │ │ ├── oxygen-edit-copy.png
│ │ │ ├── oxygen-edit-paste.png
│ │ │ ├── oxygen-edit-select-all.png
│ │ │ ├── oxygen-run-build-clean.png
│ │ │ └── oxygen-system-search.png
│ │ └── 48x48
│ │ │ └── JuisCheck.ico
│ ├── ValidationRules
│ │ ├── ComboBoxValueSelectedRule.cs
│ │ ├── StringInt32RangeRule.cs
│ │ └── StringNotNullOrWhiteSpaceRule.cs
│ └── XAML
│ │ ├── BaseStyles.xaml
│ │ ├── ColorsAndBrushes.xaml
│ │ ├── Converters.xaml
│ │ ├── MainWindowBackstageStyles.xaml
│ │ ├── MainWindowDataGridStyles.xaml
│ │ ├── MainWindowDataGridTemplates.xaml
│ │ ├── MainWindowRibbonStyles.xaml
│ │ └── RecentFileButtonTemplate.xaml
├── XML
│ ├── JC1Data.cs
│ ├── JC1Device.cs
│ ├── JC1DeviceKind.cs
│ ├── JC2Data.cs
│ ├── JC2DectDevice.cs
│ ├── JC2JuisDevice.cs
│ ├── JC2Setting.cs
│ └── JCData.cs
└── app.config
├── LICENSE
├── README.md
├── examples
├── FritzBox_Obsolete_Release.xml
├── FritzBox_Release.xml
├── FritzDECT_Release.xml
├── FritzPowerline_Release.xml
├── FritzWLAN_Obsolete_Release.xml
└── FritzWLAN_Release.xml
└── libraries
├── Muon.DotNetExtensions.dll
├── Muon.DotNetExtensions.pdb
├── Muon.DotNetExtensions.xml
├── Muon.Windows.Controls.dll
├── Muon.Windows.Controls.pdb
├── Muon.Windows.Controls.xml
├── Muon.Windows.dll
├── Muon.Windows.pdb
└── Muon.Windows.xml
/.editorconfig:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.github/lockdown.yml:
--------------------------------------------------------------------------------
1 | # Configuration for Repo Lockdown - https://github.com/dessant/repo-lockdown
2 |
3 | only: pulls
4 |
5 | pulls:
6 | comment: >
7 | This repository does not accept pull requests.
8 | Please read the CONTRIBUTING document at https://github.com/kingfisher63/avm_juischeck for guidance.
9 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /.vs
2 | /JuisCheck/bin
3 | /JuisCheck/obj
4 | /bin
5 |
--------------------------------------------------------------------------------
/CHANGELOG:
--------------------------------------------------------------------------------
1 | v2.1.2 (2023/01/28)
2 | -------------------
3 | Change: 'Upgrade' predefined DECT base to FRITZ!OS 7.50.
4 | Fix: handle leading/trailing whitespace in update version (triggered
5 | 'Invalid firmware update version' error during 'Make current').
6 |
7 | v2.1.1 (2021/04/02)
8 | -------------------
9 | Change: Updated Italian localization (thanks bovirus).
10 | Fix: HTTPS downloads failed because TLS1.2 was not enabled.
11 |
12 | Note: HTTPS downloads require Windows 7 or later as Windows
13 | Vista and earlier do not support TLS1.2.
14 |
15 | v2.1.0 (2020/10/19)
16 | -------------------
17 | Change: DECT: use JUIS instead of CATI server to search for updates.
18 | New: DECT: view update info (release notes) in web browser.
19 | Fix: DECT: update search with language other than German returned
20 | an error.
21 | Fix: DECT: support for 5-part version numbers (FRITZ!DECT 500).
22 |
23 | Note: If you have a FRITZ!DECT 500 in a device collection, you must
24 | either correct the firmware version manually or do an update
25 | search and make the found version current. JuisCheck did not
26 | handle 5-part version numbers correctly prior to v2.1.0.
27 |
28 | v2.0.3 (2020/10/16)
29 | -------------------
30 | Change: 'Upgrade' predefined DECT base to FRITZ!OS 7.21.
31 | Change: No firmware major version warning if Hardware == FirmwareMajor
32 | for Hardware >= 249 (FRITZ!Powerline 1260v2). This limit is an
33 | educated guess and may change in the future.
34 | New: Support for LabPLUS firmware type string (build type 1007)
35 | Fix: Highlight new updates also for DECT devices.
36 | Fix: Beta (Labor) DECT firmware cannot be found with beta (Labor)
37 | FRITZ!OS version (wrong FRITZ!OS version format in query).
38 |
39 | v2.0.2 (2020/04/21)
40 | -------------------
41 | Change: Updated Italian localization (thanks bovirus).
42 | New: Highlight new updates (i.e. updates that differ from the current
43 | value in the Update column).
44 | Doc: updated README.md
45 | Doc: added CONTRIBUTING.md
46 |
47 | v2.0.1 (2020/04/13)
48 | -------------------
49 | New: Predefined DECT base device (FRITZ!Box 7590 with FRITZ!OS 7.12).
50 | New: German localization.
51 | New: Show download file name in download window caption.
52 | Fix: Application restart message is shown when resetting settings to
53 | default even if the UI language setting is already default.
54 | Fix: Backstage panel width is too small for German localization.
55 |
56 | v2.0.0 (2020/04/04)
57 | -------------------
58 | Note: JuisCheck v2 is a major release that comes with some breaking changes.
59 | Please consult the README.md file for details about upgrading from
60 | JuisCheck v1.x.
61 | Change: Requires .NET Framework 4.5 or later (Windows Vista or later).
62 | Change: New collection XML file format (incompatible with JuisCheck 1.x).
63 | Change: Column visibility is saved in the collection XML file.
64 | Change: Use built-in engine to download firmware images instead of launching
65 | the default web browser as web browsers are dropping FTP support.
66 | Change: No firmware major version warning if Hardware == FirmwareMajor for
67 | Hardware >= 252 (FRITZ!Box 6660 Cable). This limit is an educated
68 | guess and may change in the future.
69 | New: Select device as Mesh master for non-DECT devices.
70 | New: Select device as DECT base for DECT devices.
71 | New: Column for Mesh master / DECT base (replaces Base Fritz!OS column).
72 | New: Select default columns for new collections (in backstage settings).
73 | New: Select user interface language (default: automatic).
74 | New: Italian localization (thanks bovirus).
75 | New: Support for build type 1006 (TEST beta).
76 | New: Support for devices like DECT 500 which have a different firmware
77 | file name format (5 version parts instead of 4).
78 | New: Portable mode.
79 | New: Menu item icons in backstage.
80 | New: Exit the program with Ctrl-X.
81 | Fix: Device information tooltip is not updated after data change.
82 | Fix: Device information tooltip date/time format is inconsistent with
83 | table date/time format.
84 | Fix: FileNotFoundException is thrown at startup when trying to autoload
85 | a file that does not exist (eg. because it has been renamed or
86 | deleted).
87 | Fix: Firmware version string is not updated after build type change under
88 | certain circumstances.
89 | Fix: Some version formats in the update info cannot not be parsed. JuisCheck
90 | can now handle a wide variety of formats.
91 | Fix: Flags text box height is too small on Windows 10.
92 |
93 | v1.4.2 (2019/06/23)
94 | -------------------
95 | New: Support for build type 1007 (PLUS beta).
96 | Fix: Update version 149.07.08-67660Labor for FRITZ!Box 7560 could not be
97 | made current due to missing white space between the build number (67660)
98 | and the build type qualifier (Labor). The update version is a string
99 | that is apparently hand crafted by AVM which may cause unanticipated
100 | format variations.
101 |
102 | v1.4.1 (2019/03/07)
103 | -------------------
104 | New: Keyboard shortcuts for all ribbon buttons.
105 | Fix: Datagrid keyboard navigation did not work correctly when focus was
106 | returned to the datagrid (e.g. after adding or editing a device).
107 | Fix: Update version 105.06.85i for FRITZ!Box 6840 LTE International could
108 | not be made current due to the trailing 'i'.
109 |
110 | v1.4.0 (2018/12/29)
111 | -------------------
112 | New: Add a device that is a copy of the selected device.
113 | New: JuisCheck remembers the directory of the last successful 'Open' or
114 | 'Save As' dialog. Opening a device collection from the Recent Files
115 | list does not change the remembered directory.
116 | Fix: The column width would jump when resizing a column to a width less
117 | than the column header text width.
118 | Fix: The sort direction was only cleared on the 'Device name' and 'Product
119 | name' columns when a new device collection was opened or the current
120 | collection was closed.
121 | Fix: The column width was not reset to Auto when a new device collection
122 | was opened or the current collection was closed.
123 | Fix: The 'Update file name' column was not cleared in the data grid when
124 | an update was made current.
125 |
126 | v1.3.0 (2018/12/28)
127 | -------------------
128 | New: Setting to automatically load the current device collection at next
129 | program start.
130 |
131 | v1.2.0 (2018/12/27)
132 | -------------------
133 | New: Support for the legacy jason_boxinfo.xml device information. When a
134 | request for juis_boxinfo.xml fails with HTTP error 404 (Not Found),
135 | JuisCheck will make a request for jason_boxinfo.xml. A heuristic is
136 | used to determine the firmware build type from the Lab element (the
137 | default is Release).
138 |
139 | v1.1.0 (2018/12/25)
140 | -------------------
141 | New: Recent files context menu: open file, remove file from the list.
142 | New: Recent files: button to remove all files from the list.
143 | New: Hide/show datagrid columns via a context menu on the column headers.
144 | New: Datagrid columns for hardware, country, language and update file name
145 | (hidden by default).
146 | New: Button to reset settings to defaults.
147 | Fix: The device information tooltip on the datagrid was garbled ('Update file
148 | name' and 'Last checked' fields were in the same row for non-DECT devices).
149 | Change: Base Fritz!OS column is hidden by default.
150 |
151 | v1.0.1 (2018/12/24)
152 | -------------------
153 | Fix: JuisCheck would exit silently in case of an unhandled exception. It now
154 | displays an error message and attempts to copy the exception data to the
155 | clipboard before exiting.
156 | Fix: A COMException might be thrown when copying image URLs to the clipboard.
157 | The cause is probably that the clipboard is locked by another program
158 | (e.g. some tool that monitors the clipboard). JuisCheck now retries
159 | in case of errors and displays an error message if all attempts fail.
160 | Fix: JuisCheck used Linux style newline (\n) when copying multiple URLs to
161 | the clipboard instead of Windows style newline (\r\n).
162 | Fix: The tooltips of the Recent and Settings backstage menu buttons would
163 | also be shown on the panel area. The tooltips are now restricted to the
164 | button area.
165 |
166 | v1.0.0 (2018/12/20)
167 | -------------------
168 | Initial release
169 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | JuisCheck is *Open Source* (so that you can inspect the code or create your own
4 | version if you like). However it is not *Open Collaboration*. This repository
5 | offers JuisCheck 'as is' and does not accept pull requests. **Pull requests are
6 | closed automatically.**
7 |
8 | ## Bug reports
9 |
10 | Create a new issue if you wish to report a bug. Please include any error messages
11 | (if applicable) and steps to reproduce (if possible).
12 |
13 | ## Features requests
14 |
15 | Create a new issue if you wish to suggest a new feature. Feature requests will be
16 | considered if they are within the scope of the program as outlined at the top of
17 | the [README](README.md) document.
18 |
19 | ## User interface translation (localization)
20 |
21 | Tranlations are only accepted for user interface languages *supported by FRITZ!OS*.
22 | Unfortunately it is impossible to selectively permit pull requests. Kindly create
23 | a new issue if you wish to contribute a translation.
24 |
--------------------------------------------------------------------------------
/JuisCheck.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29920.165
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JuisCheck", "JuisCheck\JuisCheck.csproj", "{E1A82DAF-EE0A-43FA-BEC7-EB63EC3EF78D}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{37F69898-70D6-44AD-9094-53D5A0B7FF34}"
9 | ProjectSection(SolutionItems) = preProject
10 | .editorconfig = .editorconfig
11 | EndProjectSection
12 | EndProject
13 | Global
14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
15 | Debug|Any CPU = Debug|Any CPU
16 | Release|Any CPU = Release|Any CPU
17 | EndGlobalSection
18 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
19 | {E1A82DAF-EE0A-43FA-BEC7-EB63EC3EF78D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
20 | {E1A82DAF-EE0A-43FA-BEC7-EB63EC3EF78D}.Debug|Any CPU.Build.0 = Debug|Any CPU
21 | {E1A82DAF-EE0A-43FA-BEC7-EB63EC3EF78D}.Release|Any CPU.ActiveCfg = Release|Any CPU
22 | {E1A82DAF-EE0A-43FA-BEC7-EB63EC3EF78D}.Release|Any CPU.Build.0 = Release|Any CPU
23 | EndGlobalSection
24 | GlobalSection(SolutionProperties) = preSolution
25 | HideSolutionNode = FALSE
26 | EndGlobalSection
27 | GlobalSection(ExtensibilityGlobals) = postSolution
28 | SolutionGuid = {24B6B326-913B-4435-A843-AFA74EEB9288}
29 | EndGlobalSection
30 | EndGlobal
31 |
--------------------------------------------------------------------------------
/JuisCheck/.editorconfig:
--------------------------------------------------------------------------------
1 | # To learn more about .editorconfig see https://aka.ms/editorconfigdocs
2 |
3 | # CA1062: Validate arguments of public methods
4 | dotnet_code_quality.CA1062.exclude_extension_method_this_parameter = true
5 |
6 | [*.cs]
7 |
8 | # CA1303: Do not pass literals as localized parameters
9 | dotnet_diagnostic.CA1303.severity = none
10 |
11 | # Default severity for analyzer diagnostics with category 'Style'
12 | dotnet_analyzer_diagnostic.category-Style.severity = none
13 |
--------------------------------------------------------------------------------
/JuisCheck/.vs/JuisCheck.csproj.dtbcache.json:
--------------------------------------------------------------------------------
1 | {"RootPath":"D:\\Projects\\Roger\\Windows Utilities\\JuisCheck\\JuisCheck","ProjectFileName":"JuisCheck.csproj","Configuration":"Debug|AnyCPU","FrameworkPath":"","Sources":[{"SourceFile":"CollectionSettings.cs"},{"SourceFile":"ComboBoxEx.cs"},{"SourceFile":"ComboBoxValue.cs"},{"SourceFile":"ComboBoxValueComparer.cs"},{"SourceFile":"Connected Services\\JUIS\\Reference.cs"},{"SourceFile":"DectDevice.cs"},{"SourceFile":"DectDeviceDialog.xaml.cs"},{"SourceFile":"DeviceComparer.cs"},{"SourceFile":"DeviceProperty.cs"},{"SourceFile":"DownloadDialog.xaml.cs"},{"SourceFile":"FindUpdatesDialog.xaml.cs"},{"SourceFile":"GlobalSuppressions.cs"},{"SourceFile":"Jason\\BoxInfo.cs"},{"SourceFile":"JuisDevice.cs"},{"SourceFile":"MainWindow.Devices.cs"},{"SourceFile":"NaturalStringComparer.cs"},{"SourceFile":"RecentItemsCollection.cs"},{"SourceFile":"Resources\\Converters\\BoolToVisibilityConverter.cs"},{"SourceFile":"Resources\\Converters\\InverseBooleanConverter.cs"},{"SourceFile":"Resources\\Converters\\NullableDateTimeToStringConverter.cs"},{"SourceFile":"Resources\\ValidationRules\\ComboBoxValueSelectedRule.cs"},{"SourceFile":"Resources\\ValidationRules\\StringInt32RangeRule.cs"},{"SourceFile":"Resources\\ValidationRules\\StringNotNullOrWhiteSpaceRule.cs"},{"SourceFile":"XML\\JC1Data.cs"},{"SourceFile":"XML\\JC1Device.cs"},{"SourceFile":"XML\\JC1DeviceKind.cs"},{"SourceFile":"XML\\JC2Data.cs"},{"SourceFile":"XML\\JC2DectDevice.cs"},{"SourceFile":"XML\\JC2JuisDevice.cs"},{"SourceFile":"XML\\JC2Setting.cs"},{"SourceFile":"XML\\JCData.cs"},{"SourceFile":"App.xaml.cs"},{"SourceFile":"Device.cs"},{"SourceFile":"DeviceCollection.cs"},{"SourceFile":"JuisDeviceDialog.xaml.cs"},{"SourceFile":"Lang\\JCstring.Designer.cs"},{"SourceFile":"MainWindow.Backstage.cs"},{"SourceFile":"MainWindow.xaml.cs"},{"SourceFile":"MultiSelectDataGrid.cs"},{"SourceFile":"Properties\\AssemblyInfo.cs"},{"SourceFile":"Properties\\Resources.Designer.cs"},{"SourceFile":"Properties\\Settings.Designer.cs"},{"SourceFile":"obj\\Debug\\.NETFramework,Version=v4.5.AssemblyAttributes.cs"},{"SourceFile":"D:\\Projects\\Roger\\Windows Utilities\\JuisCheck\\JuisCheck\\obj\\Debug\\DectDeviceDialog.g.cs"},{"SourceFile":"D:\\Projects\\Roger\\Windows Utilities\\JuisCheck\\JuisCheck\\obj\\Debug\\DownloadDialog.g.cs"},{"SourceFile":"D:\\Projects\\Roger\\Windows Utilities\\JuisCheck\\JuisCheck\\obj\\Debug\\JuisDeviceDialog.g.cs"},{"SourceFile":"D:\\Projects\\Roger\\Windows Utilities\\JuisCheck\\JuisCheck\\obj\\Debug\\FindUpdatesDialog.g.cs"},{"SourceFile":"D:\\Projects\\Roger\\Windows Utilities\\JuisCheck\\JuisCheck\\obj\\Debug\\MainWindow.g.cs"},{"SourceFile":"D:\\Projects\\Roger\\Windows Utilities\\JuisCheck\\JuisCheck\\obj\\Debug\\App.g.cs"},{"SourceFile":"D:\\Projects\\Roger\\Windows Utilities\\JuisCheck\\JuisCheck\\obj\\Debug\\GeneratedInternalTypeHelper.g.cs"}],"References":[{"Reference":"C:\\Users\\Roger\\.nuget\\packages\\controlzex\\4.2.2\\lib\\net45\\ControlzEx.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Users\\Roger\\.nuget\\packages\\costura.fody\\4.1.0\\lib\\net40\\Costura.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Users\\Roger\\.nuget\\packages\\fluent.ribbon\\7.1.0\\lib\\net45\\Fluent.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.5\\Microsoft.CSharp.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Users\\Roger\\.nuget\\packages\\microsoft.xaml.behaviors.wpf\\1.1.19\\lib\\net45\\Microsoft.Xaml.Behaviors.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.5\\mscorlib.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"D:\\Projects\\Roger\\Windows Utilities\\JuisCheck\\libraries\\Muon.DotNetExtensions.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"D:\\Projects\\Roger\\Windows Utilities\\JuisCheck\\libraries\\Muon.Windows.Controls.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"D:\\Projects\\Roger\\Windows Utilities\\JuisCheck\\libraries\\Muon.Windows.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.5\\PresentationCore.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.5\\PresentationFramework.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.5\\System.Core.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.5\\System.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.5\\System.Drawing.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.5\\System.Net.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.5\\System.Runtime.Serialization.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.5\\System.ServiceModel.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.5\\System.Windows.Forms.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.5\\System.Xaml.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.5\\System.Xml.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.5\\UIAutomationProvider.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.5\\UIAutomationTypes.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.5\\WindowsBase.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.5\\WindowsFormsIntegration.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""}],"Analyzers":[],"Outputs":[{"OutputItemFullPath":"D:\\Projects\\Roger\\Windows Utilities\\JuisCheck\\JuisCheck\\bin\\Debug\\JuisCheck.exe","OutputItemRelativePath":"JuisCheck.exe"},{"OutputItemFullPath":"D:\\Projects\\Roger\\Windows Utilities\\JuisCheck\\JuisCheck\\bin\\Debug\\JuisCheck.pdb","OutputItemRelativePath":"JuisCheck.pdb"}],"CopyToOutputEntries":[]}
--------------------------------------------------------------------------------
/JuisCheck/App.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/JuisCheck/App.xaml.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Program : JuisCheck for Windows
3 | * Copyright : Copyright (C) Roger Hünen
4 | * License : GNU General Public License version 3 (see LICENSE)
5 | */
6 |
7 | using Muon.Dotnet.Extensions;
8 | using System;
9 | using System.Collections.Generic;
10 | using System.Diagnostics;
11 | using System.Globalization;
12 | using System.IO;
13 | using System.Linq;
14 | using System.Net;
15 | using System.Net.Security;
16 | using System.Reflection;
17 | using System.Runtime.InteropServices;
18 | using System.Security.Cryptography.X509Certificates;
19 | using System.Threading;
20 | using System.Windows;
21 | using System.Windows.Markup;
22 | using System.Windows.Threading;
23 | using WinForms = System.Windows.Forms;
24 |
25 | using JuisCheck.Lang;
26 | using JuisCheck.Properties;
27 |
28 | namespace JuisCheck
29 | {
30 | ///
31 | /// Interaction logic for App.xaml
32 | ///
33 | public partial class App : Application
34 | {
35 | public const string defaultDataFileName = "default.xml";
36 | public const string portableProgramFileName = "JuisCheckPortable.exe";
37 | public const string programName = "JuisCheck";
38 | public const string programVersionSuffix = ""; // BETA, RC1, etc.
39 |
40 | public const StringComparison defaultDisplayStringComparison = StringComparison.CurrentCultureIgnoreCase;
41 | public const StringComparison defaultFileNameComparison = StringComparison.OrdinalIgnoreCase;
42 |
43 | private static readonly Settings programSettings = Settings.Default;
44 |
45 | public static bool IsLanguageSelectionEnabled { get; private set; }
46 | public static bool IsPortableMode { get; private set; }
47 | public static bool RestartPending { get; private set; }
48 |
49 | public static List AdditionalLanguages { get; } = new List() { "de", "es", "fr", "it", "nl", "pl" };
50 |
51 | /*****************/
52 | /* Other methods */
53 | /*****************/
54 |
55 | public static void CancelRestart()
56 | {
57 | RestartPending = false;
58 | }
59 |
60 | public static string GetAssemblyName() { return Assembly.GetExecutingAssembly().GetName().Name; }
61 | public static string GetCopyright() { return Assembly.GetExecutingAssembly().GetCopyright(); }
62 | public static string GetDefaultDirectory() { return Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); }
63 | public static string GetLocation() { return Assembly.GetExecutingAssembly().Location; }
64 | public static string GetProgramDirectory() { return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); }
65 | public static string GetProgramFileName() { return Path.GetFileName(Assembly.GetExecutingAssembly().Location); }
66 | public static string GetProgramInfo() { return $"{programName} {GetVersion()}{programVersionSuffix}"; }
67 | public static MainWindow GetMainWindow() { return (MainWindow)Current.MainWindow; }
68 | public static string GetVersion() { return Assembly.GetExecutingAssembly().GetName().Version.ToString(3); }
69 |
70 | public static void Restart()
71 | {
72 | RestartPending = true;
73 | GetMainWindow().Close();
74 | }
75 |
76 | public static bool SafeClipboardSetText( string text )
77 | {
78 | try {
79 | // Does retries internally if needed (System.Windows.Clipboard does not do this)
80 | WinForms.Clipboard.SetDataObject(text, true);
81 | return true;
82 | }
83 | catch (ExternalException) {
84 | return false;
85 | }
86 | }
87 |
88 | private static bool ServiceCertificateValidationCallback(object obt, X509Certificate cert, X509Chain chain, SslPolicyErrors sslPolicyErrors)
89 | {
90 | if (sslPolicyErrors == SslPolicyErrors.None) {
91 | return true;
92 | }
93 |
94 | var cert2 = new X509Certificate2(cert);
95 | var commonName = cert2.GetNameInfo(X509NameType.SimpleName, false);
96 |
97 | if (commonName == JUIS.GetServerName()) {
98 | return true;
99 | }
100 |
101 | return false;
102 | }
103 |
104 | // Event handler: Exit
105 |
106 | private void Exit_Handler( object sender, ExitEventArgs evt )
107 | {
108 | if (!IsPortableMode) {
109 | programSettings.Save();
110 | }
111 |
112 | if (RestartPending) {
113 | Process.Start(App.GetLocation());
114 | }
115 | }
116 |
117 | // Event handler: Startup
118 |
119 | private void Startup_Handler( object sender, StartupEventArgs evt )
120 | {
121 | string assemblyName = GetAssemblyName();
122 | string programDirectory = GetProgramDirectory();
123 | string programName = GetProgramFileName();
124 |
125 | // Portable mode
126 |
127 | IsPortableMode = string.Compare(programName, portableProgramFileName, defaultFileNameComparison) == 0;
128 |
129 | // Initialize settings
130 |
131 | if (IsPortableMode) {
132 | programSettings.Reset();
133 | programSettings.AutoLoadFile = Path.Combine(programDirectory, defaultDataFileName);
134 | programSettings.LastDocumentDirectory = programDirectory;
135 | programSettings.LastDownloadDirectory = programDirectory;
136 | } else
137 | if (programSettings.SettingsUpgradeRequired) {
138 | programSettings.Upgrade();
139 | programSettings.SettingsUpgradeRequired = false;
140 | }
141 |
142 | // Additional languages (using resource dictionaries)
143 |
144 | if (IsPortableMode) {
145 | IsLanguageSelectionEnabled = false;
146 | } else {
147 | foreach (string language in AdditionalLanguages.ToList()) {
148 | if (!File.Exists(Path.Combine(programDirectory, language, $"{assemblyName}.resources.dll"))) {
149 | AdditionalLanguages.Remove(language);
150 | }
151 | }
152 |
153 | if (AdditionalLanguages.Count == 0) {
154 | programSettings.UserInterfaceLanguage = "auto";
155 | }
156 |
157 | IsLanguageSelectionEnabled = AdditionalLanguages.Count != 0;
158 | }
159 |
160 | // Set user interface language
161 |
162 | CultureInfo cultureInfo;
163 | try {
164 | cultureInfo = new CultureInfo(programSettings.UserInterfaceLanguage);
165 | }
166 | catch (CultureNotFoundException) {
167 | cultureInfo = CultureInfo.InstalledUICulture;
168 | }
169 | Thread.CurrentThread.CurrentUICulture = cultureInfo;
170 |
171 | // SSL/TLS
172 |
173 | ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3; // Deprecated
174 | ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Tls; // Deprecated
175 | ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Tls11; // Deprecated
176 | ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
177 |
178 | // Ignore certificate errors for JUIS queries (AVM uses a private root CA that is not globally trused)
179 |
180 | ServicePointManager.ServerCertificateValidationCallback += ServiceCertificateValidationCallback;
181 | }
182 |
183 | // Event handler: DispatcherUnhandledException
184 |
185 | private void DispatcherUnhandledException_Handler( object sender, DispatcherUnhandledExceptionEventArgs evt )
186 | {
187 | string exceptionText = string.Empty;
188 |
189 | for (Exception exception = evt.Exception; exception != null; exception = exception.InnerException) {
190 | exceptionText += $"Type = {exception.GetType().Name}\r\n";
191 | exceptionText += $"Message = {exception.Message}\r\n";
192 |
193 | if (exception is ExternalException externalException) {
194 | exceptionText += $"HResult = 0x{externalException.ErrorCode:X8}";
195 | }
196 |
197 | if (exception is XamlParseException xamlParseException) {
198 | exceptionText += $"XAML URI = {xamlParseException.BaseUri}\r\n";
199 | exceptionText += $"XAML line = {xamlParseException.LineNumber}\r\n";
200 | exceptionText += $"XAML pos = {xamlParseException.LinePosition}\r\n";
201 | exceptionText += $"XAML key = {xamlParseException.KeyContext}\r\n";
202 | exceptionText += $"XAML name = {xamlParseException.NameContext}\r\n";
203 | }
204 |
205 | exceptionText += $"HasInner = {exception.InnerException != null}\r\n";
206 | exceptionText += $"{exception.StackTrace}\r\n\r\n";
207 | }
208 |
209 | string message;
210 | if (SafeClipboardSetText(exceptionText)) {
211 | message = JCstring.MessageTextUnhandledExceptionCopySuccess.Unescape();
212 | } else {
213 | message = JCstring.MessageTextUnhandledExceptionCopyFailure.Unescape();
214 | }
215 |
216 | _ = MessageBoxEx.Show(new MessageBoxExParams {
217 | CaptionText = JCstring.MessageCaptionFatalError,
218 | MessageText = string.Format(CultureInfo.CurrentCulture, message, evt.Exception.GetType().Name),
219 | Image = MessageBoxExImage.Error,
220 | ButtonText = new string[] { JCstring.DialogButtonTextOk }
221 | });
222 |
223 | Environment.Exit(1);
224 | }
225 | }
226 | }
227 |
--------------------------------------------------------------------------------
/JuisCheck/CollectionSettings.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Program : JuisCheck for Windows
3 | * Copyright : Copyright (C) Roger Hünen
4 | * License : GNU General Public License version 3 (see LICENSE)
5 | */
6 |
7 | using System;
8 | using System.Collections.Generic;
9 | using System.ComponentModel;
10 | using System.Globalization;
11 | using System.Runtime.CompilerServices;
12 |
13 | using JuisCheck.Properties;
14 |
15 | namespace JuisCheck
16 | {
17 | public sealed class CollectionSettings : INotifyPropertyChanged
18 | {
19 | private static readonly Settings programSettings = Settings.Default;
20 | private readonly Dictionary settings = new Dictionary();
21 |
22 | public const string keyDataGridColumnVisibleCountry = "DataGridColumnVisibleCountry";
23 | public bool DataGridColumnVisibleCountry
24 | {
25 | get => GetBoolValue(keyDataGridColumnVisibleCountry);
26 | set {
27 | settings[keyDataGridColumnVisibleCountry] = value.ToString(CultureInfo.InvariantCulture);
28 | NotifyPropertyChanged();
29 | }
30 | }
31 |
32 | public const string keyDataGridColumnVisibleDeviceAddress = "DataGridColumnVisibleDeviceAddress";
33 | public bool DataGridColumnVisibleDeviceAddress
34 | {
35 | get => GetBoolValue(keyDataGridColumnVisibleDeviceAddress);
36 | set {
37 | settings[keyDataGridColumnVisibleDeviceAddress] = value.ToString(CultureInfo.InvariantCulture);
38 | NotifyPropertyChanged();
39 | }
40 | }
41 |
42 | public const string keyDataGridColumnVisibleFirmware = "DataGridColumnVisibleFirmware";
43 | public bool DataGridColumnVisibleFirmware
44 | {
45 | get => GetBoolValue(keyDataGridColumnVisibleFirmware);
46 | set {
47 | settings[keyDataGridColumnVisibleFirmware] = value.ToString(CultureInfo.InvariantCulture);
48 | NotifyPropertyChanged();
49 | }
50 | }
51 |
52 | public const string keyDataGridColumnVisibleFirmwareBuildType = "DataGridColumnVisibleFirmwareBuildType";
53 | public bool DataGridColumnVisibleFirmwareBuildType
54 | {
55 | get => GetBoolValue(keyDataGridColumnVisibleFirmwareBuildType);
56 | set {
57 | settings[keyDataGridColumnVisibleFirmwareBuildType] = value.ToString(CultureInfo.InvariantCulture);
58 | NotifyPropertyChanged();
59 | }
60 | }
61 |
62 | public const string keyDataGridColumnVisibleHardware = "DataGridColumnVisibleHardware";
63 | public bool DataGridColumnVisibleHardware
64 | {
65 | get => GetBoolValue(keyDataGridColumnVisibleHardware);
66 | set {
67 | settings[keyDataGridColumnVisibleHardware] = value.ToString(CultureInfo.InvariantCulture);
68 | NotifyPropertyChanged();
69 | }
70 | }
71 |
72 | public const string keyDataGridColumnVisibleLanguage = "DataGridColumnVisibleLanguage";
73 | public bool DataGridColumnVisibleLanguage
74 | {
75 | get => GetBoolValue(keyDataGridColumnVisibleLanguage);
76 | set {
77 | settings[keyDataGridColumnVisibleLanguage] = value.ToString(CultureInfo.InvariantCulture);
78 | NotifyPropertyChanged();
79 | }
80 | }
81 |
82 | public const string keyDataGridColumnVisibleMasterBase = "DataGridColumnVisibleMasterBase";
83 | public bool DataGridColumnVisibleMasterBase
84 | {
85 | get => GetBoolValue(keyDataGridColumnVisibleMasterBase);
86 | set {
87 | settings[keyDataGridColumnVisibleMasterBase] = value.ToString(CultureInfo.InvariantCulture);
88 | NotifyPropertyChanged();
89 | }
90 | }
91 |
92 | public const string keyDataGridColumnVisibleOEM = "DataGridColumnVisibleOEM";
93 | public bool DataGridColumnVisibleOEM
94 | {
95 | get => GetBoolValue(keyDataGridColumnVisibleOEM);
96 | set {
97 | settings[keyDataGridColumnVisibleOEM] = value.ToString(CultureInfo.InvariantCulture);
98 | NotifyPropertyChanged();
99 | }
100 | }
101 |
102 | public const string keyDataGridColumnVisibleProductName = "DataGridColumnVisibleProductName";
103 | public bool DataGridColumnVisibleProductName
104 | {
105 | get => GetBoolValue(keyDataGridColumnVisibleProductName);
106 | set {
107 | settings[keyDataGridColumnVisibleProductName] = value.ToString(CultureInfo.InvariantCulture);
108 | NotifyPropertyChanged();
109 | }
110 | }
111 |
112 | public const string keyDataGridColumnVisibleUpdateFileName = "DataGridColumnVisibleUpdateFileName";
113 | public bool DataGridColumnVisibleUpdateFileName
114 | {
115 | get => GetBoolValue(keyDataGridColumnVisibleUpdateFileName);
116 | set {
117 | settings[keyDataGridColumnVisibleUpdateFileName] = value.ToString(CultureInfo.InvariantCulture);
118 | NotifyPropertyChanged();
119 | }
120 | }
121 |
122 | public const string keyDataGridColumnVisibleUpdateInfo = "DataGridColumnVisibleUpdateInfo";
123 | public bool DataGridColumnVisibleUpdateInfo
124 | {
125 | get => GetBoolValue(keyDataGridColumnVisibleUpdateInfo);
126 | set {
127 | settings[keyDataGridColumnVisibleUpdateInfo] = value.ToString(CultureInfo.InvariantCulture);
128 | NotifyPropertyChanged();
129 | }
130 | }
131 |
132 | public const string keyDataGridColumnVisibleUpdateLastChecked = "DataGridColumnVisibleUpdateLastChecked";
133 | public bool DataGridColumnVisibleUpdateLastChecked
134 | {
135 | get => GetBoolValue(keyDataGridColumnVisibleUpdateLastChecked);
136 | set {
137 | settings[keyDataGridColumnVisibleUpdateLastChecked] = value.ToString(CultureInfo.InvariantCulture);
138 | NotifyPropertyChanged();
139 | }
140 | }
141 |
142 | /****************/
143 | /* Constructors */
144 | /****************/
145 |
146 | public CollectionSettings()
147 | {
148 | Reset();
149 | }
150 |
151 | /******************/
152 | /* Other medthods */
153 | /******************/
154 |
155 | public void Add( string settingName, string settingValue )
156 | {
157 | if (settingName == null) { throw new ArgumentNullException(nameof(settingName)); }
158 | if (settingValue == null) { throw new ArgumentNullException(nameof(settingValue)); }
159 |
160 | settings[settingName] = settingValue;
161 | }
162 |
163 | private bool GetBoolValue( string settingName, bool defaultValue = false ) {
164 | if (settingName == null) { throw new ArgumentNullException(nameof(settingName)); }
165 |
166 | if (settings.TryGetValue(settingName, out string stringValue)) {
167 | if (bool.TryParse(stringValue, out bool value)) {
168 | return value;
169 | }
170 | }
171 |
172 | return defaultValue;
173 | }
174 |
175 | public Dictionary GetDictionary()
176 | {
177 | return settings;
178 | }
179 |
180 | public void Reset()
181 | {
182 | SetDefaultsValues();
183 | }
184 |
185 | public void NotifySettingsProperties()
186 | {
187 | NotifyPropertyChanged(nameof(DataGridColumnVisibleCountry));
188 | NotifyPropertyChanged(nameof(DataGridColumnVisibleDeviceAddress));
189 | NotifyPropertyChanged(nameof(DataGridColumnVisibleFirmware));
190 | NotifyPropertyChanged(nameof(DataGridColumnVisibleFirmwareBuildType));
191 | NotifyPropertyChanged(nameof(DataGridColumnVisibleHardware));
192 | NotifyPropertyChanged(nameof(DataGridColumnVisibleLanguage));
193 | NotifyPropertyChanged(nameof(DataGridColumnVisibleMasterBase));
194 | NotifyPropertyChanged(nameof(DataGridColumnVisibleOEM));
195 | NotifyPropertyChanged(nameof(DataGridColumnVisibleProductName));
196 | NotifyPropertyChanged(nameof(DataGridColumnVisibleUpdateFileName));
197 | NotifyPropertyChanged(nameof(DataGridColumnVisibleUpdateInfo));
198 | NotifyPropertyChanged(nameof(DataGridColumnVisibleUpdateLastChecked));
199 | }
200 |
201 | private void SetDefaultsValues()
202 | {
203 | DataGridColumnVisibleCountry = programSettings.DefaultDataGridColumnVisibleCountry;
204 | DataGridColumnVisibleDeviceAddress = programSettings.DefaultDataGridColumnVisibleDeviceAddress;
205 | DataGridColumnVisibleFirmware = programSettings.DefaultDataGridColumnVisibleFirmware;
206 | DataGridColumnVisibleFirmwareBuildType = programSettings.DefaultDataGridColumnVisibleFirmwareBuildType;
207 | DataGridColumnVisibleHardware = programSettings.DefaultDataGridColumnVisibleHardware;
208 | DataGridColumnVisibleLanguage = programSettings.DefaultDataGridColumnVisibleLanguage;
209 | DataGridColumnVisibleMasterBase = programSettings.DefaultDataGridColumnVisibleMasterBase;
210 | DataGridColumnVisibleOEM = programSettings.DefaultDataGridColumnVisibleOEM;
211 | DataGridColumnVisibleProductName = programSettings.DefaultDataGridColumnVisibleProductName;
212 | DataGridColumnVisibleUpdateFileName = programSettings.DefaultDataGridColumnVisibleUpdateFileName;
213 | DataGridColumnVisibleUpdateInfo = programSettings.DefaultDataGridColumnVisibleUpdateInfo;
214 | DataGridColumnVisibleUpdateLastChecked = programSettings.DefaultDataGridColumnVisibleUpdateLastChecked;
215 | }
216 |
217 | // Interface: INotifyPropertyChanged
218 |
219 | public event PropertyChangedEventHandler PropertyChanged;
220 |
221 | private void NotifyPropertyChanged( [CallerMemberName] string propertyName = null )
222 | {
223 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
224 | }
225 | }
226 | }
227 |
--------------------------------------------------------------------------------
/JuisCheck/ComboBoxEx.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Program : JuisCheck for Windows
3 | * Copyright : Copyright (C) Roger Hünen
4 | * License : GNU General Public License version 3 (see LICENSE)
5 | */
6 |
7 | using System;
8 | using System.Windows;
9 | using System.Windows.Controls;
10 | using System.Windows.Threading;
11 |
12 | namespace JuisCheck
13 | {
14 | public class ComboBoxEx : ComboBox
15 | {
16 | // DependencyProperty: MaxDropDownItems
17 |
18 | public static readonly DependencyProperty MaxDropDownItemsProperty = DependencyProperty.Register("MaxDropDownItems", typeof(int), typeof(ComboBoxEx), new FrameworkPropertyMetadata(0));
19 |
20 | public int MaxDropDownItems
21 | {
22 | get => (int)GetValue(MaxDropDownItemsProperty);
23 | set => SetValue(MaxDropDownItemsProperty, value);
24 | }
25 |
26 | // Event: DropDownOpened
27 |
28 | protected override void OnDropDownOpened( EventArgs evt )
29 | {
30 | base.OnDropDownOpened(evt);
31 |
32 | if (MaxDropDownItems > 0) {
33 | Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => {
34 | if (ItemContainerGenerator.ContainerFromIndex(0) is UIElement container) {
35 | if (container.RenderSize.Height > 0) {
36 | MaxDropDownHeight = container.RenderSize.Height * MaxDropDownItems + 2;
37 | }
38 | }
39 | }));
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/JuisCheck/ComboBoxValue.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Program : JuisCheck for Windows
3 | * Copyright : Copyright (C) Roger Hünen
4 | * License : GNU General Public License version 3 (see LICENSE)
5 | */
6 |
7 | using System;
8 | using System.Collections.Generic;
9 | using System.Globalization;
10 | using System.Linq;
11 |
12 | using JuisCheck.Lang;
13 |
14 | namespace JuisCheck
15 | {
16 | public class ComboBoxValue
17 | {
18 | public string Value { get; private set; }
19 | public string DisplayString { get; private set; }
20 |
21 | public ComboBoxValue( string value, string displayString )
22 | {
23 | Value = value;
24 | DisplayString = displayString;
25 | }
26 | }
27 |
28 | public static class ComboBoxValueExt
29 | {
30 | public static List AppendMissingAsUnknown( this List values, int currentValue )
31 | {
32 | if (values == null) {
33 | throw new ArgumentNullException(nameof(values));
34 | }
35 |
36 | if (currentValue >= 0) {
37 | string currentValueStr = currentValue.ToString(CultureInfo.InvariantCulture);
38 | if (!values.Any( v => currentValueStr == v.Value )) {
39 | values.Add(new ComboBoxValue(currentValueStr, string.Format(CultureInfo.CurrentCulture, JCstring.ComboBoxValueUnknown, currentValueStr)));
40 | }
41 | }
42 |
43 | return values;
44 | }
45 |
46 | public static List AppendMissingAsUnknown( this List values, string currentValue )
47 | {
48 | if (values == null) {
49 | throw new ArgumentNullException(nameof(values));
50 | }
51 |
52 | if (!string.IsNullOrWhiteSpace(currentValue)) {
53 | if (!values.Any( v => currentValue == v.Value )) {
54 | values.Add(new ComboBoxValue(currentValue, string.Format(CultureInfo.CurrentCulture, JCstring.ComboBoxValueUnknown, currentValue)));
55 | }
56 | }
57 |
58 | return values;
59 | }
60 |
61 | public static List Prepend( this List values, string value, string displayString )
62 | {
63 | values.Insert(0, new ComboBoxValue(value ?? throw new ArgumentNullException(nameof(value)), displayString ?? throw new ArgumentNullException(nameof(displayString))));
64 |
65 | return values;
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/JuisCheck/ComboBoxValueComparer.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Program : JuisCheck for Windows
3 | * Copyright : Copyright (C) Roger Hünen
4 | * License : GNU General Public License version 3 (see LICENSE)
5 | */
6 |
7 | using System;
8 | using System.Collections.Generic;
9 |
10 | namespace JuisCheck
11 | {
12 | public sealed class ComboBoxValueComparer : Comparer
13 | {
14 | private readonly IComparer comparer;
15 |
16 | public ComboBoxValueComparer( StringComparison stringComparison )
17 | {
18 | switch (stringComparison) {
19 | case StringComparison.CurrentCulture: comparer = StringComparer.CurrentCulture; break;
20 | case StringComparison.CurrentCultureIgnoreCase: comparer = StringComparer.CurrentCultureIgnoreCase; break;
21 | case StringComparison.InvariantCulture: comparer = StringComparer.InvariantCulture; break;
22 | case StringComparison.InvariantCultureIgnoreCase: comparer = StringComparer.InvariantCultureIgnoreCase; break;
23 | case StringComparison.Ordinal: comparer = StringComparer.Ordinal; break;
24 | case StringComparison.OrdinalIgnoreCase: comparer = StringComparer.OrdinalIgnoreCase; break;
25 | default: throw new ArgumentOutOfRangeException(nameof(stringComparison));
26 | }
27 | }
28 |
29 | public ComboBoxValueComparer( IComparer stringComparer )
30 | {
31 | comparer = stringComparer ?? throw new ArgumentNullException(nameof(stringComparer));
32 | }
33 |
34 | public override int Compare( ComboBoxValue value1, ComboBoxValue value2 )
35 | {
36 | if (value1 == null) {
37 | throw new ArgumentNullException(nameof(value1));
38 | }
39 | if (value2 == null) {
40 | throw new ArgumentNullException(nameof(value2));
41 | }
42 |
43 | return comparer.Compare(value1.DisplayString, value2.DisplayString);
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/JuisCheck/ContextMenuHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows;
3 | using System.Windows.Controls;
4 |
5 | namespace JuisCheck
6 | {
7 | public static class ContextMenuHelper
8 | {
9 | public static UIElement GetPlacementTarget(object o)
10 | {
11 | if (o == null) {
12 | throw new ArgumentNullException(nameof(o));
13 | }
14 |
15 | if (o is DependencyObject element) {
16 | while (element != null) {
17 | if (element is ContextMenu contextMenu) {
18 | return contextMenu.PlacementTarget;
19 | }
20 | element = LogicalTreeHelper.GetParent(element);
21 | }
22 | }
23 |
24 | return null;
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/JuisCheck/DectDeviceDialog.xaml.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Program : JuisCheck for Windows
3 | * Copyright : Copyright (C) Roger Hünen
4 | * License : GNU General Public License version 3 (see LICENSE)
5 | */
6 |
7 | using Muon.Dotnet.Extensions;
8 | using System;
9 | using System.Collections.Generic;
10 | using System.Linq;
11 | using System.Windows;
12 | using System.Windows.Controls;
13 | using System.Windows.Input;
14 |
15 | namespace JuisCheck
16 | {
17 | ///
18 | /// Interaction logic for DectDeviceDialog.xaml
19 | ///
20 | public sealed partial class DectDeviceDialog : Window
21 | {
22 | private readonly DectDevice origDevice;
23 |
24 | public DectDevice DeviceData { get; private set; }
25 | public int SelectedIndex { get; set; } // Dummy for ComboBox SelectedIndex validation
26 |
27 | public List CountryValues { get; private set; }
28 | public List DectBaseValues { get; private set; }
29 | public List LanguageValues { get; private set; }
30 | public List OEMValues { get; private set; }
31 |
32 | public DectDeviceDialog( DectDevice device )
33 | {
34 | origDevice = device ?? throw new ArgumentNullException(nameof(device));
35 | DeviceData = new DectDevice(device);
36 |
37 | InitComboBoxValues(device);
38 | InitializeComponent();
39 | DataContext = this;
40 | }
41 |
42 | private void InitComboBoxValues(DectDevice device)
43 | {
44 | CountryValues = Device.GetCountryValues().AppendMissingAsUnknown(device.Country);
45 | LanguageValues = Device.GetLanguageValues().AppendMissingAsUnknown(device.Language);
46 | OEMValues = Device.GetOemValues().AppendMissingAsUnknown(device.OEM);
47 |
48 | DectBaseValues = new List();
49 | foreach (JuisDevice baseDevice in App.GetMainWindow().Devices.Where(d => d is JuisDevice)) {
50 | DectBaseValues.Add(new ComboBoxValue(baseDevice.ID, baseDevice.DeviceName));
51 | }
52 | DectBaseValues.Add(new ComboBoxValue(DectDevice.predefinedDectBaseID, DectDevice.GetPredefinedDectBaseText()));
53 | DectBaseValues.Sort(new ComboBoxValueComparer(new NaturalStringComparer(App.defaultDisplayStringComparison)));
54 | DectBaseValues.AppendMissingAsUnknown(device.DectBase);
55 | }
56 |
57 | // Routed command: CmdOk
58 |
59 | public static readonly RoutedCommand CmdOK = new RoutedCommand();
60 |
61 | private void CmdOK_CanExecute( object sender, CanExecuteRoutedEventArgs evt )
62 | {
63 | evt.CanExecute = !this.GetTreeHasError(true, true);
64 | }
65 |
66 | private void CmdOK_Executed( object sender, ExecutedRoutedEventArgs evt )
67 | {
68 | DeviceData.TrimStrings();
69 | origDevice.CopyFrom(DeviceData);
70 |
71 | DialogResult = true;
72 | }
73 |
74 | // Event: TextBox_GotFocus
75 |
76 | private void TextBox_GotFocus_Handler( object sender, RoutedEventArgs evt )
77 | {
78 | if (sender is TextBox textBox) {
79 | textBox.SelectAll();
80 | }
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/JuisCheck/DeviceCollection.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Program : JuisCheck for Windows
3 | * Copyright : Copyright (C) Roger Hünen
4 | * License : GNU General Public License version 3 (see LICENSE)
5 | */
6 |
7 | using System;
8 | using System.Collections;
9 | using System.Collections.ObjectModel;
10 | using System.Collections.Specialized;
11 | using System.ComponentModel;
12 | using System.Linq;
13 | using System.Runtime.CompilerServices;
14 | using System.Windows.Threading;
15 |
16 | namespace JuisCheck
17 | {
18 | public class DeviceCollection : ObservableCollection
19 | {
20 | public CollectionSettings Settings { get; protected set; } = new CollectionSettings();
21 |
22 | private string _FileName = null;
23 | public string FileName
24 | {
25 | get => _FileName;
26 | protected set {
27 | if (_FileName != value) {
28 | _FileName = value;
29 | NotifyPropertyChanged();
30 | }
31 |
32 | }
33 | }
34 |
35 | private bool _IsModified = false;
36 | public bool IsModified
37 | {
38 | get => _IsModified;
39 | protected set {
40 | if (_IsModified != value) {
41 | _IsModified = value;
42 | NotifyPropertyChanged();
43 | }
44 | }
45 | }
46 |
47 | /****************/
48 | /* Constructors */
49 | /****************/
50 |
51 | public DeviceCollection () : base()
52 | {
53 | CollectionChanged += CollectionChanged_Handler;
54 | Settings.PropertyChanged += Settings_PropertyChanged_Handler;
55 | }
56 |
57 | /*****************/
58 | /* Other methods */
59 | /*****************/
60 |
61 | protected void AddItemPropertyChangedHandlers()
62 | {
63 | AddItemPropertyChangedHandlers((IList)Items);
64 | }
65 |
66 | protected void AddItemPropertyChangedHandlers( IList devices )
67 | {
68 | if (devices == null) {
69 | throw new ArgumentNullException(nameof(devices));
70 | }
71 |
72 | foreach (Device device in devices) {
73 | device.PropertyChanged += Item_PropertyChanged_Handler;
74 | }
75 | }
76 |
77 | public void Empty()
78 | {
79 | Clear();
80 |
81 | FileName = null;
82 | IsModified = false;
83 | }
84 |
85 | public Device FindByID( string id )
86 | {
87 | return this.FirstOrDefault( d => d.ID == id );
88 | }
89 |
90 | public void Load( string fileName )
91 | {
92 | FileName = fileName;
93 |
94 | bool isModified = XML.JCData.LoadFromFile(fileName, this);
95 | foreach (Device device in this) {
96 | if (string.IsNullOrWhiteSpace(device.ID)) {
97 | device.ID = Guid.NewGuid().ToString();
98 | isModified = true;
99 | }
100 | }
101 | Settings.NotifySettingsProperties();
102 |
103 | IsModified = isModified;
104 | }
105 |
106 | protected void RemoveItemPropertyChangedHandlers( IList devices )
107 | {
108 | if (devices == null) {
109 | throw new ArgumentNullException(nameof(devices));
110 | }
111 |
112 | foreach (Device device in devices) {
113 | device.PropertyChanged -= Item_PropertyChanged_Handler;
114 | }
115 | }
116 |
117 | public void Save( string fileName = null )
118 | {
119 | FileName = fileName ?? FileName;
120 | XML.JCData.SaveToFile(FileName, this);
121 |
122 | IsModified = false;
123 | }
124 |
125 | // Event handler: CollectionChanged
126 |
127 | private void CollectionChanged_Handler( object sender, NotifyCollectionChangedEventArgs evt )
128 | {
129 | switch (evt.Action) {
130 | case NotifyCollectionChangedAction.Add:
131 | AddItemPropertyChangedHandlers(evt.NewItems);
132 | IsModified = true;
133 | break;
134 |
135 | case NotifyCollectionChangedAction.Move:
136 | IsModified = true;
137 | break;
138 |
139 | case NotifyCollectionChangedAction.Remove:
140 | RemoveItemPropertyChangedHandlers(evt.OldItems);
141 | IsModified = true;
142 | break;
143 |
144 | case NotifyCollectionChangedAction.Replace:
145 | RemoveItemPropertyChangedHandlers(evt.OldItems);
146 | AddItemPropertyChangedHandlers(evt.NewItems);
147 | IsModified = true;
148 | break;
149 |
150 | case NotifyCollectionChangedAction.Reset:
151 | IsModified = true;
152 | break;
153 | }
154 | }
155 |
156 | // Event handler: Item_PropertyChanged
157 |
158 | private void Item_PropertyChanged_Handler( object sender, PropertyChangedEventArgs evt )
159 | {
160 | if (evt.PropertyName == nameof(Device.DeviceName)) {
161 | foreach (Device device in this) {
162 | device.NotifyDeviceNameChanged(((Device)sender).ID);
163 | }
164 | }
165 |
166 | if (evt.PropertyName != nameof(Device.IsSelected)) {
167 | IsModified = true;
168 | }
169 | }
170 |
171 | // Event handler: Settings_PropertyChanged
172 |
173 | private void Settings_PropertyChanged_Handler( object sender, PropertyChangedEventArgs evt )
174 | {
175 | IsModified = true;
176 | }
177 |
178 | // Event source: CollectionPropertyChanged
179 | //
180 | // Note: we cannot use the INotifyPropertyChanged implementation from the
181 | // ObservableCollection class because PropertyChanged is protected.
182 |
183 | public event PropertyChangedEventHandler CollectionPropertyChanged;
184 |
185 | protected void NotifyPropertyChanged( [CallerMemberName] string propertyName = null )
186 | {
187 | CollectionPropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
188 | }
189 | }
190 | }
191 |
--------------------------------------------------------------------------------
/JuisCheck/DeviceComparer.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Program : JuisCheck for Windows
3 | * Copyright : Copyright (C) Roger Hünen
4 | * License : GNU General Public License version 3 (see LICENSE)
5 | */
6 |
7 | using System;
8 | using System.Collections.Generic;
9 | using System.ComponentModel;
10 |
11 | using JuisCheck.Lang;
12 |
13 | namespace JuisCheck
14 | {
15 | public sealed class DeviceComparer : Comparer
16 | {
17 | private readonly DeviceProperty sortProperty;
18 | private readonly ListSortDirection sortDirection;
19 | private readonly NaturalStringComparer stringComparer;
20 |
21 | public DeviceComparer( DeviceProperty property, ListSortDirection direction )
22 | {
23 | if (!Enum.IsDefined(typeof(DeviceProperty), property)) {
24 | throw new ArgumentOutOfRangeException(nameof(property));
25 | }
26 | if (!Enum.IsDefined(typeof(ListSortDirection), direction)) {
27 | throw new ArgumentOutOfRangeException(nameof(direction));
28 | }
29 |
30 | sortProperty = property;
31 | sortDirection = direction;
32 | stringComparer = new NaturalStringComparer(App.defaultDisplayStringComparison);
33 | }
34 |
35 | public override int Compare( Device device1, Device device2 )
36 | {
37 | if (device1 == null) {
38 | throw new ArgumentNullException(nameof(device1));
39 | }
40 | if (device2 == null) {
41 | throw new ArgumentNullException(nameof(device2));
42 | }
43 |
44 | int result;
45 |
46 | switch (sortProperty) {
47 | case DeviceProperty.DeviceAddressStr: result = stringComparer.Compare(device1.DeviceAddressStr, device2.DeviceAddressStr); break;
48 | case DeviceProperty.DeviceName: result = stringComparer.Compare(device1.DeviceName, device2.DeviceName); break;
49 | case DeviceProperty.FirmwareStr: result = stringComparer.Compare(device1.FirmwareStr, device2.FirmwareStr); break;
50 | case DeviceProperty.ProductName: result = stringComparer.Compare(device1.ProductName, device2.ProductName); break;
51 | default: throw new ApplicationException("Unsupported comparison");
52 | }
53 |
54 | return sortDirection == ListSortDirection.Ascending ? result : -result;
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/JuisCheck/DeviceProperty.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Program : JuisCheck for Windows
3 | * Copyright : Copyright (C) Roger Hünen
4 | * License : GNU General Public License version 3 (see LICENSE)
5 | */
6 |
7 | namespace JuisCheck
8 | {
9 | public enum DeviceProperty
10 | {
11 | DeviceAddressStr,
12 | DeviceName,
13 | FirmwareStr,
14 | ProductName
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/JuisCheck/DownloadDialog.xaml:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/JuisCheck/DownloadDialog.xaml.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Program : JuisCheck for Windows
3 | * Copyright : Copyright (C) Roger Hünen
4 | * License : GNU General Public License version 3 (see LICENSE)
5 | */
6 |
7 | using System;
8 | using System.ComponentModel;
9 | using System.IO;
10 | using System.Net;
11 | using System.Windows;
12 | using System.Windows.Threading;
13 |
14 | using JuisCheck.Lang;
15 |
16 | namespace JuisCheck
17 | {
18 | ///
19 | /// Interaction logic for DownloadDialog.xaml
20 | ///
21 | public sealed partial class DownloadDialog : Window, IDisposable
22 | {
23 | private readonly WebClient webClient;
24 | private readonly Uri downloadUri;
25 | private readonly string downloadFilePath;
26 |
27 | private bool completed = false;
28 | private bool disposed = false;
29 |
30 | public DownloadDialog( Uri uri, string filePath, string windowTitle )
31 | {
32 | downloadUri = uri;
33 | downloadFilePath = filePath;
34 |
35 | InitializeComponent();
36 | DataContext = this;
37 | Title = windowTitle;
38 |
39 | webClient = new WebClient();
40 | webClient.DownloadFileCompleted += WebClient_DownloadFileCompleted_Handler;
41 | webClient.DownloadProgressChanged += WebClient_DownloadProgressChanged_Handler;
42 | }
43 |
44 | // Event handler: Closing
45 |
46 | private void Closing_Handler( object sender, CancelEventArgs evt )
47 | {
48 | if (!completed) {
49 | webClient.CancelAsync();
50 | IsEnabled = false;
51 | evt.Cancel = true;
52 | }
53 | }
54 |
55 | // Event handler: Loaded
56 |
57 | private void Loaded_Handler( object sender, RoutedEventArgs evt )
58 | {
59 | if (string.Compare(downloadUri.Scheme, "http", StringComparison.OrdinalIgnoreCase) == 0 ||
60 | string.Compare(downloadUri.Scheme, "https", StringComparison.OrdinalIgnoreCase) == 0)
61 | {
62 | webClient.Headers.Add("User-Agent", $"JuisCheck/{App.GetVersion()} (MS Windows)");
63 | webClient.Headers.Add("Accept", "*/*");
64 | }
65 |
66 | webClient.DownloadFileAsync(downloadUri, downloadFilePath);
67 | }
68 |
69 | // Event handler: WebClient_DownloadFileCompleted
70 |
71 | void WebClient_DownloadFileCompleted_Handler( object sender, AsyncCompletedEventArgs evt )
72 | {
73 | if (evt.Cancelled) {
74 | try {
75 | File.Delete(downloadFilePath);
76 | } catch {
77 | }
78 | } else {
79 | if (evt.Error is Exception ex) {
80 | Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => {
81 | MessageBoxEx.Show(new MessageBoxExParams {
82 | CaptionText = JCstring.MessageCaptionError,
83 | MessageText = ex.Message,
84 | Image = MessageBoxExImage.Error,
85 | ButtonText = new string[] { JCstring.DialogButtonTextOk },
86 | Owner = this
87 | });
88 | }));
89 | }
90 | }
91 |
92 | completed = true;
93 | Close();
94 | }
95 |
96 | // Event handler: WebClient_DownloadProgressChanged
97 |
98 | private void WebClient_DownloadProgressChanged_Handler( object sender, DownloadProgressChangedEventArgs evt )
99 | {
100 | if (evt.TotalBytesToReceive == 0) {
101 | pbProgress.IsIndeterminate = true;
102 | } else {
103 | pbProgress.Value = evt.BytesReceived * pbProgress.Maximum / evt.TotalBytesToReceive;
104 | }
105 | }
106 |
107 | // Interface: IDisposable
108 |
109 | public void Dispose()
110 | {
111 | Dispose(true);
112 | GC.SuppressFinalize(this);
113 | }
114 |
115 | private void Dispose( bool disposing )
116 | {
117 | if (!disposed) {
118 | if (disposing) {
119 | webClient.Dispose();
120 | }
121 | disposed = true;
122 | }
123 | }
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/JuisCheck/ExtensionMethods.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 | using System.Windows.Controls;
3 |
4 | namespace JuisCheck
5 | {
6 | public static class ExtensionMethods
7 | {
8 | public static bool GetTreeHasError(this DependencyObject node, bool skipDisabled, bool skipInvisible)
9 | {
10 | if (node is UIElement uiElement) {
11 | if (skipDisabled && !uiElement.IsEnabled) {
12 | return false;
13 | }
14 | if (skipInvisible && !uiElement.IsVisible) {
15 | return false;
16 | }
17 | }
18 |
19 | if (Validation.GetHasError(node)) {
20 | return true;
21 | }
22 |
23 | foreach (object childNode in LogicalTreeHelper.GetChildren(node)) {
24 | if (childNode is DependencyObject dependencyObject) {
25 | if (dependencyObject.GetTreeHasError(skipDisabled, skipInvisible)) {
26 | return true;
27 | }
28 | }
29 | }
30 |
31 | return false;
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/JuisCheck/FindUpdatesDialog.xaml:
--------------------------------------------------------------------------------
1 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/JuisCheck/FindUpdatesDialog.xaml.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Program : JuisCheck for Windows
3 | * Copyright : Copyright (C) Roger Hünen
4 | * License : GNU General Public License version 3 (see LICENSE)
5 | */
6 |
7 | using Muon.Dotnet.Extensions;
8 | using System;
9 | using System.Collections.Generic;
10 | using System.ComponentModel;
11 | using System.Windows;
12 | using System.Windows.Threading;
13 |
14 | using JuisCheck.Lang;
15 |
16 | namespace JuisCheck
17 | {
18 | ///
19 | /// Interaction logic for FindUpdatesDialog.xaml
20 | ///
21 | public sealed partial class FindUpdatesDialog : Window, IDisposable
22 | {
23 | private readonly List queryDevices;
24 | private readonly BackgroundWorker queryWorker;
25 | private bool completed = false;
26 | private bool disposed = false;
27 |
28 | public FindUpdatesDialog( List devices )
29 | {
30 | queryDevices = devices ?? throw new ArgumentNullException(nameof(devices));
31 | queryWorker = new BackgroundWorker() {
32 | WorkerReportsProgress = true,
33 | WorkerSupportsCancellation = true
34 | };
35 | queryWorker.DoWork += Worker_DoWork_Handler;
36 | queryWorker.ProgressChanged += Worker_ProgressChanged_Handler;
37 | queryWorker.RunWorkerCompleted += Worker_RunWorkerCompleted_Handler;
38 |
39 | InitializeComponent();
40 | DataContext = this;
41 |
42 | pbProgress.Minimum = 0;
43 | pbProgress.Maximum = queryDevices.Count;
44 | pbProgress.Value = 0;
45 | }
46 |
47 | // Event handler: Closing
48 |
49 | private void Closing_Handler( object sender, CancelEventArgs evt )
50 | {
51 | if (!completed) {
52 | queryWorker.CancelAsync();
53 | IsEnabled = false;
54 | evt.Cancel = true;
55 | }
56 | }
57 |
58 | // Event handler: Loaded
59 |
60 | private void Loaded_Handler( object sender, RoutedEventArgs evt )
61 | {
62 | queryWorker.RunWorkerAsync();
63 | }
64 |
65 | // Event handler: Worker_DoWork
66 |
67 | private void Worker_DoWork_Handler( object sender, DoWorkEventArgs evt )
68 | {
69 | BackgroundWorker worker = (BackgroundWorker)sender;
70 | int progress = 0;
71 |
72 | foreach (Device device in queryDevices) {
73 | string errorMessage = device.FindFirmwareUpdate(Dispatcher);
74 |
75 | if (errorMessage != null) {
76 | int result = -1;
77 | Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => {
78 | result = MessageBoxEx.Show(new MessageBoxExParams {
79 | CaptionText = JCstring.MessageCaptionError,
80 | MessageText = errorMessage.Unescape(),
81 | Image = MessageBoxExImage.Error,
82 | ButtonText = new string[] { JCstring.DialogButtonTextSkip, JCstring.DialogButtonTextCancel },
83 | Owner = this
84 | });
85 | }));
86 |
87 | if (result != 0) { // Cancel button, close box
88 | break;
89 | }
90 | }
91 |
92 | worker.ReportProgress(++progress);
93 | if (worker.CancellationPending) {
94 | break;
95 | }
96 | }
97 | }
98 |
99 | // Event handler: Worker_ProgressChanged
100 |
101 | private void Worker_ProgressChanged_Handler( object sender, ProgressChangedEventArgs evt )
102 | {
103 | pbProgress.Value = evt.ProgressPercentage;
104 | }
105 |
106 | // Event handler: Worker_RunWorkerCompleted
107 |
108 | private void Worker_RunWorkerCompleted_Handler( object sender, RunWorkerCompletedEventArgs evt )
109 | {
110 | completed = true;
111 | Close();
112 | }
113 |
114 | // Interface: IDisposable
115 |
116 | public void Dispose()
117 | {
118 | Dispose(true);
119 | GC.SuppressFinalize(this);
120 | }
121 |
122 | private void Dispose( bool disposing )
123 | {
124 | if (!disposed) {
125 | if (disposing) {
126 | queryWorker.Dispose();
127 | }
128 | disposed = true;
129 | }
130 | }
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/JuisCheck/FodyWeavers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/JuisCheck/FodyWeavers.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks
13 |
14 |
15 |
16 |
17 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.
18 |
19 |
20 |
21 |
22 | A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks
23 |
24 |
25 |
26 |
27 | A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.
28 |
29 |
30 |
31 |
32 | A list of unmanaged 32 bit assembly names to include, delimited with line breaks.
33 |
34 |
35 |
36 |
37 | A list of unmanaged 64 bit assembly names to include, delimited with line breaks.
38 |
39 |
40 |
41 |
42 | The order of preloaded assemblies, delimited with line breaks.
43 |
44 |
45 |
46 |
47 |
48 | This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file.
49 |
50 |
51 |
52 |
53 | Controls if .pdbs for reference assemblies are also embedded.
54 |
55 |
56 |
57 |
58 | Controls if runtime assemblies are also embedded.
59 |
60 |
61 |
62 |
63 | Controls whether the runtime assemblies are embedded with their full path or only with their assembly name.
64 |
65 |
66 |
67 |
68 | Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.
69 |
70 |
71 |
72 |
73 | As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.
74 |
75 |
76 |
77 |
78 | Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code.
79 |
80 |
81 |
82 |
83 | Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior.
84 |
85 |
86 |
87 |
88 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with |
89 |
90 |
91 |
92 |
93 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |.
94 |
95 |
96 |
97 |
98 | A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with |
99 |
100 |
101 |
102 |
103 | A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with |.
104 |
105 |
106 |
107 |
108 | A list of unmanaged 32 bit assembly names to include, delimited with |.
109 |
110 |
111 |
112 |
113 | A list of unmanaged 64 bit assembly names to include, delimited with |.
114 |
115 |
116 |
117 |
118 | The order of preloaded assemblies, delimited with |.
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 | 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.
127 |
128 |
129 |
130 |
131 | A comma-separated list of error codes that can be safely ignored in assembly verification.
132 |
133 |
134 |
135 |
136 | 'false' to turn off automatic generation of the XML Schema file.
137 |
138 |
139 |
140 |
141 |
--------------------------------------------------------------------------------
/JuisCheck/JUIS.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Program : JuisCheck for Windows
3 | * Copyright : Copyright (C) Roger Hünen
4 | * License : GNU General Public License version 3 (see LICENSE)
5 | */
6 |
7 | using System;
8 | using System.Globalization;
9 | using System.Text;
10 |
11 | namespace JuisCheck
12 | {
13 | static class JUIS
14 | {
15 | private static readonly AVM.JUIS.JUIS juis = new AVM.JUIS.JUIS();
16 |
17 | private static AVM.JUIS.RequestHeader GetRequestHeader()
18 | {
19 | string timestamp = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss", CultureInfo.InvariantCulture);
20 |
21 | return new AVM.JUIS.RequestHeader
22 | {
23 | ManualRequest = true,
24 | Nonce = Convert.ToBase64String(Encoding.UTF8.GetBytes(timestamp)),
25 | UserAgent = "Box"
26 | };
27 | }
28 |
29 | public static AVM.JUIS.UpdateInfo BoxFirmwareUpdateCheck(AVM.JUIS.BoxInfo boxInfo, AVM.JUIS.BoxInfo boxInfoMeshMaster)
30 | {
31 | return juis.BoxFirmwareUpdateCheck(GetRequestHeader(), boxInfo, boxInfoMeshMaster).UpdateInfo;
32 | }
33 |
34 | public static AVM.JUIS.UpdateInfo DeviceFirmwareUpdateCheck(AVM.JUIS.BoxInfo boxInfo, AVM.JUIS.DeviceInfo deviceInfo)
35 | {
36 | return juis.DeviceFirmwareUpdateCheck(GetRequestHeader(), boxInfo, deviceInfo).UpdateInfo;
37 | }
38 |
39 | public static string GetServerName()
40 | {
41 | return new Uri(juis.Url).Host;
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/JuisCheck/Jason/BoxInfo.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Program : JuisCheck for Windows
3 | * Copyright : Copyright (C) Roger Hünen
4 | * License : GNU General Public License version 3 (see LICENSE)
5 | */
6 |
7 | using System;
8 | using System.Collections.Generic;
9 | using System.Xml.Serialization;
10 |
11 | namespace JuisCheck.Jason
12 | {
13 | [XmlRoot(ElementName = "BoxInfo", Namespace = "http://jason.avm.de/updatecheck/")]
14 | public class BoxInfo
15 | {
16 | [XmlElement(ElementName = "Name")] public string Name { get; set; }
17 | [XmlElement(ElementName = "HW")] public int HW { get; set; }
18 | [XmlElement(ElementName = "Version")] public string Version { get; set; }
19 | [XmlElement(ElementName = "Revision")] public int Revision { get; set; }
20 | [XmlElement(ElementName = "Serial")] public string Serial { get; set; }
21 | [XmlElement(ElementName = "OEM")] public string OEM { get; set; }
22 | [XmlElement(ElementName = "Lang")] public string Lang { get; set; }
23 | [XmlElement(ElementName = "Annex")] public string Annex { get; set; }
24 | [XmlElement(ElementName = "Lab")] public string Lab { get; set; }
25 | [XmlElement(ElementName = "Country")] public string Country { get; set; }
26 | [XmlElement(ElementName = "Flag")] public List Flag { get; } = new List();
27 | [XmlElement(ElementName = "UpdateConfig")] public int UpdateConfig { get; set; }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/JuisCheck/JuisDeviceDialog.xaml.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Program : JuisCheck for Windows
3 | * Copyright : Copyright (C) Roger Hünen
4 | * License : GNU General Public License version 3 (see LICENSE)
5 | */
6 |
7 | using Muon.Dotnet.Extensions;
8 | using System;
9 | using System.Collections.Generic;
10 | using System.Globalization;
11 | using System.Linq;
12 | using System.Windows;
13 | using System.Windows.Controls;
14 | using System.Windows.Input;
15 |
16 | using JuisCheck.Lang;
17 |
18 | namespace JuisCheck
19 | {
20 | ///
21 | /// Interaction logic for DeviceDialog.xaml
22 | ///
23 | public sealed partial class JuisDeviceDialog : Window
24 | {
25 | private readonly JuisDevice origDevice;
26 |
27 | public JuisDevice DeviceData { get; private set; }
28 | public int SelectedIndex { get; set; } // Dummy for ComboBox SelectedIndex validation
29 |
30 | public List AnnexValues { get; private set; }
31 | public List BuildTypeValues { get; private set; }
32 | public List CountryValues { get; private set; }
33 | public List LanguageValues { get; private set; }
34 | public List MeshMasterValues { get; private set; }
35 | public List OEMValues { get; private set; }
36 |
37 | public JuisDeviceDialog( JuisDevice device )
38 | {
39 | origDevice = device ?? throw new ArgumentNullException(nameof(device));
40 | DeviceData = new JuisDevice(device);
41 |
42 | InitComboBoxValues(device);
43 | InitializeComponent();
44 | DataContext = this;
45 | }
46 |
47 | // Initialize the Mesh Master Values list
48 |
49 | private void InitComboBoxValues( JuisDevice device )
50 | {
51 | AnnexValues = JuisDevice.GetAnnexValues().AppendMissingAsUnknown(device.Annex);
52 | BuildTypeValues = JuisDevice.GetFirmwareBuildTypeValues().AppendMissingAsUnknown(device.FirmwareBuildType);
53 | CountryValues = Device.GetCountryValues().AppendMissingAsUnknown(device.Country);
54 | LanguageValues = Device.GetLanguageValues().AppendMissingAsUnknown(device.Language);
55 | OEMValues = Device.GetOemValues().AppendMissingAsUnknown(device.OEM);
56 |
57 | MeshMasterValues = new List();
58 | foreach (JuisDevice masterDevice in App.GetMainWindow().Devices.Where(d => d is JuisDevice && d.ID != device.ID)) {
59 | MeshMasterValues.Add(new ComboBoxValue(masterDevice.ID, masterDevice.DeviceName));
60 | }
61 | MeshMasterValues.Sort(new ComboBoxValueComparer(new NaturalStringComparer(App.defaultDisplayStringComparison)));
62 | MeshMasterValues.Prepend(string.Empty, JCstring.ComboBoxValueNoMaster);
63 | MeshMasterValues.AppendMissingAsUnknown(device.MeshMaster);
64 | }
65 |
66 | // Routed command: CmdOk
67 |
68 | public static readonly RoutedCommand CmdOK = new RoutedCommand();
69 |
70 | private void CmdOK_CanExecute( object sender, CanExecuteRoutedEventArgs evt )
71 | {
72 | evt.CanExecute = !this.GetTreeHasError(false, false);
73 | }
74 |
75 | private void CmdOK_Executed( object sender, ExecutedRoutedEventArgs evt )
76 | {
77 | DeviceData.TrimStrings();
78 | origDevice.CopyFrom(DeviceData);
79 |
80 | DialogResult = true;
81 | }
82 |
83 | // Routed command: CmdQuery
84 |
85 | public static readonly RoutedCommand CmdQuery = new RoutedCommand();
86 |
87 | private void CmdQuery_CanExecute( object sender, CanExecuteRoutedEventArgs evt )
88 | {
89 | evt.CanExecute = !string.IsNullOrWhiteSpace(DeviceData.DeviceAddress);
90 | }
91 |
92 | private void CmdQuery_Executed( object sender, ExecutedRoutedEventArgs evt )
93 | {
94 | try {
95 | DeviceData.QueryDevice();
96 | }
97 | catch (Exception ex) {
98 | MessageBoxEx.Show(new MessageBoxExParams {
99 | CaptionText = JCstring.MessageCaptionError,
100 | MessageText = string.Format(CultureInfo.CurrentCulture, JCstring.MessageTextDeviceQueryFailed.Unescape(), ex.Message),
101 | Image = MessageBoxExImage.Error,
102 | ButtonText = new string[] { JCstring.DialogButtonTextOk },
103 | Owner = this
104 | });
105 | }
106 | }
107 |
108 | // Event: TextBox_GotFocus
109 |
110 | private void TextBox_GotFocus_Handler( object sender, RoutedEventArgs evt )
111 | {
112 | if (sender is TextBox textBox) {
113 | textBox.SelectAll();
114 | }
115 | }
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/JuisCheck/MessageBoxEx.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
16 |
19 |
24 |
30 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/JuisCheck/MessageBoxEx.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Media;
4 | using System.Windows;
5 | using System.Windows.Controls;
6 | using System.Windows.Documents;
7 | using System.Windows.Interop;
8 | using System.Windows.Input;
9 | using System.Windows.Media.Imaging;
10 |
11 | #pragma warning disable CA1819 // Properties should not return arrays
12 |
13 | namespace JuisCheck
14 | {
15 | public enum MessageBoxExImage
16 | {
17 | None = 0,
18 | Question = 1,
19 | Information = 2,
20 | Warning = 3,
21 | Error = 4
22 | }
23 |
24 | public sealed class MessageBoxExParams
25 | {
26 | public string[] ButtonText { get; set; } = { "OK" };
27 | public string CaptionText { get; set; } = null;
28 | public string CheckboxText { get; set; } = null;
29 | public bool CheckboxValue { get; set; } = false;
30 | public int DefaultButton { get; set; } = -1;
31 | public MessageBoxExImage Image { get; set; } = MessageBoxExImage.None;
32 | public string MessageText { get; set; } = null;
33 | public Window Owner { get; set; } = null;
34 | public SystemSound Sound { get; set; } = null;
35 | }
36 |
37 | public sealed partial class MessageBoxEx : Window
38 | {
39 | //
40 | // Static members
41 | //
42 |
43 | public static int Show(MessageBoxExParams msgParams)
44 | {
45 | return Show(msgParams, false, out bool _);
46 | }
47 |
48 | public static int Show(MessageBoxExParams msgParams, out bool cbValue)
49 | {
50 | return Show(msgParams, true, out cbValue);
51 | }
52 |
53 | private static int Show(MessageBoxExParams msgParams, bool cbShow, out bool cbValue)
54 | {
55 | if (msgParams == null) {
56 | throw new ArgumentNullException(nameof(msgParams));
57 | }
58 |
59 | if (msgParams.MessageText == null) {
60 | throw new ArgumentException($"{nameof(msgParams)}.{nameof(msgParams.MessageText)}");
61 | }
62 | if (msgParams.CheckboxText == null && cbShow) {
63 | throw new ArgumentException($"{nameof(msgParams)}.{nameof(msgParams.CheckboxText)}");
64 | }
65 | if (msgParams.ButtonText == null) {
66 | throw new ArgumentException($"{nameof(msgParams)}: {nameof(msgParams.ButtonText)}");
67 | }
68 | if (msgParams.ButtonText.Length == 0) {
69 | throw new ArgumentException($"{nameof(msgParams)}.{nameof(msgParams.ButtonText)}");
70 | }
71 |
72 | if (msgParams.Sound != null) {
73 | msgParams.Sound.Play();
74 | }
75 |
76 | MessageBoxEx msgBox = new MessageBoxEx() {
77 | Title = msgParams.CaptionText ?? string.Empty
78 | };
79 |
80 | if (msgParams.Owner != null) {
81 | try {
82 | msgBox.Owner = msgParams.Owner;
83 | msgBox.WindowStartupLocation = WindowStartupLocation.CenterOwner;
84 | }
85 | catch (InvalidOperationException) {
86 | msgBox.WindowStartupLocation = WindowStartupLocation.CenterScreen;
87 | }
88 | } else {
89 | msgBox.WindowStartupLocation = WindowStartupLocation.CenterScreen;
90 | }
91 |
92 | msgBox.SetButtons(msgParams.ButtonText);
93 | msgBox.SetCheckbox(cbShow, msgParams.CheckboxText, msgParams.CheckboxValue);
94 | msgBox.SetImage(msgParams.Image);
95 | msgBox.SetMessage(msgParams.MessageText);
96 | msgBox.ShowDialog();
97 |
98 | cbValue = (bool)msgBox.cbCheckbox.IsChecked;
99 |
100 | return msgBox.result;
101 | }
102 |
103 | //
104 | // Other members
105 | //
106 |
107 | private int result = -1;
108 |
109 | private MessageBoxEx()
110 | {
111 | InitializeComponent();
112 | }
113 |
114 | private void AddButton(string text, int result)
115 | {
116 | Button button = new Button {
117 | Content = text,
118 | Tag = result
119 | };
120 | button.Click += Button_Click_Handler;
121 |
122 | ugButtons.Children.Add(button);
123 | ugButtons.Columns++;
124 | }
125 |
126 | private void SetButtons(string[] buttonText)
127 | {
128 | for (int i = 0; i < buttonText.Length; i++) {
129 | AddButton(buttonText[i], i);
130 | }
131 | }
132 |
133 | private void SetCheckbox(bool cbShow, string cbText, bool cbValue)
134 | {
135 | dpCheckbox.Visibility = cbShow ? Visibility.Visible : Visibility.Collapsed;
136 |
137 | if (cbShow) {
138 | cbCheckbox.IsChecked = cbValue;
139 |
140 | foreach (string line in cbText.Split('\n')) {
141 | tbkCheckboxText.Inlines.Add(new Run(line));
142 | tbkCheckboxText.Inlines.Add(new LineBreak());
143 | }
144 | }
145 | }
146 |
147 | private void SetImage(MessageBoxExImage image)
148 | {
149 | Icon icon;
150 |
151 | switch (image) {
152 | case MessageBoxExImage.Error: icon = SystemIcons.Error; break;
153 | case MessageBoxExImage.Information: icon = SystemIcons.Information; break;
154 | case MessageBoxExImage.None: icon = null; break;
155 | case MessageBoxExImage.Question: icon = SystemIcons.Question; break;
156 | case MessageBoxExImage.Warning: icon = SystemIcons.Warning; break;
157 |
158 | default:
159 | throw new ArgumentOutOfRangeException(nameof(image));
160 | }
161 |
162 | if (icon == null) {
163 | imgMessageIcon.Visibility = Visibility.Collapsed;
164 | } else {
165 | imgMessageIcon.Source = Imaging.CreateBitmapSourceFromHIcon(icon.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
166 | imgMessageIcon.Visibility = Visibility.Visible;
167 | }
168 | }
169 |
170 | private void SetMessage(string text)
171 | {
172 | foreach (string line in text.Split('\n')) {
173 | tbkMessageText.Inlines.Add(new Run(line));
174 | tbkMessageText.Inlines.Add(new LineBreak());
175 | }
176 | }
177 |
178 | //
179 | // Event handlers
180 | //
181 |
182 | private void Button_Click_Handler(object sender, RoutedEventArgs evt)
183 | {
184 | result = (int)(sender as Button).Tag;
185 | Close();
186 | }
187 |
188 | private void KeyUp_Handler(object sender, KeyEventArgs evt)
189 | {
190 | if (evt.Key == Key.Escape) {
191 | Close();
192 | }
193 | }
194 | }
195 | }
196 |
--------------------------------------------------------------------------------
/JuisCheck/MultiSelectDataGrid.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Program : JuisCheck for Windows
3 | * Copyright : Copyright (C) Roger Hünen
4 | * License : GNU General Public License version 3 (see LICENSE)
5 | */
6 |
7 | using System.Windows.Controls;
8 |
9 | namespace JuisCheck
10 | {
11 | public class MultiSelectDataGrid : DataGrid
12 | {
13 | public MultiSelectDataGrid() : base()
14 | {
15 | CanSelectMultipleItems = true;
16 | EnableColumnVirtualization = false;
17 | EnableRowVirtualization = false;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/JuisCheck/NaturalStringComparer.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Program : JuisCheck for Windows
3 | * Copyright : Copyright (C) Roger Hünen
4 | * License : GNU General Public License version 3 (see LICENSE)
5 | */
6 |
7 | using System;
8 | using System.Collections.Generic;
9 |
10 | namespace JuisCheck
11 | {
12 | public class NaturalStringComparer : Comparer
13 | {
14 | private enum TokenType
15 | {
16 | Nothing,
17 | Numerical,
18 | String,
19 | End
20 | }
21 |
22 | private sealed class StringParser
23 | {
24 | private string mSource;
25 | private int mLength;
26 | private int mCurrentIndex;
27 | private char mCurrentChar;
28 |
29 | internal void Init( string str )
30 | {
31 | mSource = str ?? string.Empty;
32 | mLength = mSource.Length;
33 | mCurrentIndex = -1;
34 |
35 | TokenType = TokenType.Nothing;
36 | NumericalValue = 0;
37 | StringValue = null;
38 |
39 | NextChar();
40 | }
41 |
42 | private void NextChar()
43 | {
44 | mCurrentIndex++;
45 | mCurrentChar = mCurrentIndex >= mLength ? '\0' : mSource[mCurrentIndex];
46 | }
47 |
48 | internal void NextToken()
49 | {
50 | NumericalValue = 0;
51 | StringValue = null;
52 |
53 | do {
54 | // End of string
55 | if (mCurrentChar == '\0') {
56 | TokenType = TokenType.End;
57 | return;
58 | }
59 |
60 | // Numerical token
61 | if (char.IsDigit(mCurrentChar)) {
62 | int startIndex = mCurrentIndex;
63 |
64 | do {
65 | NextChar();
66 | }
67 | while (char.IsDigit(mCurrentChar));
68 |
69 | StringValue = mSource.Substring(startIndex, mCurrentIndex - startIndex);
70 | TokenType = TokenType.String;
71 |
72 | if (decimal.TryParse(StringValue, out decimal value)) {
73 | NumericalValue = value;
74 | TokenType = TokenType.Numerical;
75 | }
76 |
77 | return;
78 | }
79 |
80 | // String token
81 | if (char.IsLetter(mCurrentChar)) {
82 | int startIndex = mCurrentIndex;
83 |
84 | do {
85 | NextChar();
86 | }
87 | while (char.IsLetter(mCurrentChar));
88 |
89 | StringValue = mSource.Substring(startIndex, mCurrentIndex - startIndex);
90 | TokenType = TokenType.String;
91 | return;
92 | }
93 |
94 | NextChar();
95 | }
96 | while (true);
97 | }
98 |
99 | internal decimal NumericalValue { get; private set; } = 0;
100 | internal string StringValue { get; private set; } = null;
101 | internal TokenType TokenType { get; private set; } = TokenType.Nothing;
102 | }
103 |
104 | private readonly StringParser mParser1;
105 | private readonly StringParser mParser2;
106 | private readonly StringComparison mStringComparison;
107 |
108 | public NaturalStringComparer( StringComparison stringComparison )
109 | {
110 | mParser1 = new StringParser();
111 | mParser2 = new StringParser();
112 | mStringComparison = stringComparison;
113 | }
114 |
115 | public override int Compare( string str1, string str2 )
116 | {
117 | int result;
118 |
119 | mParser1.Init(str1);
120 | mParser2.Init(str2);
121 |
122 | do {
123 | mParser1.NextToken();
124 | mParser2.NextToken();
125 |
126 | if (mParser1.TokenType == TokenType.Numerical && mParser2.TokenType == TokenType.Numerical) {
127 | result = decimal.Compare(mParser1.NumericalValue, mParser2.NumericalValue);
128 | if (result != 0) {
129 | return result;
130 | }
131 | }
132 |
133 | result = string.Compare(mParser1.StringValue, mParser2.StringValue, mStringComparison);
134 | if (result != 0) {
135 | return result;
136 | }
137 | }
138 | while (mParser1.TokenType != TokenType.End || mParser2.TokenType != TokenType.End);
139 |
140 | return 0;
141 | }
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/JuisCheck/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Resources;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 | using System.Windows;
6 |
7 | // General Information about an assembly is controlled through the following
8 | // set of attributes. Change these attribute values to modify the information
9 | // associated with an assembly.
10 | [assembly: AssemblyTitle("JuisCheck for Windows")]
11 | [assembly: AssemblyDescription("")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("")]
14 | [assembly: AssemblyProduct("JuisCheck")]
15 | [assembly: AssemblyCopyright("Copyright © Roger Hünen")]
16 | [assembly: AssemblyTrademark("")]
17 | [assembly: AssemblyCulture("")]
18 |
19 | // Setting ComVisible to false makes the types in this assembly not visible
20 | // to COM components. If you need to access a type in this assembly from
21 | // COM, set the ComVisible attribute to true on that type.
22 | [assembly: ComVisible(false)]
23 |
24 | //In order to begin building localizable applications, set
25 | //CultureYouAreCodingWith in your .csproj file
26 | //inside a . For example, if you are using US english
27 | //in your source files, set the to en-US. Then uncomment
28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in
29 | //the line below to match the UICulture setting in the project file.
30 |
31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
32 |
33 |
34 | [assembly: ThemeInfo(
35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
36 | //(used if a resource is not found in the page,
37 | // or application resource dictionaries)
38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
39 | //(used if a resource is not found in the page,
40 | // app, or any theme specific resource dictionaries)
41 | )]
42 |
43 |
44 | // Version information for an assembly consists of the following four values:
45 | //
46 | // Major Version
47 | // Minor Version
48 | // Build Number
49 | // Revision
50 | //
51 | // You can specify all the values or you can default the Build and Revision Numbers
52 | // by using the '*' as shown below:
53 | // [assembly: AssemblyVersion("1.0.*")]
54 | [assembly: AssemblyVersion("2.1.3.0")]
55 | [assembly: AssemblyFileVersion("2.1.3.0")]
56 | [assembly: NeutralResourcesLanguage("en")]
57 |
--------------------------------------------------------------------------------
/JuisCheck/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace JuisCheck.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("JuisCheck.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/JuisCheck/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/JuisCheck/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | False
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | False
19 |
20 |
21 | True
22 |
23 |
24 | True
25 |
26 |
27 | True
28 |
29 |
30 | False
31 |
32 |
33 | False
34 |
35 |
36 | False
37 |
38 |
39 | True
40 |
41 |
42 | True
43 |
44 |
45 | False
46 |
47 |
48 | True
49 |
50 |
51 | True
52 |
53 |
54 | -1
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | False
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | NaN
73 |
74 |
75 | NaN
76 |
77 |
78 | False
79 |
80 |
81 | True
82 |
83 |
84 | NaN
85 |
86 |
87 | NaN
88 |
89 |
90 |
91 |
92 |
93 | 10
94 |
95 |
96 | True
97 |
98 |
99 | auto
100 |
101 |
102 |
--------------------------------------------------------------------------------
/JuisCheck/RecentFileButton.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 | using System.Windows.Controls;
3 | using System.Windows.Media;
4 |
5 | namespace JuisCheck
6 | {
7 | public class RecentFileButton : Button
8 | {
9 | static RecentFileButton()
10 | {
11 | DefaultStyleKeyProperty.OverrideMetadata(typeof(RecentFileButton), new FrameworkPropertyMetadata(typeof(RecentFileButton)));
12 | }
13 |
14 | // DependencyProperty: DirPath
15 |
16 | public static readonly DependencyProperty DirPathProperty = DependencyProperty.Register("DirPath", typeof(string), typeof(RecentFileButton));
17 |
18 | public string DirPath
19 | {
20 | get => (string)GetValue(DirPathProperty);
21 | set => SetValue(DirPathProperty, value);
22 | }
23 |
24 | // DependencyProperty: DirPathFontSize
25 |
26 | public static readonly DependencyProperty DirPathFontSizeProperty = DependencyProperty.Register("DirPathFontSize", typeof(double), typeof(RecentFileButton));
27 |
28 | public double DirPathFontSize
29 | {
30 | get => (double)GetValue(DirPathFontSizeProperty);
31 | set => SetValue(DirPathFontSizeProperty, value);
32 | }
33 |
34 | // DependencyProperty: DirPathFontWeight
35 |
36 | public static readonly DependencyProperty DirPathFontWeightProperty = DependencyProperty.Register("DirPathFontWeight", typeof(FontWeight), typeof(RecentFileButton));
37 |
38 | public FontWeight DirPathFontWeight
39 | {
40 | get => (FontWeight)GetValue(DirPathFontWeightProperty);
41 | set => SetValue(DirPathFontWeightProperty, value);
42 | }
43 |
44 | // DependencyProperty: DirPathForeground
45 |
46 | public static readonly DependencyProperty DirPathForegroundProperty = DependencyProperty.Register("DirPathForeground", typeof(Brush), typeof(RecentFileButton));
47 |
48 | public Brush DirPathForeground
49 | {
50 | get => (Brush)GetValue(DirPathForegroundProperty);
51 | set => SetValue(DirPathForegroundProperty, value);
52 | }
53 |
54 | // DependencyProperty: DirPathMargin
55 |
56 | public static readonly DependencyProperty DirPathMarginProperty = DependencyProperty.Register("DirPathMargin", typeof(Thickness), typeof(RecentFileButton));
57 |
58 | public Thickness DirPathMargin
59 | {
60 | get => (Thickness)GetValue(DirPathMarginProperty);
61 | set => SetValue(DirPathMarginProperty, value);
62 | }
63 |
64 | // DependencyProperty: FileName
65 |
66 | public static readonly DependencyProperty FileNameProperty = DependencyProperty.Register("FileName", typeof(string), typeof(RecentFileButton));
67 |
68 | public string FileName
69 | {
70 | get => (string)GetValue(FileNameProperty);
71 | set => SetValue(FileNameProperty, value);
72 | }
73 |
74 | // DependencyProperty: FileNameFontSize
75 |
76 | public static readonly DependencyProperty FileNameFontSizeProperty = DependencyProperty.Register("FileNameFontSize", typeof(double), typeof(RecentFileButton));
77 |
78 | public double FileNameFontSize
79 | {
80 | get => (double)GetValue(FileNameFontSizeProperty);
81 | set => SetValue(FileNameFontSizeProperty, value);
82 | }
83 |
84 | // DependencyProperty: FileNameFontWeight
85 |
86 | public static readonly DependencyProperty FileNameFontWeightProperty = DependencyProperty.Register("FileNameFontWeight", typeof(FontWeight), typeof(RecentFileButton));
87 |
88 | public FontWeight FileNameFontWeight
89 | {
90 | get => (FontWeight)GetValue(FileNameFontWeightProperty);
91 | set => SetValue(FileNameFontWeightProperty, value);
92 | }
93 |
94 | // DependencyProperty: FileNameForeground
95 |
96 | public static readonly DependencyProperty FileNameForegroundProperty = DependencyProperty.Register("FileNameForeground", typeof(Brush), typeof(RecentFileButton));
97 |
98 | public Brush FileNameForeground
99 | {
100 | get => (Brush)GetValue(FileNameForegroundProperty);
101 | set => SetValue(FileNameForegroundProperty, value);
102 | }
103 |
104 | // DependencyProperty: FileNameMargin
105 |
106 | public static readonly DependencyProperty FileNameMarginProperty = DependencyProperty.Register("FileNameMargin", typeof(Thickness), typeof(RecentFileButton));
107 |
108 | public Thickness FileNameMargin
109 | {
110 | get => (Thickness)GetValue(FileNameMarginProperty);
111 | set => SetValue(FileNameMarginProperty, value);
112 | }
113 |
114 | // DependencyProperty: Image
115 |
116 | public static readonly DependencyProperty ImageProperty = DependencyProperty.Register("Image", typeof(ImageSource), typeof(RecentFileButton));
117 |
118 | public ImageSource Image
119 | {
120 | get => (ImageSource)GetValue(ImageProperty);
121 | set => SetValue(ImageProperty, value);
122 | }
123 |
124 | // DependencyProperty: ImageHeight
125 |
126 | public static readonly DependencyProperty ImageHeightProperty = DependencyProperty.Register("ImageHeight", typeof(double), typeof(RecentFileButton));
127 |
128 | public double ImageHeight
129 | {
130 | get => (double)GetValue(ImageHeightProperty);
131 | set => SetValue(ImageHeightProperty, value);
132 | }
133 |
134 | // DependencyProperty: ImageMargin
135 |
136 | public static readonly DependencyProperty ImageMarginProperty = DependencyProperty.Register("ImageMargin", typeof(Thickness), typeof(RecentFileButton));
137 |
138 | public Thickness ImageMargin
139 | {
140 | get => (Thickness)GetValue(ImageMarginProperty);
141 | set => SetValue(ImageMarginProperty, value);
142 | }
143 |
144 | // DependencyProperty: ImageWidth
145 |
146 | public static readonly DependencyProperty ImageWidthProperty = DependencyProperty.Register("ImageWidth", typeof(double), typeof(RecentFileButton));
147 |
148 | public double ImageWidth
149 | {
150 | get => (double)GetValue(ImageWidthProperty);
151 | set => SetValue(ImageWidthProperty, value);
152 | }
153 |
154 | // DependencyProperty: MouseOverBackground
155 |
156 | public static readonly DependencyProperty MouseOverBackgroundProperty = DependencyProperty.Register("MouseOverBackground", typeof(Brush), typeof(RecentFileButton));
157 |
158 | public Brush MouseOverBackground
159 | {
160 | get => (Brush)GetValue(MouseOverBackgroundProperty);
161 | set => SetValue(MouseOverBackgroundProperty, value);
162 | }
163 |
164 | // DependencyProperty: MouseOverBorderBrush
165 |
166 | public static readonly DependencyProperty MouseOverBorderBrushProperty = DependencyProperty.Register("MouseOverBorderBrush", typeof(Brush), typeof(RecentFileButton));
167 |
168 | public Brush MouseOverBorderBrush
169 | {
170 | get => (Brush)GetValue(MouseOverBorderBrushProperty);
171 | set => SetValue(MouseOverBorderBrushProperty, value);
172 | }
173 | }
174 | }
175 |
--------------------------------------------------------------------------------
/JuisCheck/RecentItemsCollection.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Program : JuisCheck for Windows
3 | * Copyright : Copyright (C) Roger Hünen
4 | * License : GNU General Public License version 3 (see LICENSE)
5 | */
6 |
7 | using System.Collections.Generic;
8 |
9 | namespace JuisCheck
10 | {
11 | public class RecentItemsCollection : List
12 | {
13 | /**********************/
14 | /* Class constructors */
15 | /**********************/
16 |
17 | public RecentItemsCollection()
18 | {
19 | }
20 |
21 | public RecentItemsCollection( IEnumerable items ) : base(items)
22 | {
23 | }
24 |
25 | /*****************/
26 | /* Other methods */
27 | /*****************/
28 |
29 | public List GetMaxItems( int maxCount )
30 | {
31 | return GetRange(0, maxCount < Count ? maxCount : Count);
32 | }
33 |
34 | public void InsertRecent( string item )
35 | {
36 | Remove(item);
37 | Insert(0, item);
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/JuisCheck/Resources/Converters/BoolToVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Program : JuisCheck for Windows
3 | * Copyright : Copyright (C) Roger Hünen
4 | * License : GNU General Public License version 3 (see LICENSE)
5 | */
6 |
7 | using System;
8 | using System.Globalization;
9 | using System.Windows;
10 | using System.Windows.Data;
11 |
12 | using JuisCheck.Lang;
13 |
14 | namespace JuisCheck.Resources.Converters
15 | {
16 | [ValueConversion(sourceType: typeof(bool), targetType: typeof(Visibility))]
17 | public class BoolToVisibilityConverter : IValueConverter
18 | {
19 | public object Convert( object value, Type targetType, object parameter, CultureInfo culture )
20 | {
21 | if (targetType != typeof(Visibility)) {
22 | throw new InvalidOperationException("Invalid target type");
23 | }
24 | if (!(value is bool)) {
25 | throw new InvalidOperationException("Invalid value type");
26 | }
27 |
28 | return (bool)value ? Visibility.Visible : Visibility.Collapsed;
29 | }
30 |
31 | public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture )
32 | {
33 | return (Visibility)value == Visibility.Visible;
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/JuisCheck/Resources/Converters/InverseBooleanConverter.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Program : JuisCheck for Windows
3 | * Copyright : Copyright (C) Roger Hünen
4 | * License : GNU General Public License version 3 (see LICENSE)
5 | */
6 |
7 | using System;
8 | using System.Globalization;
9 | using System.Windows.Data;
10 |
11 | using JuisCheck.Lang;
12 |
13 | namespace JuisCheck.Resources.Converters
14 | {
15 | [ValueConversion(sourceType: typeof(bool), targetType: typeof(bool))]
16 | public class InverseBooleanConverter : IValueConverter
17 | {
18 | public object Convert( object value, Type targetType, object parameter, CultureInfo culture )
19 | {
20 | if (targetType != typeof(bool)) {
21 | throw new InvalidOperationException("Invalid target type");
22 | }
23 | if (!(value is bool)) {
24 | throw new InvalidOperationException("Invalid value type");
25 | }
26 |
27 | return !(bool)value;
28 | }
29 |
30 | public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture )
31 | {
32 | throw new NotImplementedException();
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/JuisCheck/Resources/Converters/NullableDateTimeToStringConverter.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Program : JuisCheck for Windows
3 | * Copyright : Copyright (C) Roger Hünen
4 | * License : GNU General Public License version 3 (see LICENSE)
5 | */
6 |
7 | using System;
8 | using System.Globalization;
9 | using System.Windows.Data;
10 |
11 | using JuisCheck.Lang;
12 |
13 | namespace JuisCheck.Resources.Converters
14 | {
15 | [ValueConversion(sourceType: typeof(DateTime?), targetType: typeof(string))]
16 | public class NullableDateTimeToStringConverter : IValueConverter
17 | {
18 | public object Convert( object value, Type targetType, object parameter, CultureInfo culture )
19 | {
20 | if (targetType != typeof(string)) {
21 | throw new InvalidOperationException("Invalid target type");
22 | }
23 | if (value == null) {
24 | return string.Empty;
25 | }
26 | if (!(value is DateTime)) {
27 | throw new InvalidOperationException("Invalid value type");
28 | }
29 |
30 | return ((DateTime)value).ToString("G", CultureInfo.CurrentCulture);
31 | }
32 |
33 | public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture )
34 | {
35 | throw new NotImplementedException();
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/JuisCheck/Resources/Images/16x16/oxygen-application-exit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/JuisCheck/Resources/Images/16x16/oxygen-application-exit.png
--------------------------------------------------------------------------------
/JuisCheck/Resources/Images/16x16/oxygen-dialog-warning.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/JuisCheck/Resources/Images/16x16/oxygen-dialog-warning.png
--------------------------------------------------------------------------------
/JuisCheck/Resources/Images/16x16/oxygen-document-close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/JuisCheck/Resources/Images/16x16/oxygen-document-close.png
--------------------------------------------------------------------------------
/JuisCheck/Resources/Images/16x16/oxygen-document-open-recent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/JuisCheck/Resources/Images/16x16/oxygen-document-open-recent.png
--------------------------------------------------------------------------------
/JuisCheck/Resources/Images/16x16/oxygen-document-open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/JuisCheck/Resources/Images/16x16/oxygen-document-open.png
--------------------------------------------------------------------------------
/JuisCheck/Resources/Images/16x16/oxygen-document-save-as.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/JuisCheck/Resources/Images/16x16/oxygen-document-save-as.png
--------------------------------------------------------------------------------
/JuisCheck/Resources/Images/16x16/oxygen-document-save.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/JuisCheck/Resources/Images/16x16/oxygen-document-save.png
--------------------------------------------------------------------------------
/JuisCheck/Resources/Images/16x16/oxygen-help-about.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/JuisCheck/Resources/Images/16x16/oxygen-help-about.png
--------------------------------------------------------------------------------
/JuisCheck/Resources/Images/16x16/oxygen-preferences-system.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/JuisCheck/Resources/Images/16x16/oxygen-preferences-system.png
--------------------------------------------------------------------------------
/JuisCheck/Resources/Images/32x32/oxygen-dialog-information.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/JuisCheck/Resources/Images/32x32/oxygen-dialog-information.png
--------------------------------------------------------------------------------
/JuisCheck/Resources/Images/32x32/oxygen-dialog-ok-apply.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/JuisCheck/Resources/Images/32x32/oxygen-dialog-ok-apply.png
--------------------------------------------------------------------------------
/JuisCheck/Resources/Images/32x32/oxygen-document-close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/JuisCheck/Resources/Images/32x32/oxygen-document-close.png
--------------------------------------------------------------------------------
/JuisCheck/Resources/Images/32x32/oxygen-document-edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/JuisCheck/Resources/Images/32x32/oxygen-document-edit.png
--------------------------------------------------------------------------------
/JuisCheck/Resources/Images/32x32/oxygen-document-new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/JuisCheck/Resources/Images/32x32/oxygen-document-new.png
--------------------------------------------------------------------------------
/JuisCheck/Resources/Images/32x32/oxygen-document-open-recent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/JuisCheck/Resources/Images/32x32/oxygen-document-open-recent.png
--------------------------------------------------------------------------------
/JuisCheck/Resources/Images/32x32/oxygen-download.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/JuisCheck/Resources/Images/32x32/oxygen-download.png
--------------------------------------------------------------------------------
/JuisCheck/Resources/Images/32x32/oxygen-edit-clear-list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/JuisCheck/Resources/Images/32x32/oxygen-edit-clear-list.png
--------------------------------------------------------------------------------
/JuisCheck/Resources/Images/32x32/oxygen-edit-copy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/JuisCheck/Resources/Images/32x32/oxygen-edit-copy.png
--------------------------------------------------------------------------------
/JuisCheck/Resources/Images/32x32/oxygen-edit-paste.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/JuisCheck/Resources/Images/32x32/oxygen-edit-paste.png
--------------------------------------------------------------------------------
/JuisCheck/Resources/Images/32x32/oxygen-edit-select-all.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/JuisCheck/Resources/Images/32x32/oxygen-edit-select-all.png
--------------------------------------------------------------------------------
/JuisCheck/Resources/Images/32x32/oxygen-run-build-clean.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/JuisCheck/Resources/Images/32x32/oxygen-run-build-clean.png
--------------------------------------------------------------------------------
/JuisCheck/Resources/Images/32x32/oxygen-system-search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/JuisCheck/Resources/Images/32x32/oxygen-system-search.png
--------------------------------------------------------------------------------
/JuisCheck/Resources/Images/48x48/JuisCheck.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/JuisCheck/Resources/Images/48x48/JuisCheck.ico
--------------------------------------------------------------------------------
/JuisCheck/Resources/ValidationRules/ComboBoxValueSelectedRule.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Program : JuisCheck for Windows
3 | * Copyright : Copyright (C) Roger Hünen
4 | * License : GNU General Public License version 3 (see LICENSE)
5 | */
6 |
7 | using System;
8 | using System.Globalization;
9 | using System.Windows.Controls;
10 |
11 | using JuisCheck.Lang;
12 |
13 | namespace JuisCheck.Resources.ValidationRules
14 | {
15 | public class ComboBoxValueSelectedRule : ValidationRule
16 | {
17 | public override ValidationResult Validate( object value, CultureInfo cultureInfo )
18 | {
19 | if (!(value is int intval)) {
20 | throw new InvalidOperationException("Invalid value type");
21 | }
22 |
23 | if (intval < 0) {
24 | return new ValidationResult(false, JCstring.ValidationErrorNoValueSelected);
25 | }
26 |
27 | return ValidationResult.ValidResult;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/JuisCheck/Resources/ValidationRules/StringInt32RangeRule.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Program : JuisCheck for Windows
3 | * Copyright : Copyright (C) Roger Hünen
4 | * License : GNU General Public License version 3 (see LICENSE)
5 | */
6 |
7 | using System;
8 | using System.Globalization;
9 | using System.Windows.Controls;
10 |
11 | using JuisCheck.Lang;
12 |
13 | namespace JuisCheck.Resources.ValidationRules
14 | {
15 | public class StringInt32RangeRule : ValidationRule
16 | {
17 | public int Min { get; set; } = int.MinValue;
18 | public int Max { get; set; } = int.MaxValue;
19 |
20 | public override ValidationResult Validate( object value, CultureInfo cultureInfo )
21 | {
22 | if (!(value is string strval)) {
23 | throw new InvalidOperationException("Invalid value type");
24 | }
25 | strval = strval.Trim();
26 |
27 | if (strval.Length == 0) {
28 | return new ValidationResult(false, JCstring.ValidationErrorEmptyOrWhiteSpace);
29 | }
30 |
31 | if (!int.TryParse((string)value, out int intval)) {
32 | return new ValidationResult(false, JCstring.ValidationErrorInvalidCharacters);
33 | }
34 |
35 | if (intval < Min || intval > Max) {
36 | return new ValidationResult(false, string.Format(CultureInfo.CurrentCulture, JCstring.ValidationErrorValueOutOfRange, Min, Max));
37 | }
38 |
39 | return ValidationResult.ValidResult;
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/JuisCheck/Resources/ValidationRules/StringNotNullOrWhiteSpaceRule.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Program : JuisCheck for Windows
3 | * Copyright : Copyright (C) Roger Hünen
4 | * License : GNU General Public License version 3 (see LICENSE)
5 | */
6 |
7 | using System;
8 | using System.Globalization;
9 | using System.Windows.Controls;
10 |
11 | using JuisCheck.Lang;
12 |
13 | namespace JuisCheck.Resources.ValidationRules
14 | {
15 | public class StringNotNullOrWhiteSpaceRule : ValidationRule
16 | {
17 | public override ValidationResult Validate( object value, CultureInfo cultureInfo )
18 | {
19 | if (!(value is string strval)) {
20 | throw new InvalidOperationException("Invalid value type");
21 | }
22 |
23 | if (string.IsNullOrWhiteSpace(strval)) {
24 | return new ValidationResult(false, JCstring.ValidationErrorEmptyOrWhiteSpace);
25 | }
26 |
27 | return ValidationResult.ValidResult;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/JuisCheck/Resources/XAML/BaseStyles.xaml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
17 |
18 |
20 |
21 |
32 |
33 |
36 |
37 |
41 |
42 |
43 |
46 |
47 |
56 |
57 |
--------------------------------------------------------------------------------
/JuisCheck/Resources/XAML/ColorsAndBrushes.xaml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/JuisCheck/Resources/XAML/Converters.xaml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/JuisCheck/Resources/XAML/MainWindowBackstageStyles.xaml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
33 |
34 |
59 |
60 |
64 |
65 |
68 |
69 |
79 |
80 |
86 |
87 |
93 |
94 |
97 |
98 |
101 |
102 |
103 |
104 |
110 |
111 |
116 |
117 |
118 |
119 |
125 |
126 |
131 |
132 |
136 |
137 |
141 |
142 |
146 |
147 |
150 |
151 |
154 |
155 |
158 |
159 |
--------------------------------------------------------------------------------
/JuisCheck/Resources/XAML/MainWindowDataGridTemplates.xaml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
--------------------------------------------------------------------------------
/JuisCheck/Resources/XAML/MainWindowRibbonStyles.xaml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
22 |
23 |
27 |
28 |
--------------------------------------------------------------------------------
/JuisCheck/Resources/XAML/RecentFileButtonTemplate.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
43 |
44 |
54 |
55 |
62 |
63 |
64 |
67 |
68 |
73 |
74 |
80 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/JuisCheck/XML/JC1Data.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Xml;
5 | using System.Xml.Serialization;
6 |
7 | namespace JuisCheck.XML
8 | {
9 | [XmlRoot("Devices")]
10 | public class JC1Data
11 | {
12 | [XmlElement("Device")]
13 | public List Devices { get; } = new List();
14 |
15 | public static void LoadFromString( string xml, DeviceCollection devices )
16 | {
17 | if (xml == null) {
18 | throw new ArgumentNullException(nameof(xml));
19 | }
20 | if (devices == null) {
21 | throw new ArgumentNullException(nameof(devices));
22 | }
23 |
24 | XmlReaderSettings xmlReaderSettings = new XmlReaderSettings() { IgnoreComments = true, IgnoreWhitespace = true };
25 | XmlSerializer xmlSerializer = new XmlSerializer(typeof(JC1Data));
26 |
27 | using (XmlReader xmlReader = XmlReader.Create(new StringReader(xml), xmlReaderSettings)) {
28 | JC1Data jc1data = (JC1Data)xmlSerializer.Deserialize(xmlReader);
29 |
30 | devices.Clear();
31 | foreach (JC1Device jc1device in jc1data.Devices) {
32 | if (jc1device.DeviceKind == JC1DeviceKind.DECT) {
33 | devices.Add(new DectDevice(jc1device));
34 | }
35 | if (jc1device.DeviceKind == JC1DeviceKind.JUIS) {
36 | devices.Add(new JuisDevice(jc1device));
37 | }
38 | }
39 |
40 | devices.Settings.Reset();
41 | }
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/JuisCheck/XML/JC1Device.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Xml.Serialization;
4 |
5 | namespace JuisCheck.XML
6 | {
7 | public class JC1Device
8 | {
9 | [XmlAttribute("kind")] public JC1DeviceKind DeviceKind { get; set; } = JC1DeviceKind.Unknown;
10 |
11 | [XmlElement("DeviceName")] public string DeviceName { get; set; }
12 | [XmlElement("DeviceAddress")] public string DeviceAddress { get; set; }
13 | [XmlElement("ProductName")] public string ProductName { get; set; }
14 | [XmlElement("HardwareMajor")] public int HardwareMajor { get; set; }
15 | [XmlElement("HardwareMinor")] public int HardwareMinor { get; set; }
16 | [XmlElement("SerialNumber")] public string SerialNumber { get; set; }
17 | [XmlElement("FirmwareMajor")] public int FirmwareMajor { get; set; }
18 | [XmlElement("FirmwareMinor")] public int FirmwareMinor { get; set; }
19 | [XmlElement("FirmwarePatch")] public int FirmwarePatch { get; set; }
20 | [XmlElement("FirmwareBuildNumber")] public int FirmwareBuildNumber { get; set; }
21 | [XmlElement("FirmwareBuildType")] public int FirmwareBuildType { get; set; }
22 | [XmlElement("OEM")] public string OEM { get; set; }
23 | [XmlElement("Annex")] public string Annex { get; set; }
24 | [XmlElement("Country")] public string Country { get; set; }
25 | [XmlElement("Language")] public string Language { get; set; }
26 | [XmlElement("Flag")] public List Flags { get; } = new List();
27 | [XmlElement("BaseFritzOS")] public string BaseFritzOS { get; set; } // Not used in JuisCheck 2.x
28 | [XmlElement("UpdateAvailable")] public bool UpdateAvailable { get; set; }
29 | [XmlElement("UpdateInfo")] public string UpdateInfo { get; set; }
30 | [XmlElement("UpdateImageURL")] public string UpdateImageURL { get; set; }
31 | [XmlElement("UpdateInfoURL")] public string UpdateInfoURL { get; set; }
32 | [XmlElement("UpdateLastChecked")] public DateTime? UpdateLastChecked { get; set; }
33 |
34 | public JC1Device()
35 | {
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/JuisCheck/XML/JC1DeviceKind.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Program : JuisCheck for Windows
3 | * Copyright : Copyright (C) Roger Hünen
4 | * License : GNU General Public License version 3 (see LICENSE)
5 | */
6 |
7 | using System.Xml.Serialization;
8 |
9 | namespace JuisCheck.XML
10 | {
11 | public enum JC1DeviceKind
12 | {
13 | [XmlEnum(Name = "Unknown")]
14 | Unknown,
15 | [XmlEnum(Name = "DECT")]
16 | DECT,
17 | [XmlEnum(Name = "JUIS")]
18 | JUIS
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/JuisCheck/XML/JC2Data.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Xml;
5 | using System.Xml.Serialization;
6 |
7 | namespace JuisCheck.XML
8 | {
9 | [XmlRoot("JuisCheck2")]
10 | public class JC2Data
11 | {
12 | public const string xmlRootElementName = "JuisCheck2";
13 |
14 | // Note: the member order determines the order of elements in the XML output.
15 |
16 | [XmlArray("DectDevices")] public List DectDevices { get; } = new List();
17 | [XmlArray("JuisDevices")] public List JuisDevices { get; } = new List();
18 | [XmlArray("Settings")] public List Settings { get; } = new List();
19 |
20 | public static void LoadFromString( string xml, DeviceCollection devices )
21 | {
22 | if (xml == null) {
23 | throw new ArgumentNullException(nameof(xml));
24 | }
25 | if (devices == null) {
26 | throw new ArgumentNullException(nameof(devices));
27 | }
28 |
29 | XmlReaderSettings xmlReaderSettings = new XmlReaderSettings() { IgnoreComments = true, IgnoreWhitespace = true };
30 | XmlSerializer xmlSerializer = new XmlSerializer(typeof(JC2Data));
31 |
32 | using (XmlReader xmlReader = XmlReader.Create(new StringReader(xml), xmlReaderSettings)) {
33 | JC2Data jc2data = (JC2Data)xmlSerializer.Deserialize(xmlReader);
34 |
35 | devices.Clear();
36 | foreach (JC2DectDevice jc2dectDevice in jc2data.DectDevices) {
37 | devices.Add(new DectDevice(jc2dectDevice));
38 | }
39 | foreach (JC2JuisDevice jc2juisDevice in jc2data.JuisDevices) {
40 | devices.Add(new JuisDevice(jc2juisDevice));
41 | }
42 |
43 | devices.Settings.Reset();
44 | foreach(JC2Setting setting in jc2data.Settings) {
45 | devices.Settings.Add(setting.Name, setting.Value);
46 | }
47 | }
48 | }
49 |
50 | public static void SaveToFile( string fileName, DeviceCollection devices )
51 | {
52 | if (fileName == null) {
53 | throw new ArgumentNullException(nameof(fileName));
54 | }
55 | if (devices == null) {
56 | throw new ArgumentNullException(nameof(devices));
57 | }
58 |
59 | using (XmlWriter xmlWriter = XmlWriter.Create(fileName, new XmlWriterSettings { Indent = true })) {
60 | JC2Data jc2data = new JC2Data();
61 |
62 | foreach (Device device in devices) {
63 | if (device is DectDevice dectDevice) {
64 | jc2data.DectDevices.Add(new JC2DectDevice(dectDevice));
65 | }
66 | if (device is JuisDevice juisDevice) {
67 | jc2data.JuisDevices.Add(new JC2JuisDevice(juisDevice));
68 | }
69 | }
70 |
71 | foreach (KeyValuePair setting in devices.Settings.GetDictionary()) {
72 | jc2data.Settings.Add(new JC2Setting(setting.Key, setting.Value));
73 | }
74 |
75 | XmlSerializer xmlSerializer = new XmlSerializer(typeof(JC2Data));
76 | xmlSerializer.Serialize(xmlWriter, jc2data);
77 | }
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/JuisCheck/XML/JC2DectDevice.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Xml.Serialization;
3 |
4 | namespace JuisCheck.XML
5 | {
6 | [XmlType("DectDevice")]
7 | public class JC2DectDevice
8 | {
9 | // Note: the member order determines the order of attributes in the XML output.
10 |
11 | [XmlAttribute("id")] public string ID { get; set; }
12 |
13 | // Note: the member order determines the order of elements in the XML output.
14 |
15 | [XmlElement("DeviceName")] public string DeviceName { get; set; }
16 | [XmlElement("ProductName")] public string ProductName { get; set; }
17 | [XmlElement("HardwareMajor")] public int HardwareMajor { get; set; }
18 | [XmlElement("HardwareMinor")] public int HardwareMinor { get; set; }
19 | [XmlElement("FirmwareMajor")] public int FirmwareMajor { get; set; }
20 | [XmlElement("FirmwareMinor")] public int FirmwareMinor { get; set; }
21 | [XmlElement("FirmwareMinor2")] public int FirmwareMinor2 { get; set; }
22 | [XmlElement("FirmwareMinor3")] public int FirmwareMinor3 { get; set; }
23 | [XmlElement("FirmwareMinor4")] public int FirmwareMinor4 { get; set; }
24 | [XmlElement("OEM")] public string OEM { get; set; }
25 | [XmlElement("Country")] public string Country { get; set; }
26 | [XmlElement("Language")] public string Language { get; set; }
27 | [XmlElement("DectBase")] public string DectBase { get; set; }
28 | [XmlElement("UpdateAvailable")] public bool UpdateAvailable { get; set; }
29 | [XmlElement("UpdateInfo")] public string UpdateInfo { get; set; }
30 | [XmlElement("UpdateImageURL")] public string UpdateImageURL { get; set; }
31 | [XmlElement("UpdateInfoURL")] public string UpdateInfoURL { get; set; }
32 | [XmlElement("UpdateLastChecked")] public DateTime? UpdateLastChecked { get; set; }
33 |
34 | public JC2DectDevice()
35 | {
36 | }
37 |
38 | public JC2DectDevice( DectDevice dectDevice )
39 | {
40 | if (dectDevice == null) {
41 | throw new ArgumentNullException(nameof(dectDevice));
42 | }
43 |
44 | ID = dectDevice.ID;
45 |
46 | DeviceName = dectDevice.DeviceName;
47 | ProductName = dectDevice.ProductName;
48 | HardwareMajor = dectDevice.HardwareMajor;
49 | HardwareMinor = dectDevice.HardwareMinor;
50 | FirmwareMajor = dectDevice.FirmwareMajor;
51 | FirmwareMinor = dectDevice.FirmwareMinor;
52 | FirmwareMinor2 = dectDevice.FirmwareMinor2;
53 | FirmwareMinor3 = dectDevice.FirmwareMinor3;
54 | FirmwareMinor4 = dectDevice.FirmwareMinor4;
55 | OEM = dectDevice.OEM;
56 | Country = dectDevice.Country;
57 | Language = dectDevice.Language;
58 | DectBase = dectDevice.DectBase;
59 | UpdateAvailable = dectDevice.UpdateAvailable;
60 | UpdateImageURL = dectDevice.UpdateImageURL;
61 | UpdateInfo = dectDevice.UpdateVersion;
62 | UpdateInfoURL = dectDevice.UpdateInfoURL;
63 | UpdateLastChecked = dectDevice.UpdateLastChecked;
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/JuisCheck/XML/JC2JuisDevice.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Xml.Serialization;
4 |
5 | namespace JuisCheck.XML
6 | {
7 | [XmlType("JuisDevice")]
8 | public class JC2JuisDevice
9 | {
10 | // Note: the member order determines the order of attributes in the XML output.
11 |
12 | [XmlAttribute("id")] public string ID { get; set; }
13 |
14 | // Note: the member order determines the order of elements in the XML output.
15 |
16 | [XmlElement("DeviceName")] public string DeviceName { get; set; }
17 | [XmlElement("DeviceAddress")] public string DeviceAddress { get; set; }
18 | [XmlElement("ProductName")] public string ProductName { get; set; }
19 | [XmlElement("Hardware")] public int Hardware { get; set; }
20 | [XmlElement("SerialNumber")] public string SerialNumber { get; set; }
21 | [XmlElement("FirmwareMajor")] public int FirmwareMajor { get; set; }
22 | [XmlElement("FirmwareMinor")] public int FirmwareMinor { get; set; }
23 | [XmlElement("FirmwarePatch")] public int FirmwarePatch { get; set; }
24 | [XmlElement("FirmwareBuildNumber")] public int FirmwareBuildNumber { get; set; }
25 | [XmlElement("FirmwareBuildType")] public int FirmwareBuildType { get; set; }
26 | [XmlElement("OEM")] public string OEM { get; set; }
27 | [XmlElement("Annex")] public string Annex { get; set; }
28 | [XmlElement("Country")] public string Country { get; set; }
29 | [XmlElement("Language")] public string Language { get; set; }
30 | [XmlArray("Flags")][XmlArrayItem("Flag")] public List Flags { get; } = new List();
31 | [XmlElement("MeshMaster")] public string MeshMaster { get; set; }
32 | [XmlElement("UpdateAvailable")] public bool UpdateAvailable { get; set; }
33 | [XmlElement("UpdateInfo")] public string UpdateInfo { get; set; }
34 | [XmlElement("UpdateImageURL")] public string UpdateImageURL { get; set; }
35 | [XmlElement("UpdateInfoURL")] public string UpdateInfoURL { get; set; }
36 | [XmlElement("UpdateLastChecked")] public DateTime? UpdateLastChecked { get; set; }
37 |
38 | public JC2JuisDevice()
39 | {
40 | }
41 |
42 | public JC2JuisDevice( JuisDevice juisDevice )
43 | {
44 | if (juisDevice == null) {
45 | throw new ArgumentNullException(nameof(juisDevice));
46 | }
47 |
48 | ID = juisDevice.ID;
49 |
50 | DeviceName = juisDevice.DeviceName;
51 | DeviceAddress = juisDevice.DeviceAddress;
52 | ProductName = juisDevice.ProductName;
53 | Hardware = juisDevice.Hardware;
54 | SerialNumber = juisDevice.SerialNumber;
55 | FirmwareMajor = juisDevice.FirmwareMajor;
56 | FirmwareMinor = juisDevice.FirmwareMinor;
57 | FirmwarePatch = juisDevice.FirmwarePatch;
58 | FirmwareBuildNumber = juisDevice.FirmwareBuildNumber;
59 | FirmwareBuildType = juisDevice.FirmwareBuildType;
60 | OEM = juisDevice.OEM;
61 | Annex = juisDevice.Annex;
62 | Country = juisDevice.Country;
63 | Language = juisDevice.Language;
64 | Flags = JuisDevice.FlagsToList(juisDevice.Flags);
65 | MeshMaster = juisDevice.MeshMaster;
66 | UpdateAvailable = juisDevice.UpdateAvailable;
67 | UpdateImageURL = juisDevice.UpdateImageURL;
68 | UpdateInfo = juisDevice.UpdateVersion;
69 | UpdateInfoURL = juisDevice.UpdateInfoURL;
70 | UpdateLastChecked = juisDevice.UpdateLastChecked;
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/JuisCheck/XML/JC2Setting.cs:
--------------------------------------------------------------------------------
1 | using System.Xml.Serialization;
2 |
3 | namespace JuisCheck.XML
4 | {
5 | [XmlType("Setting")]
6 | public class JC2Setting
7 | {
8 | // Note: the member order determines the order of attributes in the XML output.
9 |
10 | [XmlAttribute("name")] public string Name { get; set; }
11 |
12 | // Note: the member order determines the order of elements in the XML output.
13 |
14 | [XmlElement("Value")] public string Value { get; set; }
15 |
16 | /****************/
17 | /* Constructors */
18 | /****************/
19 |
20 | public JC2Setting()
21 | {
22 | }
23 |
24 | public JC2Setting( string name, string value )
25 | {
26 | Name = name;
27 | Value = value;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/JuisCheck/XML/JCData.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 |
4 | namespace JuisCheck.XML
5 | {
6 | public static class JCData
7 | {
8 | public static bool LoadFromFile( string fileName, DeviceCollection devices )
9 | {
10 | if (fileName == null) {
11 | throw new ArgumentNullException(nameof(fileName));
12 | }
13 | if (devices == null) {
14 | throw new ArgumentNullException(nameof(devices));
15 | }
16 |
17 | // Read data only once
18 |
19 | string xml = File.ReadAllText(fileName);
20 |
21 | // Try JuisCheck2 file format
22 |
23 | try {
24 | JC2Data.LoadFromString(xml, devices);
25 | return false;
26 | }
27 | catch (InvalidOperationException) {
28 | }
29 |
30 | // Try JuisCheck1 file format
31 |
32 | JC1Data.LoadFromString(xml, devices);
33 | return true;
34 | }
35 |
36 | public static void SaveToFile( string fileName, DeviceCollection devices )
37 | {
38 | if (fileName == null) {
39 | throw new ArgumentNullException(nameof(fileName));
40 | }
41 | if (devices == null) {
42 | throw new ArgumentNullException(nameof(devices));
43 | }
44 |
45 | JC2Data.SaveToFile(fileName, devices);
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/JuisCheck/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | False
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | False
28 |
29 |
30 | True
31 |
32 |
33 | True
34 |
35 |
36 | True
37 |
38 |
39 | False
40 |
41 |
42 | False
43 |
44 |
45 | False
46 |
47 |
48 | True
49 |
50 |
51 | True
52 |
53 |
54 | False
55 |
56 |
57 | True
58 |
59 |
60 | True
61 |
62 |
63 | -1
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | False
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 | NaN
82 |
83 |
84 | NaN
85 |
86 |
87 | False
88 |
89 |
90 | True
91 |
92 |
93 | NaN
94 |
95 |
96 | NaN
97 |
98 |
99 |
100 |
101 |
102 | 10
103 |
104 |
105 | True
106 |
107 |
108 | auto
109 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/examples/FritzPowerline_Release.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | FRITZ!Powerline 540E
7 |
8 | FRITZ!Powerline 540E
9 | 201
10 |
11 | 129
12 | 7
13 | 12
14 | 70667
15 | 1
16 | avm
17 | Ohne
18 | 049
19 | de
20 |
21 |
22 | false
23 |
24 |
25 |
26 |
27 |
28 |
29 | FRITZ!Powerline 546E
30 |
31 | FRITZ!Powerline 546E
32 | 190
33 |
34 | 118
35 | 7
36 | 12
37 | 70668
38 | 1
39 | avm
40 | Ohne
41 | 049
42 | de
43 |
44 |
45 | false
46 |
47 |
48 |
49 |
50 |
51 |
52 | FRITZ!Powerline 1240E
53 |
54 | FRITZ!Powerline 1240E
55 | 222
56 |
57 | 150
58 | 7
59 | 12
60 | 70669
61 | 1
62 | avm
63 | Ohne
64 | 049
65 | de
66 |
67 |
68 | false
69 |
70 |
71 |
72 |
73 |
74 |
75 | FRITZ!Powerline 1260E
76 |
77 | FRITZ!Powerline 1260E
78 | 229
79 |
80 | 157
81 | 7
82 | 12
83 | 70670
84 | 1
85 | avm
86 | Ohne
87 | 049
88 | de
89 |
90 |
91 | false
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 | False
101 |
102 |
103 | False
104 |
105 |
106 | True
107 |
108 |
109 | True
110 |
111 |
112 | False
113 |
114 |
115 | False
116 |
117 |
118 | False
119 |
120 |
121 | True
122 |
123 |
124 | True
125 |
126 |
127 | False
128 |
129 |
130 | True
131 |
132 |
133 | True
134 |
135 |
136 |
--------------------------------------------------------------------------------
/examples/FritzWLAN_Obsolete_Release.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | FRITZ!WLAN Repeater 300E
7 |
8 | FRITZ!WLAN Repeater 300E
9 | 173
10 |
11 | 101
12 | 6
13 | 33
14 | 0
15 | 1
16 | avm
17 | Ohne
18 | 049
19 | de
20 |
21 |
22 | false
23 |
24 |
25 |
26 |
27 |
28 |
29 | FRITZ!WLAN Repeater DVB-C
30 |
31 | FRITZ!WLAN Repeater DVB-C
32 | 205
33 |
34 | 133
35 | 7
36 | 1
37 | 63069
38 | 1
39 | avm
40 | Ohne
41 | 049
42 | de
43 |
44 |
45 | false
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | False
55 |
56 |
57 | True
58 |
59 |
60 | True
61 |
62 |
63 | True
64 |
65 |
66 | False
67 |
68 |
69 | False
70 |
71 |
72 | False
73 |
74 |
75 | True
76 |
77 |
78 | True
79 |
80 |
81 | False
82 |
83 |
84 | True
85 |
86 |
87 | True
88 |
89 |
90 |
--------------------------------------------------------------------------------
/examples/FritzWLAN_Release.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | FRITZ!WLAN Repeater 310A
7 |
8 | FRITZ!WLAN Repeater 310A
9 | 194
10 |
11 | 122
12 | 7
13 | 12
14 | 70773
15 | 1
16 | avm
17 | Ohne
18 | 049
19 | de
20 |
21 |
22 | false
23 |
24 |
25 |
26 |
27 |
28 |
29 | FRITZ!WLAN Repeater 310B
30 |
31 | FRITZ!WLAN Repeater 310B
32 | 215
33 |
34 | 143
35 | 7
36 | 12
37 | 70776
38 | 1
39 | avm
40 | Ohne
41 | 049
42 | de
43 |
44 |
45 | false
46 |
47 |
48 |
49 |
50 |
51 |
52 | FRITZ!WLAN Repeater 450E
53 |
54 | FRITZ!WLAN Repeater 450E
55 | 200
56 |
57 | 128
58 | 7
59 | 12
60 | 70774
61 | 1
62 | avm
63 | Ohne
64 | 049
65 | de
66 |
67 |
68 | false
69 |
70 |
71 |
72 |
73 |
74 |
75 | FRITZ!WLAN Repeater 1160
76 |
77 | FRITZ!WLAN Repeater 1160
78 | 216
79 |
80 | 144
81 | 7
82 | 12
83 | 70777
84 | 1
85 | avm
86 | Ohne
87 | 049
88 | de
89 |
90 |
91 | false
92 |
93 |
94 |
95 |
96 |
97 |
98 | FRITZ!WLAN Repeater 1750E
99 |
100 | FRITZ!WLAN Repeater 1750E
101 | 206
102 |
103 | 134
104 | 7
105 | 12
106 | 70775
107 | 1
108 | avm
109 | Ohne
110 | 049
111 | de
112 |
113 |
114 | false
115 |
116 |
117 |
118 |
119 |
120 |
121 | FRITZ!WLAN Repeater 3000
122 |
123 | FRITZ!WLAN Repeater 3000
124 | 246
125 |
126 | 174
127 | 7
128 | 14
129 | 73940
130 | 1
131 | avm
132 | Ohne
133 | 049
134 | de
135 |
136 |
137 | false
138 |
139 |
140 |
141 |
142 |
143 |
144 | FRITZ!WLAN Repeater 1200
145 |
146 | FRITZ!WLAN Repeater 1200
147 | 244
148 |
149 | 172
150 | 7
151 | 14
152 | 73941
153 | 1
154 | avm
155 | Ohne
156 | 049
157 | de
158 |
159 |
160 | false
161 |
162 |
163 |
164 |
165 |
166 |
167 | FRITZ!WLAN Repeater 600
168 |
169 | FRITZ!WLAN Repeater 600
170 | 240
171 |
172 | 168
173 | 7
174 | 12
175 | 70604
176 | 1
177 | avm
178 | Ohne
179 | 049
180 | de
181 |
182 |
183 | false
184 |
185 |
186 |
187 |
188 |
189 |
190 | FRITZ!WLAN Repeater 2400
191 |
192 | FRITZ!WLAN Repeater 2400
193 | 241
194 |
195 | 169
196 | 7
197 | 12
198 | 70403
199 | 1
200 | avm
201 | Ohne
202 | 049
203 | de
204 |
205 |
206 | false
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 | False
216 |
217 |
218 | False
219 |
220 |
221 | True
222 |
223 |
224 | True
225 |
226 |
227 | False
228 |
229 |
230 | False
231 |
232 |
233 | False
234 |
235 |
236 | True
237 |
238 |
239 | True
240 |
241 |
242 | False
243 |
244 |
245 | True
246 |
247 |
248 | True
249 |
250 |
251 |
--------------------------------------------------------------------------------
/libraries/Muon.DotNetExtensions.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/libraries/Muon.DotNetExtensions.dll
--------------------------------------------------------------------------------
/libraries/Muon.DotNetExtensions.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/libraries/Muon.DotNetExtensions.pdb
--------------------------------------------------------------------------------
/libraries/Muon.DotNetExtensions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Muon.DotNetExtensions
5 |
6 |
7 |
8 |
9 | This namespace contains extension methods for Microsoft .NET classes.
10 |
11 |
12 |
13 |
14 | Defines extensions to the class.
15 |
16 |
17 |
18 |
19 | Gets the Company attribute of an assembly.
20 |
21 | The assembly.
22 | The Company attribute.
23 | assembly is null.
24 |
25 |
26 |
27 | Gets the Copyright attribute of an assembly.
28 |
29 | The assembly.
30 | The Copyright attribute.
31 |
32 |
33 |
34 | Gets the Description attribute of an assembly.
35 |
36 | The assembly.
37 | The Description attribute.
38 | assembly is null.
39 |
40 |
41 |
42 | Gets the Product attribute of an assembly.
43 |
44 | The assembly.
45 | The Product attribute.
46 | assembly is null.
47 |
48 |
49 |
50 | Gets the Title attribute of an assembly.
51 |
52 | The assembly.
53 | The Title attribute.
54 | assembly is null.
55 |
56 |
57 |
58 | Gets the Version attribute of an assembly.
59 |
60 | The assembly.
61 | The number of version parts to get (1-4). The default is 4.
62 | The Version attribute.
63 | assembly is null.
64 |
65 |
66 |
67 | Defines extensions to the class.
68 |
69 |
70 |
71 |
72 | Returns the unescaped version of a string. See for the supported escape sequences.
73 |
74 | The original string.
75 | The unescaped string.
76 |
77 |
78 |
79 | Returns a new string that contains at most the specified number of
80 | characters of the current instance.
81 |
82 | The original string.
83 | The maximum number of characters to return.
84 | The new string.
85 |
86 |
87 |
88 | Defines extensions to the class.
89 |
90 |
91 |
92 |
93 | Determines if any DependenctObject node in a DependencyObject tree has an error.
94 |
95 | The root node of the DependencyObject tree.
96 | True if the DependencyObject tree has an error.
97 |
98 |
99 |
100 | Determines if any DependenctObject node in a DependencyObject tree has an error.
101 |
102 | The root node of the DependencyObject tree.
103 | If true do not evaluate nodes that are disabled.
104 | If true do not evaluate nodes that are invisible.
105 | True if the DependencyObject tree has an error.
106 |
107 |
108 |
109 |
--------------------------------------------------------------------------------
/libraries/Muon.Windows.Controls.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/libraries/Muon.Windows.Controls.dll
--------------------------------------------------------------------------------
/libraries/Muon.Windows.Controls.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/libraries/Muon.Windows.Controls.pdb
--------------------------------------------------------------------------------
/libraries/Muon.Windows.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/libraries/Muon.Windows.dll
--------------------------------------------------------------------------------
/libraries/Muon.Windows.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingfisher63/avm_juischeck/986745a49ac9719ba59610d6df2caf565ddcdfcf/libraries/Muon.Windows.pdb
--------------------------------------------------------------------------------