├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── VSRepoGUI.sln
└── VSRepoGUI
├── App.config
├── App.xaml
├── App.xaml.cs
├── Converters
├── BoolToCollapsedConverter.cs
├── ButtonStatusConverter.cs
├── ButtonStatusToTextConverter.cs
├── DateUtcConverter.cs
├── InverseBooleanConverter.cs
├── LabelStatusVisibilityConverter.cs
└── NamespaceModulenameText.cs
├── Diagnose.cs
├── FodyWeavers.xml
├── FodyWeavers.xsd
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── PortableSettings.cs
├── Properties
├── AssemblyInfo.cs
├── Resources.Designer.cs
├── Resources.resx
├── Settings.Designer.cs
└── Settings.settings
├── Resources
├── icon.ico
└── vsrepo_logo.png
├── SettingsService.cs
├── SystemInfo.cs
├── VSRepoGUI.csproj
├── VsApi.cs
├── VsRegistry.cs
└── Vspackage.cs
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Build results
17 | [Dd]ebug/
18 | [Dd]ebugPublic/
19 | [Rr]elease/
20 | [Rr]eleases/
21 | x64/
22 | x86/
23 | [Aa][Rr][Mm]/
24 | [Aa][Rr][Mm]64/
25 | bld/
26 | [Bb]in/
27 | [Oo]bj/
28 | [Ll]og/
29 |
30 | # Visual Studio 2015/2017 cache/options directory
31 | .vs/
32 | # Uncomment if you have tasks that create the project's static files in wwwroot
33 | #wwwroot/
34 |
35 | # Visual Studio 2017 auto generated files
36 | Generated\ Files/
37 |
38 | # MSTest test Results
39 | [Tt]est[Rr]esult*/
40 | [Bb]uild[Ll]og.*
41 |
42 | # NUNIT
43 | *.VisualState.xml
44 | TestResult.xml
45 |
46 | # Build Results of an ATL Project
47 | [Dd]ebugPS/
48 | [Rr]eleasePS/
49 | dlldata.c
50 |
51 | # Benchmark Results
52 | BenchmarkDotNet.Artifacts/
53 |
54 | # .NET Core
55 | project.lock.json
56 | project.fragment.lock.json
57 | artifacts/
58 |
59 | # StyleCop
60 | StyleCopReport.xml
61 |
62 | # Files built by Visual Studio
63 | *_i.c
64 | *_p.c
65 | *_h.h
66 | *.ilk
67 | *.meta
68 | *.obj
69 | *.iobj
70 | *.pch
71 | *.pdb
72 | *.ipdb
73 | *.pgc
74 | *.pgd
75 | *.rsp
76 | *.sbr
77 | *.tlb
78 | *.tli
79 | *.tlh
80 | *.tmp
81 | *.tmp_proj
82 | *_wpftmp.csproj
83 | *.log
84 | *.vspscc
85 | *.vssscc
86 | .builds
87 | *.pidb
88 | *.svclog
89 | *.scc
90 |
91 | # Chutzpah Test files
92 | _Chutzpah*
93 |
94 | # Visual C++ cache files
95 | ipch/
96 | *.aps
97 | *.ncb
98 | *.opendb
99 | *.opensdf
100 | *.sdf
101 | *.cachefile
102 | *.VC.db
103 | *.VC.VC.opendb
104 |
105 | # Visual Studio profiler
106 | *.psess
107 | *.vsp
108 | *.vspx
109 | *.sap
110 |
111 | # Visual Studio Trace Files
112 | *.e2e
113 |
114 | # TFS 2012 Local Workspace
115 | $tf/
116 |
117 | # Guidance Automation Toolkit
118 | *.gpState
119 |
120 | # ReSharper is a .NET coding add-in
121 | _ReSharper*/
122 | *.[Rr]e[Ss]harper
123 | *.DotSettings.user
124 |
125 | # JustCode is a .NET coding add-in
126 | .JustCode
127 |
128 | # TeamCity is a build add-in
129 | _TeamCity*
130 |
131 | # DotCover is a Code Coverage Tool
132 | *.dotCover
133 |
134 | # AxoCover is a Code Coverage Tool
135 | .axoCover/*
136 | !.axoCover/settings.json
137 |
138 | # Visual Studio code coverage results
139 | *.coverage
140 | *.coveragexml
141 |
142 | # NCrunch
143 | _NCrunch_*
144 | .*crunch*.local.xml
145 | nCrunchTemp_*
146 |
147 | # MightyMoose
148 | *.mm.*
149 | AutoTest.Net/
150 |
151 | # Web workbench (sass)
152 | .sass-cache/
153 |
154 | # Installshield output folder
155 | [Ee]xpress/
156 |
157 | # DocProject is a documentation generator add-in
158 | DocProject/buildhelp/
159 | DocProject/Help/*.HxT
160 | DocProject/Help/*.HxC
161 | DocProject/Help/*.hhc
162 | DocProject/Help/*.hhk
163 | DocProject/Help/*.hhp
164 | DocProject/Help/Html2
165 | DocProject/Help/html
166 |
167 | # Click-Once directory
168 | publish/
169 |
170 | # Publish Web Output
171 | *.[Pp]ublish.xml
172 | *.azurePubxml
173 | # Note: Comment the next line if you want to checkin your web deploy settings,
174 | # but database connection strings (with potential passwords) will be unencrypted
175 | *.pubxml
176 | *.publishproj
177 |
178 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
179 | # checkin your Azure Web App publish settings, but sensitive information contained
180 | # in these scripts will be unencrypted
181 | PublishScripts/
182 |
183 | # NuGet Packages
184 | *.nupkg
185 | # The packages folder can be ignored because of Package Restore
186 | **/[Pp]ackages/*
187 | # except build/, which is used as an MSBuild target.
188 | !**/[Pp]ackages/build/
189 | # Uncomment if necessary however generally it will be regenerated when needed
190 | #!**/[Pp]ackages/repositories.config
191 | # NuGet v3's project.json files produces more ignorable files
192 | *.nuget.props
193 | *.nuget.targets
194 |
195 | # Microsoft Azure Build Output
196 | csx/
197 | *.build.csdef
198 |
199 | # Microsoft Azure Emulator
200 | ecf/
201 | rcf/
202 |
203 | # Windows Store app package directories and files
204 | AppPackages/
205 | BundleArtifacts/
206 | Package.StoreAssociation.xml
207 | _pkginfo.txt
208 | *.appx
209 |
210 | # Visual Studio cache files
211 | # files ending in .cache can be ignored
212 | *.[Cc]ache
213 | # but keep track of directories ending in .cache
214 | !?*.[Cc]ache/
215 |
216 | # Others
217 | ClientBin/
218 | ~$*
219 | *~
220 | *.dbmdl
221 | *.dbproj.schemaview
222 | *.jfm
223 | *.pfx
224 | *.publishsettings
225 | orleans.codegen.cs
226 |
227 | # Including strong name files can present a security risk
228 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
229 | #*.snk
230 |
231 | # Since there are multiple workflows, uncomment next line to ignore bower_components
232 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
233 | #bower_components/
234 |
235 | # RIA/Silverlight projects
236 | Generated_Code/
237 |
238 | # Backup & report files from converting an old project file
239 | # to a newer Visual Studio version. Backup files are not needed,
240 | # because we have git ;-)
241 | _UpgradeReport_Files/
242 | Backup*/
243 | UpgradeLog*.XML
244 | UpgradeLog*.htm
245 | ServiceFabricBackup/
246 | *.rptproj.bak
247 |
248 | # SQL Server files
249 | *.mdf
250 | *.ldf
251 | *.ndf
252 |
253 | # Business Intelligence projects
254 | *.rdl.data
255 | *.bim.layout
256 | *.bim_*.settings
257 | *.rptproj.rsuser
258 | *- Backup*.rdl
259 |
260 | # Microsoft Fakes
261 | FakesAssemblies/
262 |
263 | # GhostDoc plugin setting file
264 | *.GhostDoc.xml
265 |
266 | # Node.js Tools for Visual Studio
267 | .ntvs_analysis.dat
268 | node_modules/
269 |
270 | # Visual Studio 6 build log
271 | *.plg
272 |
273 | # Visual Studio 6 workspace options file
274 | *.opt
275 |
276 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
277 | *.vbw
278 |
279 | # Visual Studio LightSwitch build output
280 | **/*.HTMLClient/GeneratedArtifacts
281 | **/*.DesktopClient/GeneratedArtifacts
282 | **/*.DesktopClient/ModelManifest.xml
283 | **/*.Server/GeneratedArtifacts
284 | **/*.Server/ModelManifest.xml
285 | _Pvt_Extensions
286 |
287 | # Paket dependency manager
288 | .paket/paket.exe
289 | paket-files/
290 |
291 | # FAKE - F# Make
292 | .fake/
293 |
294 | # JetBrains Rider
295 | .idea/
296 | *.sln.iml
297 |
298 | # CodeRush personal settings
299 | .cr/personal
300 |
301 | # Python Tools for Visual Studio (PTVS)
302 | __pycache__/
303 | *.pyc
304 |
305 | # Cake - Uncomment if you are using it
306 | # tools/**
307 | # !tools/packages.config
308 |
309 | # Tabs Studio
310 | *.tss
311 |
312 | # Telerik's JustMock configuration file
313 | *.jmconfig
314 |
315 | # BizTalk build output
316 | *.btp.cs
317 | *.btm.cs
318 | *.odx.cs
319 | *.xsd.cs
320 |
321 | # OpenCover UI analysis results
322 | OpenCover/
323 |
324 | # Azure Stream Analytics local run output
325 | ASALocalRun/
326 |
327 | # MSBuild Binary and Structured Log
328 | *.binlog
329 |
330 | # NVidia Nsight GPU debugger configuration file
331 | *.nvuser
332 |
333 | # MFractors (Xamarin productivity tool) working folder
334 | .mfractor/
335 |
336 | # Local History for Visual Studio
337 | .localhistory/
338 |
339 | # BeatPulse healthcheck temp database
340 | healthchecksdb
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # VSRepoGUI
2 | A GUI for VSRepo
3 |
4 | You'll need [listpedeps.exe](https://github.com/brechtsanders/pedeps/releases) for missing plugin dependencies.
5 |
6 | Paste it in the same folder as vsrepogui.exe or install with `choco install pedeps`
7 |
8 | ### Links
9 |
10 | - [VSRepoGUI Forum](https://forum.doom9.org/showthread.php?t=176313)
11 | - [VSRepo Github](https://github.com/vapoursynth/vsrepo)
12 | - [VSRepo Forum](https://forum.doom9.org/showthread.php?t=175590)
13 |
14 |
15 | 
16 | 
17 |
--------------------------------------------------------------------------------
/VSRepoGUI.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.28803.156
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSRepoGUI", "VSRepoGUI\VSRepoGUI.csproj", "{FD263958-6C61-49F5-8725-E4D2AA27BE54}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {FD263958-6C61-49F5-8725-E4D2AA27BE54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {FD263958-6C61-49F5-8725-E4D2AA27BE54}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {FD263958-6C61-49F5-8725-E4D2AA27BE54}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {FD263958-6C61-49F5-8725-E4D2AA27BE54}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {A126607E-C9BE-4975-9791-F0CB0BCC3546}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/VSRepoGUI/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/VSRepoGUI/App.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/VSRepoGUI/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Configuration;
4 | using System.Data;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 |
9 | namespace VSRepoGUI
10 | {
11 | ///
12 | /// Interaktionslogik für "App.xaml"
13 | ///
14 | public partial class App : Application
15 | {
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/VSRepoGUI/Converters/BoolToCollapsedConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Windows;
4 | using System.Windows.Data;
5 |
6 | namespace VSRepoGUI.Converters
7 | {
8 | public class BoolToCollapsedConverter : IValueConverter
9 | {
10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
11 | {
12 | bool flag = false;
13 | if (value is bool)
14 | {
15 | flag = (bool)value;
16 | }
17 |
18 | string reverse = parameter as string;
19 | if (reverse != null && reverse == "Reverse")
20 | flag = !flag;
21 |
22 | return flag ? Visibility.Visible : Visibility.Collapsed;
23 | }
24 |
25 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
26 | {
27 | throw new NotImplementedException();
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/VSRepoGUI/Converters/ButtonStatusConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Data;
3 | using System.Windows.Media;
4 |
5 | namespace VSRepoGUI.Converters
6 | {
7 |
8 | public class ButtonStatusConverter : IValueConverter
9 | {
10 | //public static Style style = "MaterialDesignRaisedButton";
11 |
12 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
13 | {
14 | if ((VsApi.PluginStatus)value == VsApi.PluginStatus.Installed)
15 | {
16 | return new SolidColorBrush(Colors.OrangeRed);
17 | }
18 | if ((VsApi.PluginStatus)value == VsApi.PluginStatus.InstalledUnknown)
19 | {
20 | return new SolidColorBrush(Colors.Red);
21 | }
22 | if ((VsApi.PluginStatus)value == VsApi.PluginStatus.NotInstalled)
23 | {
24 | return new SolidColorBrush(Colors.Green);
25 | }
26 | return new SolidColorBrush(Colors.LimeGreen);
27 | }
28 |
29 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
30 | {
31 | throw new NotImplementedException();
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/VSRepoGUI/Converters/ButtonStatusToTextConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows;
3 | using System.Windows.Data;
4 | using System.Windows.Media;
5 |
6 | namespace VSRepoGUI.Converters
7 | {
8 | public class ButtonStatusToTextConverter : IValueConverter
9 | {
10 | //public static Style style = "MaterialDesignRaisedButton";
11 |
12 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
13 | {
14 |
15 | if ((VsApi.PluginStatus)value == VsApi.PluginStatus.Installed)
16 | {
17 | return "Uninstall";
18 |
19 | }
20 | if ((VsApi.PluginStatus)value == VsApi.PluginStatus.InstalledUnknown)
21 | {
22 | return "Force Upgrade";
23 | }
24 | if ((VsApi.PluginStatus)value == VsApi.PluginStatus.NotInstalled)
25 | {
26 | return "Install";
27 | }
28 | return "Update";
29 | }
30 |
31 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
32 | {
33 | throw new NotImplementedException();
34 | }
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/VSRepoGUI/Converters/DateUtcConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Data;
3 |
4 | namespace VSRepoGUI.Converters
5 | {
6 | public class DateUtcConverter : IValueConverter
7 | {
8 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
9 | {
10 | if(value != null)
11 | {
12 | try
13 | {
14 | return DateTime.SpecifyKind(DateTime.Parse(value.ToString()), DateTimeKind.Utc).ToLocalTime();
15 | } catch
16 | {
17 | return "";
18 | }
19 |
20 | }
21 | return "";
22 | }
23 |
24 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
25 | {
26 | throw new NotImplementedException();
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/VSRepoGUI/Converters/InverseBooleanConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Data;
3 |
4 | namespace VSRepoGUI.Converters
5 | {
6 | [ValueConversion(typeof(bool), typeof(bool))]
7 | public class InverseBooleanConverter : IValueConverter
8 | {
9 | #region IValueConverter Members
10 |
11 | public object Convert(object value, Type targetType, object parameter,
12 | System.Globalization.CultureInfo culture)
13 | {
14 | if (targetType != typeof(bool))
15 | throw new InvalidOperationException("The target must be a boolean");
16 |
17 | return !(bool)value;
18 | }
19 |
20 | public object ConvertBack(object value, Type targetType, object parameter,
21 | System.Globalization.CultureInfo culture)
22 | {
23 | throw new NotSupportedException();
24 | }
25 |
26 | #endregion
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/VSRepoGUI/Converters/LabelStatusVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Windows;
4 | using System.Windows.Data;
5 |
6 | namespace VSRepoGUI.Converters
7 | {
8 | public class LabelStatusVisibilityConverter : IValueConverter
9 | {
10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
11 | {
12 | if(value is null)
13 | {
14 | return Visibility.Collapsed;
15 | }
16 | return Visibility.Visible;
17 | }
18 |
19 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
20 | {
21 | throw new NotImplementedException();
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/VSRepoGUI/Converters/NamespaceModulenameText.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Windows;
4 | using System.Windows.Data;
5 |
6 | namespace VSRepoGUI.Converters
7 | {
8 | public class NamespaceModulenameText : IValueConverter
9 | {
10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
11 | {
12 | return ((Package)value).Namespace ?? ((Package)value).Modulename;
13 | }
14 |
15 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
16 | {
17 | throw new NotImplementedException();
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/VSRepoGUI/Diagnose.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Diagnostics;
5 | using System.IO;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Text.RegularExpressions;
9 | using System.Threading.Tasks;
10 |
11 | namespace VSRepoGUI
12 | {
13 | public class Diagnose
14 | {
15 | public string python_bin = "python.exe";
16 |
17 | // https://docs.microsoft.com/en-us/windows/win32/sysinfo/operating-system-version
18 | public Dictionary os_versions = new Dictionary
19 | {
20 | {"5.0", "Windows 2000" },
21 | {"5.1", "Windows XP" },
22 | {"5.2", "Windows XP 64-Bit Edition or Windows Server 2003 (or R3)" },
23 | {"6.0", "Windows Vista or Windows Server 2008" },
24 | {"6.1", "Windows 7 or Windows Server 2008 R2" },
25 | {"6.2", "Windows 8 or Windows Server 2012" },
26 | {"6.3", "Windows 8.1 or Windows Server 2012 R2" },
27 | {"10.0", "Windows 10 or Windows Server 2016/2019" },
28 | };
29 |
30 | public Diagnose(string pythonbin)
31 | {
32 | this.python_bin = pythonbin;
33 | }
34 |
35 |
36 | ///
37 | /// Result [["continuity.dll", "Plugin load failed, namespace edgefixer already populated (D:\\xy\\plugins64\\continuity.dll)"],
38 | /// ["cublas64_80.dll", "No entry point found in D:\\xy\\plugins64\\cublas64_80.dll"], ... ]]
39 | ///
40 | ///
41 | ///
42 | public async Task>> CheckPluginsAsync(string path)
43 | {
44 | Dictionary> dllfiles = new Dictionary>();
45 | string code = GetDllCheckCode(path);
46 | string result = await Task.Run(() => run_python(code));
47 | Console.WriteLine(result);
48 | string[][] packages;
49 | try
50 | {
51 | packages = JsonConvert.DeserializeObject(result);
52 | if (packages == null)
53 | return null;
54 | }
55 | catch
56 | {
57 | return null;
58 | }
59 | dllfiles.Add("no_problems", (from file in packages
60 | where file[1].Contains("already loaded")
61 | select Path.Combine(path, file[0])).OrderBy(f => f).ToList());
62 |
63 | dllfiles.Add("not_a_vsplugin", (from file in packages
64 | where file[1].Contains("No entry point found")
65 | select Path.Combine(path, file[0])).OrderBy(f => f).ToList());
66 |
67 | dllfiles.Add("wrong_arch", (from file in packages
68 | where file[1].Contains("returned 193")
69 | select Path.Combine(path, file[0])).OrderBy(f => f).ToList());
70 |
71 | dllfiles.Add("incompatible_dependency", (from file in packages
72 | where file[1].Contains("returned 127")
73 | select Path.Combine(path, file[0])).OrderBy(f => f).ToList());
74 |
75 | dllfiles.Add("missing_dependency", (from file in packages
76 | where file[1].Contains("returned 126")
77 | select Path.Combine(path, file[0])).OrderBy(f => f).ToList());
78 |
79 | dllfiles.Add("namespace", (from file in packages
80 | where file[1].Contains("already populated")
81 | select Path.Combine(path, file[0])).OrderBy(f => f).ToList());
82 |
83 | dllfiles.Add("others", (from file in packages
84 | where !(file[1].Contains("returned 193") || file[1].Contains("No entry point found") || file[1].Contains("already loaded") || file[1].Contains("returned 126") || file[1].Contains("returned 127") || file[1].Contains("already populated"))
85 | select Path.Combine(path, file[0])).OrderBy(f => f).ToList());
86 | return dllfiles;
87 | }
88 |
89 | public async Task GetVapoursynthVersion()
90 | {
91 | return await Task.Run(() => run_python("import vapoursynth as vs; print(vs.core.version())"));
92 | }
93 |
94 |
95 | public async Task GetLoadedVapoursynthDll()
96 | {
97 | var result = await Task.Run(() => run_python("import vapoursynth; print(vapoursynth.__file__)").Trim());
98 | if (String.IsNullOrEmpty(result))
99 | return null;
100 | return result.Split('.')[0] + ".dll";
101 | }
102 |
103 |
104 | public async Task GetPythonLocation()
105 | {
106 | return await Task.Run(() => run_python("import sys; print(sys.executable)").Trim());
107 | }
108 |
109 | public async Task GetDllDependencies(string file)
110 | {
111 | var result = await Task.Run(() => run_listpedeps(file));
112 | var dep = ParseDepends(result);
113 | if (dep == null)
114 | return null;
115 | else
116 | return dep;
117 | }
118 |
119 |
120 | private Depends ParseDepends(string input)
121 | {
122 | var dep = new Depends();
123 |
124 | var lines = input.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
125 |
126 | dep.file = input;
127 | dep.architecture = ArchToSimpleArch( Array.FindAll(lines, c => c.Contains("architecture:"))[0].Split(':')[1].Trim() );
128 | dep.machine_name = Array.FindAll(lines, c => c.Contains("machine name:"))[0].Split(':')[1].Trim();
129 | dep.subsystem = Array.FindAll(lines, c => c.Contains("subsystem:"))[0].Split(':')[1].Trim();
130 | dep.minimum_windows_version = Array.FindAll(lines, c => c.Contains("minimum Windows version:"))[0].Split(':')[1].Trim();
131 | dep.minimum_windows_osname = OsVersionToName(dep.minimum_windows_version);
132 |
133 | var split_import = input.Split(new string[] { "IMPORTS" }, StringSplitOptions.RemoveEmptyEntries)[1].Split(new string[] { "EXPORTS" }, StringSplitOptions.RemoveEmptyEntries)[0].Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
134 | foreach(var import in split_import)
135 | {
136 | var imp_tmp = import.Split(':');
137 | if(imp_tmp[0].Trim() != "KERNEL32.dll")
138 | {
139 | dep.Imports.Add(imp_tmp[0].Trim());
140 | }
141 | }
142 | dep.Imports = dep.Imports.Distinct().ToList();
143 |
144 | var split_export = input.Split(new string[] { "EXPORTS" }, StringSplitOptions.RemoveEmptyEntries)[1].Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
145 | foreach (var export in split_export)
146 | {
147 | var exp_tmp = export.Split(':');
148 | dep.Exports.Add(exp_tmp[0].Trim());
149 | if (exp_tmp[1].Trim().Contains("VapourSynthPluginInit"))
150 | dep.IsVapourSynthPlugin = true;
151 | if (exp_tmp[1].Trim().Contains("AvisynthPluginInit"))
152 | dep.IsAvisynthPlugin = true;
153 | }
154 | dep.Exports = dep.Exports.Distinct().ToList();
155 |
156 | return dep;
157 | }
158 |
159 |
160 | public Dictionary> CheckDuplicateAvsScripts(string path) //Dictionary>
161 | {
162 | var script_functions = new Dictionary();
163 | var script_functions_dups = new Dictionary>();
164 |
165 | //string pattern = @"function\s+([a-zA-Z_{1}][a-zA-Z0-9_]+).+[\s|\S](?=\()";
166 | //string pattern = @"function\s+.+[\s|\S](?=\()";
167 | //string pattern = @"^[f-fF-F]unction\s\w+";
168 | //string pattern = @"^(?!#|assert|.+#.+function)(.+|)function\s+\w+"; // good
169 | //string pattern = @"^(?!#|assert|.+#.+function)(.+|)function\s+\w+(\s+)?(?=\()"; // misses stuff in srestore.avsi and others
170 | string pattern = @"^(?!#|assert|.+#.+function)(.+|)function\s+\w+(\s+|.{5})?(?=\()"; // best?
171 | string[] filePaths = Directory.GetFiles(path, "*.avsi");
172 |
173 | foreach (var file in filePaths)
174 | {
175 | Console.WriteLine(file);
176 | foreach (Match m in Regex.Matches(File.ReadAllText(file, Encoding.UTF8), pattern, RegexOptions.IgnoreCase | RegexOptions.Multiline))
177 | {
178 | var potential_function = m.Value.Trim();
179 | Console.WriteLine("'{0}' found at index {1}.", potential_function, m.Index);
180 | if (potential_function.Split(' ').Length == 2) // check for valid function (in case the regex finds an invalid string)
181 | {
182 | string script_func = potential_function.Split(' ')[1].Trim();
183 | //Console.WriteLine("'{0}' found at index {1}.", m.Value.Trim(), m.Index);
184 | if (script_functions.ContainsKey(script_func))
185 | {
186 | if (!script_functions_dups.ContainsKey(script_func))
187 | {
188 | script_functions_dups[script_func] = new List() { script_functions[script_func] };
189 | if (!script_functions_dups[script_func].Contains(file)) // don't add the same file to list. Sometimes the same function call is also a comment.
190 | {
191 | script_functions_dups[script_func].Add(file);
192 | }
193 | }
194 | else
195 | {
196 | if (!script_functions_dups[script_func].Contains(file)) // don't add the same file to list. Sometimes the same function call is also a comment.
197 | {
198 | script_functions_dups[script_func].Add(file);
199 | }
200 | }
201 | }
202 | script_functions[script_func] = file;
203 | }
204 | else
205 | {
206 | Console.WriteLine("ERR '{0}' found at index {1}.", m.Value.Trim(), m.Index);
207 | }
208 | }
209 | }
210 |
211 | //remove "duplicates" (with only 1 file entry). TODO check if this can be removed since the regex does not find commented functions anymore
212 | var dups = new Dictionary>();
213 | foreach (var item in script_functions_dups)
214 | {
215 | if (item.Value.Count > 1)
216 | dups[item.Key] = item.Value;
217 | }
218 | return dups;
219 | }
220 |
221 |
222 | //Do not format this code string
223 | public string GetDllCheckCode(string path)
224 | {
225 | path = path.Replace(@"\\", @"\");
226 | return string.Format(
227 | @"import sys, os, glob, json
228 | import vapoursynth as vs
229 | core = vs.core;
230 | path = path = r'{0}'
231 | plugin_dir = glob.glob(path + '/*.dll')
232 | error = []
233 | for dll in plugin_dir:
234 | try:
235 | core.std.LoadPlugin(path = dll)
236 | core.std.LoadPlugin(path = dll)
237 | except Exception as e:
238 | error.append([os.path.basename(dll), str(e)])
239 | continue
240 | print(json.dumps(error))
241 | ", path);
242 | }
243 |
244 | public string run_python(string cmd)
245 | {
246 | ProcessStartInfo start = new ProcessStartInfo();
247 | start.FileName = python_bin;
248 | start.Arguments = string.Format("-c \"{0}\"", cmd);
249 | start.UseShellExecute = false;// Do not use OS shell
250 | start.CreateNoWindow = true; // We don't need new window
251 | start.RedirectStandardOutput = true;// Any output, generated by application will be redirected back
252 | start.RedirectStandardError = false; // Any error in standard output will be redirected back (for example exceptions)
253 | using (Process process = Process.Start(start))
254 | {
255 | using (StreamReader reader = process.StandardOutput)
256 | {
257 | string result = reader.ReadToEnd();
258 | return result;
259 | }
260 | }
261 | }
262 |
263 | public string run_listpedeps(string file)
264 | {
265 | ProcessStartInfo start = new ProcessStartInfo();
266 | start.FileName = "listpedeps.exe";
267 | start.Arguments = string.Format("\"{0}\"", file);
268 | start.UseShellExecute = false;// Do not use OS shell
269 | start.CreateNoWindow = true; // We don't need new window
270 | start.RedirectStandardOutput = true;// Any output, generated by application will be redirected back
271 | start.RedirectStandardError = false; // Any error in standard output will be redirected back (for example exceptions)
272 | try
273 | {
274 | using (Process process = Process.Start(start))
275 | {
276 | using (StreamReader reader = process.StandardOutput)
277 | {
278 | string result = reader.ReadToEnd();
279 | return result;
280 | }
281 | }
282 | } catch
283 | {
284 | return null;
285 | }
286 |
287 | }
288 |
289 | public string OsVersionToName(string version)
290 | {
291 | if (os_versions.ContainsKey(version))
292 | {
293 | return os_versions[version];
294 | }
295 | return "OS Name unknown";
296 | }
297 |
298 | public string ArchToSimpleArch(string arch)
299 | {
300 | if (arch == "x86")
301 | {
302 | return "32 Bit";
303 | }
304 | if (arch == "x86_64")
305 | {
306 | return "64 Bit";
307 | }
308 | return arch;
309 | }
310 |
311 | public class Depends
312 | {
313 | public string file;
314 | public string architecture;
315 | public string machine_name;
316 | public string subsystem;
317 | public string minimum_windows_version;
318 | public string minimum_windows_osname;
319 | public List Imports = new List();
320 | public List Exports = new List();
321 | public bool IsVapourSynthPlugin = false;
322 | public bool IsAvisynthPlugin = false;
323 | }
324 | }
325 | }
326 |
--------------------------------------------------------------------------------
/VSRepoGUI/FodyWeavers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/VSRepoGUI/FodyWeavers.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Used to control if the On_PropertyName_Changed feature is enabled.
12 |
13 |
14 |
15 |
16 | Used to control if the Dependent properties feature is enabled.
17 |
18 |
19 |
20 |
21 | Used to control if the IsChanged property feature is enabled.
22 |
23 |
24 |
25 |
26 | Used to change the name of the method that fires the notify event. This is a string that accepts multiple values in a comma separated form.
27 |
28 |
29 |
30 |
31 | Used to control if equality checks should be inserted. If false, equality checking will be disabled for the project.
32 |
33 |
34 |
35 |
36 | Used to control if equality checks should use the Equals method resolved from the base class.
37 |
38 |
39 |
40 |
41 | Used to control if equality checks should use the static Equals method resolved from the base class.
42 |
43 |
44 |
45 |
46 | Used to turn off build warnings from this weaver.
47 |
48 |
49 |
50 |
51 | Used to turn off build warnings about mismatched On_PropertyName_Changed methods.
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks
62 |
63 |
64 |
65 |
66 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.
67 |
68 |
69 |
70 |
71 | A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks
72 |
73 |
74 |
75 |
76 | A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.
77 |
78 |
79 |
80 |
81 | A list of unmanaged 32 bit assembly names to include, delimited with line breaks.
82 |
83 |
84 |
85 |
86 | A list of unmanaged 64 bit assembly names to include, delimited with line breaks.
87 |
88 |
89 |
90 |
91 | The order of preloaded assemblies, delimited with line breaks.
92 |
93 |
94 |
95 |
96 |
97 | 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.
98 |
99 |
100 |
101 |
102 | Controls if .pdbs for reference assemblies are also embedded.
103 |
104 |
105 |
106 |
107 | Controls if runtime assemblies are also embedded.
108 |
109 |
110 |
111 |
112 | Controls whether the runtime assemblies are embedded with their full path or only with their assembly name.
113 |
114 |
115 |
116 |
117 | Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.
118 |
119 |
120 |
121 |
122 | As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.
123 |
124 |
125 |
126 |
127 | 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.
128 |
129 |
130 |
131 |
132 | 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.
133 |
134 |
135 |
136 |
137 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with |
138 |
139 |
140 |
141 |
142 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |.
143 |
144 |
145 |
146 |
147 | A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with |
148 |
149 |
150 |
151 |
152 | A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with |.
153 |
154 |
155 |
156 |
157 | A list of unmanaged 32 bit assembly names to include, delimited with |.
158 |
159 |
160 |
161 |
162 | A list of unmanaged 64 bit assembly names to include, delimited with |.
163 |
164 |
165 |
166 |
167 | The order of preloaded assemblies, delimited with |.
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 | 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.
176 |
177 |
178 |
179 |
180 | A comma-separated list of error codes that can be safely ignored in assembly verification.
181 |
182 |
183 |
184 |
185 | 'false' to turn off automatic generation of the XML Schema file.
186 |
187 |
188 |
189 |
190 |
--------------------------------------------------------------------------------
/VSRepoGUI/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | Website
44 | Github
45 | Doom9
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 | Paths
75 | PLUGINS
76 | SCRIPTS
77 | VS Database
78 | VSRepo Doom9
79 | AVSRepo Doom9
80 | About
81 |
82 |
83 |
84 |
85 |
86 |
87 |
91 |
92 |
93 |
94 | Hide Installed
95 | Win64
96 |
97 |
98 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 | Loading...
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
--------------------------------------------------------------------------------
/VSRepoGUI/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using PropertyChanged;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.ComponentModel;
5 | using System.Diagnostics;
6 | using System.IO;
7 | using System.Linq;
8 | using System.Security.AccessControl;
9 | using System.Security.Principal;
10 | using System.Threading.Tasks;
11 | using System.Windows;
12 | using System.Windows.Controls;
13 | using System.Windows.Documents;
14 | using System.Windows.Media;
15 |
16 | namespace VSRepoGUI
17 | {
18 | ///
19 | /// MainWindow.xaml
20 | ///
21 | ///
22 | public partial class MainWindow : Window, INotifyPropertyChanged
23 | {
24 | public string vspackages_file; // = @"..\vspackages.json";
25 | public VsPlugins Plugins { get; set; }
26 | public Dictionary plugins_dll_parents = new Dictionary();
27 | public VsApi vsrepo;
28 | public VsRegistryHelper vsregistry = new VsRegistryHelper();
29 | public string CurrentPluginPath { get; set; }
30 | public string CurrentScriptPath { get; set; }
31 | public bool IsNotWorking { get; set; } = true;
32 | public bool PortableMode { get; set; } = false;
33 | public event PropertyChangedEventHandler PropertyChanged;
34 | public bool HideInstalled { get; set; }
35 | public string consolestd { get; set; }
36 | public List consolestdL = new List();
37 |
38 | public string version = "v0.9.8";
39 | public string AppTitle { get; set; }
40 | public bool Win64 { get; set; }
41 |
42 |
43 | public class VsPlugins : INotifyPropertyChanged
44 | {
45 | public event PropertyChangedEventHandler PropertyChanged;
46 |
47 | public Package[] UpdateAvailable { get; set; }
48 | public Package[] Installed { get; set; }
49 | public Package[] NotInstalled { get; set; }
50 | public Package[] Unknown { get; set; }
51 |
52 | [AlsoNotifyFor("All")]
53 | public Package[] Full { get; set; }
54 |
55 | // Quick and dirty props for Tab Header (stringFormat doesn't work for Header)
56 | public string TabInstalled { get; set; }
57 | public string TabNotInstalled { get; set; }
58 | public string TabUpdateAvailable { get; set; }
59 | public string TabInstalledUnknown { get; set; }
60 | public string TabAll { get; set; }
61 |
62 | private Package[] _all;
63 | public Package[] All
64 | {
65 | get { return _all; }
66 | set
67 | {
68 | UpdateAvailable = Array.FindAll(value, c => c.Status == VsApi.PluginStatus.UpdateAvailable);
69 | Installed = Array.FindAll(value, c => c.Status == VsApi.PluginStatus.Installed || c.Status == VsApi.PluginStatus.UpdateAvailable);
70 | NotInstalled = Array.FindAll(value, c => c.Status == VsApi.PluginStatus.NotInstalled);
71 | Unknown = Array.FindAll(value, c => c.Status == VsApi.PluginStatus.InstalledUnknown);
72 | //Full = value;
73 | _all = value;
74 |
75 | TabUpdateAvailable = string.Format("Updates ({0})", UpdateAvailable.Count());
76 | TabInstalled = string.Format("Installed ({0})", Installed.Count());
77 | TabNotInstalled = string.Format("Not Installed ({0})", NotInstalled.Count());
78 | TabInstalledUnknown = string.Format("Unknown Version ({0})", Unknown.Count());
79 | TabAll = string.Format("Full List ({0})", _all.Count());
80 | }
81 | }
82 | }
83 |
84 | public MainWindow()
85 | {
86 | vsrepo = new VsApi();
87 | Plugins = new VsPlugins();
88 | vsregistry.ReadAllVsRegistryInfos();
89 |
90 | //High dpi 288 fix so it won't cut off the title bar on start
91 | if (Height > SystemParameters.WorkArea.Height)
92 | {
93 | Height = SystemParameters.WorkArea.Height;
94 | Top = 2;
95 | }
96 |
97 |
98 | InitializeComponent();
99 |
100 | // init Jot Settings Tracker
101 | SettingsService.Tracker.Track(this);
102 | //showedFirstTimeSettingsAvs = false;
103 |
104 |
105 | AddChatter(vsrepo);
106 |
107 | AppTitle = "VSRepoGUI - A simple plugin manager for VapourSynth | " + version;
108 | InitVapoursynth();
109 |
110 | Win64 = Environment.Is64BitOperatingSystem; // triggers checkbox changed event
111 | }
112 |
113 |
114 | private void InitVapoursynth()
115 | {
116 | //TabablzControl doesn't support hiding or collapsing Tabitems. Hide "Settings" (last) tab if we are in vapoursynth mode
117 | TabablzControl.Items.RemoveAt(TabablzControl.Items.Count - 1);
118 |
119 | var settings = new PortableSettings().LoadLocalFile();
120 |
121 | var args = Environment.GetCommandLineArgs();
122 | if (args.Length > 1)
123 | {
124 | vsrepo.python_bin = args[1];
125 | } else
126 | {
127 | //check if python is in PATH first
128 | if (IsPythonCallable())
129 | {
130 | vsrepo.python_bin = GetPythonLocation("python.exe");
131 | _ = vsregistry.SetCurrentVsInstallation(vsrepo.python_bin);
132 | }
133 | else //is not in PATH
134 | {
135 | // Get PythonPath from VapourSynth registry and test if it's callable
136 | //var pybin = GetPythonLocation(vsregistry.GetAvailablePythonPath());
137 | var pybin = vsregistry.GetAvailablePythonPath() + "\\python.exe";
138 |
139 | if (!String.IsNullOrEmpty(pybin) && IsPythonCallable(pybin))
140 | {
141 | vsrepo.python_bin = pybin;
142 | } else
143 | {
144 | MessageBox.Show(@"It seems that Python is not installed or not set in your PATH variable. Add Python to PATH or call like this: " + Environment.NewLine + @"'VSRepoGui.exe path\to\python.exe'");
145 | System.Environment.Exit(1);
146 | }
147 |
148 | }
149 | }
150 |
151 | if(settings is null)
152 | {
153 | if(vsregistry.Registry.Count() == 0)
154 | {
155 | // MessageBox.Show("Can not find your VapourSynth installation. You can create a vsrepogui.json file for portable mode.");
156 | MessageBox.Show("Can not find your VapourSynth installation(s).");
157 | System.Environment.Exit(1);
158 | }
159 |
160 | var vsrepo_file = vsregistry.GetCurrentRegPath() + "\\vsrepo\\vsrepo.py";
161 | Console.WriteLine("vsrepo_file: " + vsrepo_file);
162 |
163 | if (File.Exists(vsrepo_file))
164 | {
165 | vsrepo.SetVsrepoPath(vsrepo_file);
166 | if (!File.Exists(vsrepo_file + "\\vspackages3.json"))
167 | {
168 | vsrepo.Update(); // run update here first to avoid issues with "vsrepo path"
169 | }
170 | }
171 | else
172 | {
173 | MessageBox.Show("Found VS installation in " + vsregistry.GetCurrentRegPath() + " but no vsrepo.py file in " + vsrepo_file + ". Make sure you have at least version R55 of VapourSynth installed.");
174 | System.Environment.Exit(1);
175 | }
176 | AppIsWorking(true);
177 | vsrepo.SetArch(Environment.Is64BitOperatingSystem);
178 | //Trigger GetPaths for 32/64 bit, they are cached in VsApi class anyway
179 | try
180 | {
181 | _ = vsrepo.GetPaths(true).Definitions; _ = vsrepo.GetPaths(false).Definitions;
182 | }
183 | catch
184 | {
185 | MessageBox.Show("GetPaths() failed. Could be a missing/broken vspackages3.json.");
186 | System.Environment.Exit(1);
187 | }
188 |
189 | vspackages_file = vsrepo.GetPaths(Environment.Is64BitOperatingSystem).Definitions;
190 | //Win64 = Environment.Is64BitOperatingSystem;
191 | Console.WriteLine("vspackages_file: " + vsrepo_file);
192 | }
193 | else // Portable mode, valid vsrepogui.json found
194 | {
195 | LabelPortable.Visibility = Visibility.Visible;
196 | PortableMode = true;
197 | vsrepo.SetPortableMode(PortableMode);
198 | vsrepo.SetVsrepoPath(settings.Bin);
199 | vspackages_file = Path.GetDirectoryName(settings.Bin) + "\\vspackages3.json";
200 |
201 | // Set paths manually and DONT trigger Win64 onPropertyChanged yet
202 | vsrepo.SetPaths(true, new Paths() { Binaries = settings.Win64.Binaries, Scripts = settings.Win64.Scripts, Definitions = vspackages_file });
203 | vsrepo.SetPaths(false, new Paths() { Binaries = settings.Win32.Binaries, Scripts = settings.Win32.Scripts, Definitions = vspackages_file });
204 |
205 | // Triggering Win64 is now safe
206 | //Win64 = Environment.Is64BitOperatingSystem;
207 | }
208 |
209 | try
210 | {
211 | Plugins.All = LoadLocalVspackage();
212 | vsrepo.Update();
213 | }
214 | catch
215 | {
216 | MessageBox.Show("Could not read (or download) vspackages.json.");
217 | System.Environment.Exit(1);
218 | }
219 |
220 | }
221 |
222 | private string GetPythonLocation(string python_bin)
223 | {
224 | string cmd = "import sys; print(sys.executable)";
225 | ProcessStartInfo start = new ProcessStartInfo();
226 | start.FileName = python_bin;
227 | start.Arguments = string.Format("-c \"{0}\"", cmd);
228 | start.UseShellExecute = false;// Do not use OS shell
229 | start.CreateNoWindow = true; // We don't need new window
230 | start.RedirectStandardOutput = true;// Any output, generated by application will be redirected back
231 | start.RedirectStandardError = false; // Any error in standard output will be redirected back (for example exceptions)
232 | using (Process process = Process.Start(start))
233 | {
234 | using (StreamReader reader = process.StandardOutput)
235 | {
236 | string result = reader.ReadToEnd();
237 | return result.Trim();
238 | }
239 | }
240 | }
241 |
242 | private bool IsPythonCallable(string pypath = "python.exe")
243 | {
244 | try
245 | {
246 | Process p = new Process();
247 | p.StartInfo.FileName = pypath;
248 | p.StartInfo.Arguments = "-V";
249 | p.StartInfo.UseShellExecute = false;
250 | p.StartInfo.CreateNoWindow = true;
251 | p.Start();
252 | p.WaitForExit();
253 | if (p.ExitCode == 0)
254 | return true;
255 | else
256 | return false;
257 | }
258 | catch
259 | {
260 | return false;
261 | }
262 | }
263 |
264 |
265 | public void AddChatter(VsApi chatter)
266 | {
267 | //vsrepo.Add(chatter);
268 | chatter.PropertyChanged += chatter_PropertyChanged;
269 | }
270 |
271 | private void chatter_PropertyChanged(object sender, PropertyChangedEventArgs e)
272 | {
273 | Console.WriteLine("A property has changed: " + e.PropertyName);
274 | var s = sender as VsApi;
275 | Console.WriteLine("||| " + s.consolestd);
276 | consolestd += s.consolestd + "\n";
277 | //consolestd.Add(s.consolestd);
278 | //ConsoleBox.Text = String.Join(Environment.NewLine, consolestd);
279 | //ConsoleBox.Text = s.consolestd + "\n";
280 | }
281 |
282 | private Package[] LoadLocalVspackage()
283 | {
284 | if (!File.Exists(vspackages_file))
285 | {
286 | vsrepo.Update();
287 | }
288 |
289 | //Load vspackages.json
290 | var jsonString = File.ReadAllText(vspackages_file);
291 | var packages = Vspackage.FromJson(jsonString);
292 | //var packages = JsonConvert.DeserializeObject(jsonString);
293 | //return (packages.FileFormat, packages.Packages);
294 | return packages.Packages;
295 | }
296 |
297 | public void AppIsWorking(bool status)
298 | {
299 | Progressbar.IsIndeterminate = status;
300 | IsNotWorking = !status;
301 | }
302 |
303 |
304 | public void FilterPlugins(Package[] plugins)
305 | {
306 | if(plugins != null)
307 | {
308 | string search = searchBox.Text.ToLower();
309 | if (search.Length > 0 && search != "search")
310 | {
311 | plugins = Array.FindAll(plugins, c => c.Name.ToLower().Contains(search) || (c.Namespace?.ToLower().Contains(search) ?? c.Modulename.ToLower().Contains(search)));
312 | }
313 | if (HideInstalled)
314 | {
315 | plugins = Array.FindAll(plugins, c => c.Status != VsApi.PluginStatus.Installed);
316 | }
317 |
318 | if(search.Length == 0)
319 | {
320 | Plugins.All = Plugins.Full;
321 | } else
322 | {
323 | Plugins.All = plugins;
324 | }
325 | dataGrid.Columns[0].SortDirection = ListSortDirection.Ascending;
326 | dataGridAvailable.Columns[0].SortDirection = ListSortDirection.Ascending;
327 | dataGridUnknown.Columns[0].SortDirection = ListSortDirection.Ascending;
328 | dataGridNotInstalled.Columns[0].SortDirection = ListSortDirection.Ascending;
329 | dataGridAll.Columns[0].SortDirection = ListSortDirection.Ascending;
330 | }
331 | }
332 |
333 | private async Task ReloadPluginsAsync()
334 | {
335 | var _plugins = LoadLocalVspackage();
336 | if(Win64)
337 | _plugins = Array.FindAll(_plugins, c => c.Releases[0].Win64 != null || c.Releases[0].Script != null || c.Releases[0].Wheel != null);
338 | else
339 | _plugins = Array.FindAll(_plugins, c => c.Releases[0].Win32 != null || c.Releases[0].Script != null || c.Releases[0].Wheel != null);
340 |
341 | var plugins_installed = await vsrepo.GetInstalledAsync();
342 |
343 | // Set Plugin status (installed, not installed, update available etc.)
344 | foreach (var plugin in plugins_installed)
345 | {
346 | var index = Array.FindIndex(_plugins, row => row.Identifier == plugin.Key);
347 | if (index >= 0) //-1 if not found
348 | {
349 | _plugins[index].Status = plugin.Value.Value;
350 | _plugins[index].Releases[0].VersionLocal = plugin.Value.Key;
351 | }
352 | }
353 | Plugins.Full = _plugins;
354 | FilterPlugins(Plugins.Full);
355 | }
356 |
357 | private async void Button_upgrade_all(object sender, RoutedEventArgs e)
358 | {
359 | AppIsWorking(true);
360 | await vsrepo.UpgradeAllAsync();
361 | await ReloadPluginsAsync();
362 | AppIsWorking(false);
363 | }
364 |
365 |
366 | private async void Button_Install(object sender, RoutedEventArgs e)
367 | {
368 | AppIsWorking(true);
369 | var button = sender as Button;
370 |
371 | var plugin_status = ((Package)button.DataContext).Status;
372 | string plugin = ((Package)button.DataContext).Namespace ?? ((Package)button.DataContext).Modulename;
373 | consolestd = "";
374 | consolestdL.Clear();
375 | if(HasWriteAccessToFolder(CurrentPluginPath))
376 | {
377 | switch (plugin_status)
378 | {
379 | case VsApi.PluginStatus.Installed:
380 | if (MessageBox.Show("Uninstall " + ((Package)button.DataContext).Name + "?", "Uninstall?", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
381 | {
382 | await vsrepo.UninstallAsync(plugin);
383 | }
384 | break;
385 | case VsApi.PluginStatus.InstalledUnknown:
386 | if (MessageBox.Show("Your local file (with unknown version) has the same name as " + ((Package)button.DataContext).Name + " and will be overwritten, proceed?", "Force Upgrade?", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
387 | {
388 | await vsrepo.UpgradeAsync(plugin, force: true);
389 | }
390 | break;
391 | case VsApi.PluginStatus.NotInstalled:
392 | await vsrepo.InstallAsync(plugin);
393 | break;
394 | case VsApi.PluginStatus.UpdateAvailable:
395 | await vsrepo.UpgradeAsync(plugin);
396 | break;
397 | }
398 |
399 |
400 |
401 | ConsoleBox.Focus();
402 | ConsoleBox.CaretIndex = ConsoleBox.Text.Length;
403 | ConsoleBox.ScrollToEnd();
404 |
405 | await ReloadPluginsAsync();
406 | } else
407 | {
408 | MessageBox.Show("Can't write to plugins folder. Restart program as admin.");
409 | }
410 | AppIsWorking(false);
411 | }
412 |
413 | private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
414 | {
415 | FilterPlugins(Plugins.Full);
416 | }
417 |
418 | private void HideInstalled_Checked(object sender, RoutedEventArgs e)
419 | {
420 | FilterPlugins(Plugins.Full);
421 | }
422 |
423 | private void HideInstalled_Unchecked(object sender, RoutedEventArgs e)
424 | {
425 | FilterPlugins(Plugins.Full);
426 | }
427 |
428 | private void TextBox_GotFocus(object sender, RoutedEventArgs e)
429 | {
430 | var textbox = sender as TextBox;
431 | textbox.Clear();
432 | }
433 |
434 | private void CheckBox_Win64_Checked(object sender, RoutedEventArgs e)
435 | {
436 | CheckBoxToggleHelper(sender as CheckBox);
437 | }
438 |
439 | private void CheckBox_Win64_Unchecked(object sender, RoutedEventArgs e)
440 | {
441 | CheckBoxToggleHelper(sender as CheckBox);
442 | }
443 |
444 | private async void CheckBoxToggleHelper(CheckBox c)
445 | {
446 | AppIsWorking(true);
447 | Win64 = c.IsChecked.Value;
448 | vsrepo.SetArch(Win64);
449 | CurrentPluginPath = vsrepo.paths[Win64].Binaries;
450 | CurrentScriptPath = vsrepo.paths[Win64].Scripts;
451 | await ReloadPluginsAsync();
452 | AppIsWorking(false);
453 | }
454 |
455 | // TODO check https://docs.microsoft.com/de-de/dotnet/api/system.io.filestream.canwrite?view=netframework-4.8
456 | public static bool HasWriteAccessToFolder(string FilePath)
457 | {
458 | try
459 | {
460 | FileSystemSecurity security;
461 | if (File.Exists(FilePath))
462 | {
463 | security = File.GetAccessControl(FilePath);
464 | }
465 | else
466 | {
467 | security = Directory.GetAccessControl(Path.GetDirectoryName(FilePath));
468 | }
469 | var rules = security.GetAccessRules(true, true, typeof(NTAccount));
470 |
471 | var currentuser = new WindowsPrincipal(WindowsIdentity.GetCurrent());
472 | bool result = false;
473 | foreach (FileSystemAccessRule rule in rules)
474 | {
475 | if (0 == (rule.FileSystemRights &
476 | (FileSystemRights.WriteData | FileSystemRights.Write)))
477 | {
478 | continue;
479 | }
480 |
481 | if (rule.IdentityReference.Value.StartsWith("S-1-"))
482 | {
483 | var sid = new SecurityIdentifier(rule.IdentityReference.Value);
484 | if (!currentuser.IsInRole(sid))
485 | {
486 | continue;
487 | }
488 | }
489 | else
490 | {
491 | if (!currentuser.IsInRole(rule.IdentityReference.Value))
492 | {
493 | continue;
494 | }
495 | }
496 |
497 | if (rule.AccessControlType == AccessControlType.Deny)
498 | return false;
499 | if (rule.AccessControlType == AccessControlType.Allow)
500 | result = true;
501 | }
502 | return result;
503 | }
504 | catch
505 | {
506 | return false;
507 | }
508 | }
509 |
510 |
511 | private void Hyperlink_Click(object sender, RoutedEventArgs e)
512 | {
513 | MessageBox.Show("Hello friend");
514 | }
515 | private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
516 | {
517 | if (e.Uri.IsAbsoluteUri) {
518 | Process.Start(e.Uri.AbsoluteUri);
519 | }
520 | }
521 |
522 | private void Hyperlink_Click_1(object sender, RoutedEventArgs e)
523 | {
524 | MessageBox.Show("Definitions: " + vsrepo.GetPaths(Win64).Definitions + "\nScripts: " + vsrepo.GetPaths(Win64).Scripts + "\nBinaries: " + vsrepo.GetPaths(Win64).Binaries);
525 | }
526 |
527 | private void Hyperlink_open(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
528 | {
529 | if(e.Uri.IsAbsoluteUri) {
530 | Process.Start(e.Uri.AbsoluteUri);
531 | }
532 | }
533 |
534 | private void Hyperlink_namespace(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
535 | {
536 | var package = (Package)(sender as Hyperlink).DataContext;
537 | Process.Start("https://github.com/vapoursynth/vsrepo/tree/master/local/" + (package.Namespace ?? package.Modulename) + ".json");
538 |
539 | }
540 |
541 | private void Hyperlink_Click_Plugins(object sender, RoutedEventArgs e)
542 | {
543 | Process.Start("explorer.exe", vsrepo.GetPaths(Win64).Binaries);
544 | }
545 |
546 | private void Hyperlink_Click_Scripts(object sender, RoutedEventArgs e)
547 | {
548 | Process.Start("explorer.exe", vsrepo.GetPaths(Win64).Scripts);
549 | }
550 |
551 | private void Hyperlink_Explorer(object sender, RoutedEventArgs e)
552 | {
553 | var hyperlink = sender as Hyperlink;
554 | Process.Start("explorer.exe", hyperlink.NavigateUri.ToString());
555 | }
556 |
557 | private void Hyperlink_Click_about(object sender, RoutedEventArgs e)
558 | {
559 | MessageBox.Show("Version " + version);
560 | }
561 |
562 |
563 | ///
564 | /// Print a "block" of plugins, helper function
565 | ///
566 | ///
567 | ///
568 | ///
569 | ///
570 | ///
571 | private static void DiagPrintHelper(Dictionary> plugins, string id, string errmsg, Paragraph tb, bool fullpath = false)
572 | {
573 | if (plugins[id].Count() > 0)
574 | {
575 | //tb.Text += errmsg;
576 | tb.Inlines.Add(new Run(errmsg) { FontSize = 14 });
577 | tb.Inlines.Add(new Run("------------------------------------------------------------\n") { Foreground = Brushes.SlateBlue });
578 | foreach (var p in plugins[id])
579 | {
580 | if(fullpath)
581 | {
582 | tb.Inlines.Add(" ");
583 | if (Path.IsPathRooted(p))
584 | tb.Inlines.Add(new Run(Path.GetDirectoryName(p) + @"\") { Foreground = Brushes.Silver });
585 | tb.Inlines.Add(Path.GetFileName(p) + "\n");
586 | }
587 | else
588 | {
589 | tb.Inlines.Add(" " + Path.GetFileName(p) + "\n");
590 | }
591 | }
592 | }
593 | }
594 |
595 |
596 | private async void TabablzControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
597 | {
598 |
599 | // ##### Vapoursynth diagnose #####
600 |
601 | if (DiagnoseTab.IsSelected)
602 | {
603 | // Textoutput controls init
604 | RichTextBox richtextbox = new RichTextBox();
605 | FlowDocument flowdoc = new FlowDocument();
606 | Paragraph tb = new Paragraph();
607 |
608 | richtextbox.IsDocumentEnabled = true;
609 | richtextbox.IsReadOnly = true;
610 | tb.FontFamily = new FontFamily("Lucida Console");
611 | tb.Padding = new Thickness(8);
612 |
613 | flowdoc.Blocks.Add(tb);
614 | richtextbox.Document = flowdoc;
615 | //tb.TextWrapping = TextWrapping.Wrap;
616 |
617 |
618 | // http://www.vapoursynth.com/doc/autoloading.html#windows
619 | // 1. \VapourSynth\plugins64
620 | // 2. \core64\plugins
621 | // 3. \plugins64
622 | // vsrepo returns (always?) the path of the AppData folder no 1.
623 | // User Plugins in core64 are bad.
624 |
625 | AppIsWorking(true);
626 | bool current_vs_installation_works = true;
627 | var diag = new Diagnose(vsrepo.python_bin);
628 |
629 | var version = await diag.GetVapoursynthVersion();
630 | var vs_dll = await diag.GetLoadedVapoursynthDll();
631 |
632 | if (String.IsNullOrWhiteSpace(version))
633 | current_vs_installation_works = false;
634 |
635 | Dictionary> plugins = await diag.CheckPluginsAsync(vsrepo.GetPaths(Win64).Binaries);
636 | if (!PortableMode)
637 | {
638 | if (current_vs_installation_works)
639 | {
640 | Dictionary> plugins64folder = await diag.CheckPluginsAsync(vsregistry.GetCurrentRegPluginsPath());
641 |
642 | //Check for duplicate dll files in both folders: appdata\plugins and vapoursynth\plugins
643 | var p1 = plugins.Values.SelectMany(x => x.Select(p => Path.GetFileName(p))).ToList();
644 | var p2 = plugins64folder.Values.SelectMany(x => x.Select(p => Path.GetFileName(p))).ToList();
645 |
646 |
647 | //Merge appdata\plugins and vapoursynth\plugins
648 | for (int i = 0; i < plugins.Count; i++)
649 | {
650 | plugins[plugins.ElementAt(i).Key] = plugins[plugins.ElementAt(i).Key].Concat(plugins64folder[plugins.ElementAt(i).Key]).ToList();
651 | }
652 |
653 | plugins["duplicate_dlls"] = p1.Intersect(p2).ToList();
654 | }
655 | else
656 | {
657 | // plugins["duplicate_dlls"] = new List();
658 | }
659 |
660 | }
661 | else
662 | {
663 | plugins["duplicate_dlls"] = new List();
664 | }
665 |
666 |
667 | var SystemInfo = new SystemInfo();
668 |
669 | tb.Inlines.Add(@"/!\ Only Plugins are tested, no Scripts /!\");
670 | if (current_vs_installation_works)
671 | tb.Inlines.Add("\n" + version);
672 | else
673 | tb.Inlines.Add(new Run("\n\nImporting VapourSynth in python failed! \n") { FontSize = 15, FontWeight = FontWeights.Bold, Foreground = Brushes.Red });
674 | tb.Inlines.Add("\nOS: " + SystemInfo.OS);
675 | tb.Inlines.Add("\n64Bit OS: " + (SystemInfo.Is64Bit ? "Yes" : "No"));
676 | if(SystemInfo.HasMultipleGpus)
677 | {
678 | int i = 0;
679 | foreach (GPU gpu in SystemInfo.Gpus)
680 | {
681 | tb.Inlines.Add("\nGPU"+ (i++) +": " + gpu.Description);
682 | }
683 | }
684 | else
685 | {
686 | tb.Inlines.Add("\nGPU: " + SystemInfo.Gpu.Description);
687 | }
688 | if (SystemInfo.HasMultipleCpus)
689 | {
690 | int i = 0;
691 | foreach (CPU cpu in SystemInfo.Cpus)
692 | {
693 | tb.Inlines.Add("\nCPU" + (i++) + ": " + cpu.Name);
694 | }
695 | tb.Inlines.Add("\nTotal CPU Cores: " + SystemInfo.TotalCpuCores);
696 | tb.Inlines.Add("\nTotal Logical Processors: " + SystemInfo.TotalLogicalProcessors);
697 | }
698 | else
699 | {
700 | tb.Inlines.Add("\nCPU: " + SystemInfo.Cpu.Name);
701 | tb.Inlines.Add("\nCPU Cores: " + SystemInfo.TotalCpuCores);
702 | tb.Inlines.Add("\nLogical Processors: " + SystemInfo.TotalLogicalProcessors);
703 | }
704 |
705 | tb.Inlines.Add("\nRAM: " + SystemInfo.Ram.Size + " GB");
706 |
707 | tb.Inlines.Add(new Run("\n\nPython location: ") { FontSize = 12, FontWeight = FontWeights.Bold });
708 | tb.Inlines.Add(await diag.GetPythonLocation()); //vsrepo.python_bin
709 |
710 |
711 | tb.Inlines.Add(new Run("\nLoaded VapourSynth dll: ") { FontSize = 12, FontWeight = FontWeights.Bold });
712 | if (vs_dll != null)
713 | tb.Inlines.Add(vs_dll + "\n");
714 | else
715 | tb.Inlines.Add(" - \n");
716 |
717 | // Show VS installations found in the registry
718 | if (vsregistry.Registry.ContainsKey("local64"))
719 | {
720 | tb.Inlines.Add("\nFound an installation in ");
721 | tb.Inlines.Add(new Run(@"HKEY_LOCAL_MACHINE\" + vsregistry.Registry["local64"].RegPath) { Foreground = Brushes.Blue });
722 | tb.Inlines.Add("\n - Path: " + vsregistry.Registry["local64"].Path);
723 | tb.Inlines.Add("\n - PythonPath: " + vsregistry.Registry["local64"].PythonPath);
724 | tb.Inlines.Add("\n - Version: " + vsregistry.Registry["local64"].Version);
725 | }
726 | if (vsregistry.Registry.ContainsKey("local32"))
727 | {
728 | tb.Inlines.Add("\nFound an installation in ");
729 | tb.Inlines.Add(new Run(@"HKEY_LOCAL_MACHINE\" + vsregistry.Registry["local32"].RegPath) { Foreground = Brushes.Blue });
730 | tb.Inlines.Add("\n - Path: " + vsregistry.Registry["local32"].Path);
731 | tb.Inlines.Add("\n - PythonPath: " + vsregistry.Registry["local32"].PythonPath);
732 | tb.Inlines.Add("\n - Version: " + vsregistry.Registry["local32"].Version);
733 | }
734 | if (vsregistry.Registry.ContainsKey("user64"))
735 | {
736 | tb.Inlines.Add("\nFound an installation in ");
737 | tb.Inlines.Add(new Run(@"HKEY_CURRENT_USER\" + vsregistry.Registry["user64"].RegPath) { Foreground = Brushes.Blue });
738 | tb.Inlines.Add("\n - Path: " + vsregistry.Registry["user64"].Path);
739 | tb.Inlines.Add("\n - PythonPath: " + vsregistry.Registry["user64"].PythonPath);
740 | tb.Inlines.Add("\n - Version: " + vsregistry.Registry["user64"].Version);
741 | }
742 | if (vsregistry.Registry.ContainsKey("user32"))
743 | {
744 | tb.Inlines.Add("\nFound an installation in ");
745 | tb.Inlines.Add(new Run(@"HKEY_CURRENT_USER\" + vsregistry.Registry["user32"].RegPath) { Foreground = Brushes.Blue });
746 | tb.Inlines.Add("\n - Path: " + vsregistry.Registry["user32"].Path);
747 | tb.Inlines.Add("\n - PythonPath: " + vsregistry.Registry["user32"].PythonPath);
748 | tb.Inlines.Add("\n - Version: " + vsregistry.Registry["user32"].Version);
749 | }
750 |
751 |
752 | tb.Inlines.Add("\n\n============================================================\n");
753 |
754 | if (plugins != null)
755 | {
756 | //Mark plugins (dlls files) which are known to vsrepo
757 | Dictionary known_files = new Dictionary();
758 | int count_unident_dll = 0;
759 | foreach (var p in plugins["not_a_vsplugin"])
760 | {
761 | if (plugins_dll_parents.ContainsKey(Path.GetFileName(p)))
762 | known_files.Add(p, plugins_dll_parents[Path.GetFileName(p)]);
763 | else
764 | count_unident_dll++;
765 | }
766 |
767 |
768 | tb.Inlines.Add(new Run(string.Format("\nChecked Plugins: {0}, Notices: {1}, Errors: {2}\n\n",
769 | plugins.Values.SelectMany(x => x).Count(),
770 | //plugins["no_problems"].Count() + plugins["not_a_vsplugin"].Count() + plugins["missing_dependency"].Count() + plugins["wrong_arch"].Count() + plugins["others"].Count(),
771 | count_unident_dll + plugins["duplicate_dlls"].Count(),
772 | plugins["wrong_arch"].Count() + plugins["missing_dependency"].Count() + plugins["others"].Count() + plugins["namespace"].Count()))
773 | { Foreground = Brushes.DarkOrange });
774 |
775 | if (PortableMode)
776 | tb.Inlines.Add(string.Format("Plugin Path: {0}\n", vsrepo.GetPaths(Win64).Binaries));
777 | else
778 | {
779 | Hyperlink link1 = new Hyperlink();
780 | Hyperlink link2 = new Hyperlink();
781 | link1.RequestNavigate += new System.Windows.Navigation.RequestNavigateEventHandler(Hyperlink_Explorer);
782 | link2.RequestNavigate += new System.Windows.Navigation.RequestNavigateEventHandler(Hyperlink_Explorer);
783 | link1.IsEnabled = link2.IsEnabled = true;
784 | link1.Inlines.Add(vsrepo.GetPaths(Win64).Binaries);
785 | link2.Inlines.Add(vsregistry.GetCurrentRegPluginsPath());
786 | link1.NavigateUri = new Uri(vsrepo.GetPaths(Win64).Binaries);
787 | link2.NavigateUri = new Uri(vsregistry.GetCurrentRegPluginsPath());
788 |
789 | tb.Inlines.Add("Plugin Paths: \n\t • ");
790 | tb.Inlines.Add(link1);
791 | tb.Inlines.Add("\n\t • ");
792 | tb.Inlines.Add(link2);
793 | tb.Inlines.Add("\n");
794 | //tb.Inlines.Add(string.Format("Plugin Paths: \n\t{0}\n\t{1}\n", vsrepo.GetPaths(Win64).Binaries, vsregistry.GetCurrentRegPluginsPath()));
795 | }
796 |
797 |
798 | DiagPrintHelper(plugins, "wrong_arch", "\n\n🔥 Error 193 - You probably mixed 32/64 bit plugins: \n", tb, true);
799 |
800 | if (plugins["missing_dependency"].Count() > 0)
801 | {
802 | tb.Inlines.Add(new Run("\n\n🔥 Error 126 - A DLL dependency is probably missing: \n") { FontSize = 14 });
803 | tb.Inlines.Add(new Run("------------------------------------------------------------\n") { Foreground = Brushes.SlateBlue });
804 | bool hint_listpedeps = false;
805 | foreach (var p in plugins["missing_dependency"])
806 | {
807 | Diagnose.Depends file_dependencies = null;
808 |
809 | try
810 | {
811 | file_dependencies = await diag.GetDllDependencies(p);
812 | }
813 | catch
814 | {
815 | hint_listpedeps = true;
816 | }
817 |
818 | if (file_dependencies != null)
819 | {
820 | tb.Inlines.Add(" ");
821 | if (Path.IsPathRooted(p))
822 | tb.Inlines.Add(new Run(Path.GetDirectoryName(p) + @"\") { Foreground = Brushes.Silver });
823 | tb.Inlines.Add(Path.GetFileName(p) + "\n");
824 | tb.Inlines.Add(" \t requires following dependencies (one of these could be missing):\n\n");
825 |
826 | foreach (var dependency in file_dependencies.Imports)
827 | {
828 | tb.Inlines.Add(" \t - " + dependency + "\n");
829 | }
830 | tb.Inlines.Add("\n");
831 |
832 | tb.Inlines.Add(" \t Architecture is " + file_dependencies.architecture + " \n");
833 | tb.Inlines.Add(" \t Minimum OS version is " + file_dependencies.minimum_windows_version + " (" + file_dependencies.minimum_windows_osname + ") \n\n");
834 | }
835 | else
836 | {
837 | tb.Inlines.Add(" ");
838 | if (Path.IsPathRooted(p))
839 | tb.Inlines.Add(new Run(Path.GetDirectoryName(p) + @"\") { Foreground = Brushes.Silver });
840 | tb.Inlines.Add(Path.GetFileName(p) + "\n");
841 | }
842 | }
843 | if (hint_listpedeps)
844 | {
845 | tb.Inlines.Add("\nInstall listpedeps.exe via 'choco install pedeps'");
846 | tb.Inlines.Add("\nor copy listpedeps.exe next to vsrepogui.exe for detailed information about missing dependencies.");
847 | tb.Inlines.Add("\nDownload here: https://github.com/brechtsanders/pedeps/releases\n\n");
848 | }
849 | }
850 |
851 | DiagPrintHelper(plugins, "namespace", "\n\n🔥 Namespace already populated, therefore it failed to load: \n", tb, true);
852 | //DiagPrintHelper(plugins, "others", "\n\n🔥 Error unknown: \n", tb, true);
853 | if (plugins["others"].Count() > 0)
854 | {
855 | tb.Inlines.Add(new Run("\n\n🔥 Error unknown: \n") { FontSize = 14 });
856 | tb.Inlines.Add(new Run("------------------------------------------------------------\n") { Foreground = Brushes.SlateBlue });
857 | bool hint_listpedeps = false;
858 | foreach (var p in plugins["others"])
859 | {
860 | Diagnose.Depends file_dependencies = null;
861 |
862 | try
863 | {
864 | file_dependencies = await diag.GetDllDependencies(p);
865 | }
866 | catch
867 | {
868 | hint_listpedeps = true;
869 | }
870 |
871 | if (file_dependencies != null)
872 | {
873 | tb.Inlines.Add(" ");
874 | if (Path.IsPathRooted(p))
875 | tb.Inlines.Add(new Run(Path.GetDirectoryName(p) + @"\") { Foreground = Brushes.Silver });
876 | tb.Inlines.Add(Path.GetFileName(p) + "\n");
877 | tb.Inlines.Add(" \t requires following dependencies:\n\n");
878 |
879 | foreach (var dependency in file_dependencies.Imports)
880 | {
881 | tb.Inlines.Add(" \t - " + dependency + "\n");
882 | }
883 | tb.Inlines.Add("\n");
884 |
885 | tb.Inlines.Add(" \t Architecture is " + file_dependencies.architecture + " \n");
886 | tb.Inlines.Add(" \t Minimum OS version is " + file_dependencies.minimum_windows_version + " (" + file_dependencies.minimum_windows_osname + ") \n\n");
887 | }
888 | else
889 | {
890 | tb.Inlines.Add(" ");
891 | if (Path.IsPathRooted(p))
892 | tb.Inlines.Add(new Run(Path.GetDirectoryName(p) + @"\") { Foreground = Brushes.Silver });
893 | tb.Inlines.Add(Path.GetFileName(p) + "\n");
894 | }
895 | }
896 | if (hint_listpedeps)
897 | {
898 | tb.Inlines.Add("\nInstall listpedeps.exe via 'choco install pedeps'");
899 | tb.Inlines.Add("\nor copy listpedeps.exe next to vsrepogui.exe for detailed information about missing dependencies.");
900 | tb.Inlines.Add("\nDownload here: https://github.com/brechtsanders/pedeps/releases\n\n");
901 | }
902 | }
903 |
904 | var not_a_vsplugin_known = plugins["not_a_vsplugin"].Where(x => known_files.ContainsKey(x)).Select(x => x).ToList();
905 | var not_a_vsplugin_unknown = plugins["not_a_vsplugin"].Where(x => !known_files.ContainsKey(x)).Select(x => x).ToList();
906 |
907 | if (not_a_vsplugin_known.Count() > 0)
908 | {
909 | tb.Inlines.Add(new Run("\n\n🙂 Identified non-VapourSynth Plugins: \n") { FontSize = 14 });
910 | tb.Inlines.Add(new Run("------------------------------------------------------------\n") { Foreground = Brushes.SlateBlue });
911 | foreach (var p in not_a_vsplugin_known)
912 | {
913 | tb.Inlines.Add(" ");
914 | if (Path.IsPathRooted(p))
915 | tb.Inlines.Add(new Run(Path.GetDirectoryName(p) + @"\") { Foreground = Brushes.Silver });
916 | tb.Inlines.Add(Path.GetFileName(p) + "\t");
917 | tb.Inlines.Add(new Run("[belongs to " + known_files[p] + "]\n") { Foreground = Brushes.Orange });
918 | }
919 | }
920 | if (not_a_vsplugin_unknown.Count() > 0)
921 | {
922 | tb.Inlines.Add(new Run("\n\n🤨 Unidentified DLLs (maybe also Plugin dependencies?): \n") { FontSize = 14 });
923 | tb.Inlines.Add(new Run("------------------------------------------------------------\n") { Foreground = Brushes.SlateBlue });
924 | foreach (var p in not_a_vsplugin_unknown)
925 | {
926 | tb.Inlines.Add(" ");
927 | if (Path.IsPathRooted(p))
928 | tb.Inlines.Add(new Run(Path.GetDirectoryName(p) + @"\") { Foreground = Brushes.Silver });
929 | tb.Inlines.Add(Path.GetFileName(p) + "\n");
930 | }
931 | }
932 | DiagPrintHelper(plugins, "duplicate_dlls", "\n\n🤨 These dlls exits in both folders: \n", tb, true);
933 |
934 | //DiagPrintHelper(plugins, "not_a_vsplugin", "\n\n🤨 Notice - Probably a Plugin dependency (not a VS Plugin): \n");
935 | DiagPrintHelper(plugins, "no_problems", "\n\n👍 Successfully loaded Plugins: \n", tb, false);
936 |
937 | }
938 | else
939 | {
940 | tb.Inlines.Add("Could not test plugins");
941 | }
942 |
943 | ScrollViewer.Content = richtextbox;
944 | AppIsWorking(false);
945 | }
946 |
947 |
948 | }
949 |
950 | }
951 |
952 |
953 | }
954 |
--------------------------------------------------------------------------------
/VSRepoGUI/PortableSettings.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.IO;
4 | using System.Windows;
5 | using Newtonsoft.Json;
6 |
7 | namespace VSRepoGUI
8 | {
9 | public partial class PortableSettings
10 | {
11 | [JsonProperty("Bin")]
12 | public string Bin { get; set; }
13 |
14 | [JsonProperty("win32")]
15 | public Win Win32 { get; set; }
16 |
17 | [JsonProperty("win64")]
18 | public Win Win64 { get; set; }
19 |
20 | private string settingsfile = "vsrepogui.json";
21 |
22 | public PortableSettings LoadLocalFile(string file)
23 | {
24 | this.settingsfile = file;
25 | return LoadLocalFile();
26 | }
27 |
28 | public PortableSettings LoadLocalFile()
29 | {
30 | if (File.Exists(MakeFullPath(settingsfile)))
31 | {
32 | var jsonString = File.ReadAllText(MakeFullPath(settingsfile));
33 | try
34 | {
35 | var settingsFile = JsonConvert.DeserializeObject(jsonString);
36 |
37 | settingsFile.Bin = MakeFullPath(settingsFile.Bin);
38 | settingsFile.Win32.Binaries = MakeFullPath(settingsFile.Win32.Binaries);
39 | settingsFile.Win32.Scripts = MakeFullPath(settingsFile.Win32.Scripts);
40 | settingsFile.Win64.Binaries = MakeFullPath(settingsFile.Win64.Binaries);
41 | settingsFile.Win64.Scripts = MakeFullPath(settingsFile.Win64.Scripts);
42 | return settingsFile;
43 | } catch(Exception e)
44 | {
45 | MessageBox.Show("vsrepogui.json is invalid");
46 | return null;
47 | }
48 | }
49 | return null;
50 | }
51 |
52 | public void SaveLocalFile()
53 | {
54 | throw new NotImplementedException();
55 | //string joutput = JsonConvert.SerializeObject(a);
56 | //System.IO.File.WriteAllText("vsrepogui.json", joutput);
57 | }
58 |
59 | public string MakeFullPath(string path)
60 | {
61 | if (!Path.IsPathRooted(path)) {
62 | return Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName) + "\\" + path;
63 | }
64 | return path;
65 | }
66 | }
67 |
68 | public partial class Win
69 | {
70 | [JsonProperty("Binaries")]
71 | public string Binaries { get; set; }
72 |
73 | [JsonProperty("Scripts")]
74 | public string Scripts { get; set; }
75 | }
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/VSRepoGUI/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 | // Allgemeine Informationen über eine Assembly werden über die folgenden
8 | // Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
9 | // die einer Assembly zugeordnet sind.
10 | [assembly: AssemblyTitle("VSRepoGUI")]
11 | [assembly: AssemblyDescription("")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("")]
14 | [assembly: AssemblyProduct("VSRepoGUI")]
15 | [assembly: AssemblyCopyright("Copyright © 2021")]
16 | [assembly: AssemblyTrademark("")]
17 | [assembly: AssemblyCulture("")]
18 |
19 | // Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
20 | // für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
21 | // COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
22 | [assembly: ComVisible(false)]
23 |
24 | //Um mit dem Erstellen lokalisierbarer Anwendungen zu beginnen, legen Sie
25 | //ImCodeVerwendeteKultur in der .csproj-Datei
26 | //in einer fest. Wenn Sie in den Quelldateien beispielsweise Deutsch
27 | //(Deutschland) verwenden, legen Sie auf \"de-DE\" fest. Heben Sie dann die Auskommentierung
28 | //des nachstehenden NeutralResourceLanguage-Attributs auf. Aktualisieren Sie "en-US" in der nachstehenden Zeile,
29 | //sodass es mit der UICulture-Einstellung in der Projektdatei übereinstimmt.
30 |
31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
32 |
33 |
34 | [assembly: ThemeInfo(
35 | ResourceDictionaryLocation.None, //Speicherort der designspezifischen Ressourcenwörterbücher
36 | //(wird verwendet, wenn eine Ressource auf der Seite nicht gefunden wird,
37 | // oder in den Anwendungsressourcen-Wörterbüchern nicht gefunden werden kann.)
38 | ResourceDictionaryLocation.SourceAssembly //Speicherort des generischen Ressourcenwörterbuchs
39 | //(wird verwendet, wenn eine Ressource auf der Seite nicht gefunden wird,
40 | // designspezifischen Ressourcenwörterbuch nicht gefunden werden kann.)
41 | )]
42 |
43 |
44 | // Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
45 | //
46 | // Hauptversion
47 | // Nebenversion
48 | // Buildnummer
49 | // Revision
50 | //
51 | // Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
52 | // indem Sie "*" wie unten gezeigt eingeben:
53 | // [assembly: AssemblyVersion("1.0.*")]
54 | [assembly: AssemblyVersion("1.0.0.0")]
55 | [assembly: AssemblyFileVersion("1.0.0.0")]
56 |
--------------------------------------------------------------------------------
/VSRepoGUI/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // Dieser Code wurde von einem Tool generiert.
4 | // Laufzeitversion:4.0.30319.42000
5 | //
6 | // Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
7 | // der Code erneut generiert wird.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace VSRepoGUI.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
17 | ///
18 | // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
19 | // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
20 | // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
21 | // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | public 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 | /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | public 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("VSRepoGUI.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
51 | /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | public static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
65 | ///
66 | public static System.Drawing.Bitmap vsrepo_logo {
67 | get {
68 | object obj = ResourceManager.GetObject("vsrepo_logo", resourceCulture);
69 | return ((System.Drawing.Bitmap)(obj));
70 | }
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/VSRepoGUI/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 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 | ..\Resources\vsrepo_logo.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
123 |
124 |
--------------------------------------------------------------------------------
/VSRepoGUI/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // Dieser Code wurde von einem Tool generiert.
4 | // Laufzeitversion:4.0.30319.42000
5 | //
6 | // Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
7 | // der Code erneut generiert wird.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace VSRepoGUI.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.1.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/VSRepoGUI/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/VSRepoGUI/Resources/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/theChaosCoder/VSRepoGUI/7bb51982bdeda541db4fa3f9fb72668d622b6fb7/VSRepoGUI/Resources/icon.ico
--------------------------------------------------------------------------------
/VSRepoGUI/Resources/vsrepo_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/theChaosCoder/VSRepoGUI/7bb51982bdeda541db4fa3f9fb72668d622b6fb7/VSRepoGUI/Resources/vsrepo_logo.png
--------------------------------------------------------------------------------
/VSRepoGUI/SettingsService.cs:
--------------------------------------------------------------------------------
1 | using Jot;
2 | using System.Windows;
3 |
4 | namespace VSRepoGUI
5 | {
6 | static class SettingsService
7 | {
8 | public static Tracker Tracker = new Tracker();
9 |
10 | static SettingsService()
11 | {
12 | Tracker
13 | .Configure()
14 | .Id(w => "vsrepogui_settings", null, false)
15 | .Properties(w => new { w.Top, w.Width, w.Height, w.Left, w.WindowState })
16 | .PersistOn(nameof(Window.Closing))
17 | .StopTrackingOn(nameof(Window.Closing));
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/VSRepoGUI/SystemInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Management;
5 |
6 | namespace VSRepoGUI
7 | {
8 | class SystemInfo
9 | {
10 | public string OS { get; set; }
11 | public bool Is64Bit { get; set; }
12 |
13 | public CPU Cpu { get; set; }
14 | public List Cpus { get; set; }
15 | public int TotalCpuCores { get; set; } = 0;
16 | public int TotalLogicalProcessors { get; set; } = 0;
17 | public GPU Gpu { get; set; }
18 | public List Gpus { get; set; }
19 | public RAM Ram { get; set; } = new RAM(); // in GB
20 |
21 | public bool HasMultipleCpus { get; set; } = false;
22 | public bool HasMultipleGpus { get; set; } = false;
23 |
24 |
25 | public SystemInfo()
26 | {
27 | OS = (from x in new ManagementObjectSearcher("SELECT Caption FROM Win32_OperatingSystem").Get().Cast()
28 | select x.GetPropertyValue("Caption")).FirstOrDefault().ToString();
29 | Is64Bit = Environment.Is64BitOperatingSystem;
30 |
31 | var cpus = GetCpus();
32 | foreach (CPU item in cpus)
33 | {
34 | TotalCpuCores += item.Cores;
35 | TotalLogicalProcessors += item.LogicalProcessors;
36 | }
37 |
38 | if (cpus.Count() > 1)
39 | {
40 | HasMultipleCpus = true;
41 | Cpus = cpus;
42 | }
43 | else
44 | {
45 | if (cpus.Count() == 1)
46 | Cpu = cpus[0];
47 | else
48 | Cpu = new CPU() { Name = "cpu detection failed" };
49 | }
50 |
51 |
52 | var gpus = GetGpus();
53 | if (gpus.Count() > 1)
54 | {
55 | HasMultipleGpus = true;
56 | Gpus = gpus;
57 | }
58 | else
59 | {
60 | if (gpus.Count() == 1)
61 | Gpu = gpus[0];
62 | else
63 | Gpu = new GPU() { Name = "Not detected", Description = "Not detected" };
64 | }
65 |
66 | SetRamInfo();
67 |
68 | }
69 | public List GetCpus()
70 | {
71 | var cpu_list = new List();
72 |
73 | ManagementObjectSearcher mos = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_Processor");
74 |
75 | foreach (ManagementObject mo in mos.Get())
76 | {
77 | CPU cpu = new CPU
78 | {
79 | DeviceId = mo["DeviceID"].ToString(),
80 | Name = mo["Name"].ToString(),
81 | Cores = int.Parse(mo["NumberOfCores"].ToString()),
82 | LogicalProcessors = int.Parse(mo["NumberOfLogicalProcessors"].ToString()),
83 | };
84 | cpu_list.Add(cpu);
85 | }
86 | return cpu_list;
87 | }
88 |
89 |
90 | public List GetGpus()
91 | {
92 | var gpu_list = new List();
93 |
94 | ManagementObjectSearcher mos = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_VideoController");
95 |
96 | foreach (ManagementObject mo in mos.Get())
97 | {
98 | GPU cpu = new GPU
99 | {
100 | DeviceId = mo["DeviceID"].ToString(),
101 | Description = mo["Description"].ToString(),
102 | Name = mo["Name"].ToString(),
103 | };
104 | gpu_list.Add(cpu);
105 | }
106 | return gpu_list;
107 | }
108 |
109 | private void SetRamInfo()
110 | {
111 | ManagementObjectSearcher mos_ram = new ManagementObjectSearcher("root\\CIMV2", "SELECT TotalPhysicalMemory FROM Win32_ComputerSystem");
112 | Ram.Size = (int)Math.Round(Convert.ToDouble(mos_ram.Get().OfType().FirstOrDefault()["TotalPhysicalMemory"].ToString()) / 1024 / 1024 / 1024, 0);
113 | }
114 | }
115 |
116 |
117 |
118 | public class CPU
119 | {
120 | public string DeviceId { get; set; }
121 | public string Name { get; set; }
122 | public int Cores { get; set; }
123 | public int LogicalProcessors { get; set; }
124 | }
125 | public class GPU
126 | {
127 | public string DeviceId { get; set; }
128 | public string Name { get; set; }
129 | public string Description { get; set; }
130 | }
131 | public class RAM
132 | {
133 | public int Size { get; set; }
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/VSRepoGUI/VSRepoGUI.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {FD263958-6C61-49F5-8725-E4D2AA27BE54}
8 | WinExe
9 | VSRepoGUI
10 | VSRepoGUI
11 | v4.7.2
12 | 512
13 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
14 | 4
15 | true
16 | true
17 | false
18 |
19 |
20 |
21 | C:\Users\anato\Desktop\fffff\
22 | true
23 | Disk
24 | false
25 | Foreground
26 | 7
27 | Days
28 | false
29 | false
30 | true
31 | 0
32 | 1.0.0.%2a
33 | false
34 | true
35 |
36 |
37 | AnyCPU
38 | true
39 | full
40 | false
41 | bin\Debug\
42 | DEBUG;TRACE
43 | prompt
44 | 4
45 |
46 |
47 | AnyCPU
48 | pdbonly
49 | true
50 | bin\Release\
51 | TRACE
52 | prompt
53 | 4
54 |
55 |
56 |
57 |
58 |
59 | Resources\icon.ico
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | 4.0
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 | MSBuild:Compile
85 | Designer
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 | MSBuild:Compile
103 | Designer
104 |
105 |
106 | App.xaml
107 | Code
108 |
109 |
110 | MainWindow.xaml
111 | Code
112 |
113 |
114 |
115 |
116 | Code
117 |
118 |
119 | True
120 | True
121 | Resources.resx
122 |
123 |
124 | PublicResXFileCodeGenerator
125 | Resources.Designer.cs
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 | False
134 | Microsoft .NET Framework 4.7.2 %28x86 und x64%29
135 | true
136 |
137 |
138 | False
139 | .NET Framework 3.5 SP1
140 | false
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 | 5.7.0
155 | runtime; build; native; contentfiles; analyzers; buildtransitive
156 | all
157 |
158 |
159 | 0.0.3.223
160 |
161 |
162 | 2.1.13
163 |
164 |
165 | 4.5.0
166 |
167 |
168 | 3.4.1
169 |
170 |
171 |
172 |
--------------------------------------------------------------------------------
/VSRepoGUI/VsApi.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Diagnostics;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 |
9 | namespace VSRepoGUI
10 | {
11 | public class VsApi : INotifyPropertyChanged
12 | {
13 | private string portable = "";
14 | private object result;
15 | public enum PluginStatus : int { NotInstalled, Installed, InstalledUnknown, UpdateAvailable };
16 | public bool Win64;
17 | public Dictionary paths = new Dictionary();
18 | private string vsrepo_path = "vsrepo.py";
19 | public string consolestd { get; set; }
20 | public string python_bin = "python.exe";
21 | public event PropertyChangedEventHandler PropertyChanged;
22 |
23 |
24 |
25 | public async Task UninstallAsync(string plugin)
26 | {
27 | await Task.Run(() => Run("uninstall", plugin));
28 | //var result = (List)this.result;
29 | //return result;
30 | }
31 |
32 | public async Task InstallAsync(string plugin, bool force = false)
33 | {
34 | string install = "install";
35 | if (force)
36 | install = "-f install";
37 | await Task.Run(() => Run(install, plugin));
38 | }
39 |
40 | public Dictionary> GetInstalled()
41 | {
42 | Run("installed");
43 | var result = (Dictionary>)this.result;
44 | return result;
45 | }
46 |
47 | public async Task>> GetInstalledAsync()
48 | {
49 | return await Task.Run(() => GetInstalled());
50 | }
51 |
52 | ///
53 | /// false for 32 and true for 64 bit
54 | ///
55 | ///
56 | /// Paths
57 | public Paths GetPaths(bool isWin64)
58 | {
59 | if (!paths.ContainsKey(isWin64))
60 | {
61 | Run("paths");
62 | var result = (List)this.result;
63 | var _paths = new Paths
64 | {
65 | Definitions = result[0],
66 | Binaries = result[1],
67 | Scripts = result[2]
68 | };
69 | if(result.Count == 4)
70 | {
71 | _paths.DistInfos = result[3];
72 | }
73 | paths.Add(isWin64, _paths);
74 | }
75 | return paths[isWin64];
76 | }
77 | public void SetPaths(bool bit, Paths paths)
78 | {
79 | this.paths[bit] = paths;
80 | }
81 |
82 | public void Update()
83 | {
84 | Run("update");
85 | }
86 |
87 | public async Task UpgradeAsync(string plugin, bool force = false)
88 | {
89 | string upgrade = "upgrade";
90 | if (force)
91 | upgrade = "-f upgrade";
92 | await Task.Run(() => Run(upgrade, plugin));
93 | }
94 |
95 | public async Task UpgradeAllAsync()
96 | {
97 | await Task.Run(() => Run("upgrade-all"));
98 | }
99 |
100 | public void SetPortableMode(bool status)
101 | {
102 | if (status)
103 | this.portable = "-p";
104 | else
105 | this.portable = "";
106 | }
107 |
108 | public void SetArch(bool isWin64)
109 | {
110 | this.Win64 = isWin64;
111 | }
112 |
113 | public void SetVsrepoPath(string path)
114 | {
115 | this.vsrepo_path = path;
116 | }
117 |
118 | public string getTarget(string operation)
119 | {
120 | /*List targetCommands = new List
121 | {
122 | "install",
123 | "upgrade",
124 | "upgrade-all",
125 | "uninstall",
126 | };
127 |
128 | if (!targetCommands.Contains(operation)) {
129 | return "";
130 | }*/
131 | if (Win64)
132 | return "-t win64";
133 | return "-t win32";
134 | }
135 |
136 | public string getCustomPaths()
137 | {
138 | if (!String.IsNullOrEmpty(portable))
139 | {
140 | if(paths.ContainsKey(Win64))
141 | {
142 | return String.Format("-b \"{0}\" -s \"{1}\"", paths[Win64].Binaries, paths[Win64].Scripts);
143 | }
144 | }
145 | return "";
146 | }
147 |
148 | private object Run(string operation, string plugins = "")
149 | {
150 | string args = String.Format("\"{0}\" {1} {2} {3} {4} {5}", vsrepo_path, portable, getCustomPaths(), getTarget(operation), operation, plugins);
151 |
152 | var process = new Process()
153 | {
154 | StartInfo = new ProcessStartInfo
155 | {
156 | FileName = python_bin,
157 | Arguments = args,
158 | RedirectStandardOutput = true,
159 | RedirectStandardError = true,
160 | UseShellExecute = false,
161 | CreateNoWindow = true,
162 | }
163 | };
164 | try
165 | {
166 | process.Start();
167 | }
168 | catch (Exception ex)
169 | {
170 | MessageBox.Show("There is a problem with python" + ex.ToString());
171 | //System.Environment.Exit(1);
172 | }
173 | Console.WriteLine("### RUN: " + process.StartInfo.FileName + " " + process.StartInfo.Arguments);
174 | //process.BeginOutputReadLine();
175 | //string error = process.StandardError.ReadToEnd();
176 | //process.WaitForExit();
177 |
178 |
179 | string result_std;
180 | List paths = new List();
181 | var installed = new Dictionary>();
182 | //string result = process.StandardOutput.ReadToEnd();
183 | while ((result_std = process.StandardOutput.ReadLine()) != null)
184 | {
185 | switch (operation)
186 | {
187 | case "installed":
188 |
189 | if (!result_std.Contains("Identifier"))
190 | {
191 | //Console.WriteLine(result_std);
192 |
193 | var status = PluginStatus.Installed;
194 | if (result_std[0].ToString() == "+")
195 | {
196 | status = PluginStatus.InstalledUnknown;
197 | }
198 | if (result_std[0].ToString() == "*")
199 | {
200 | status = PluginStatus.UpdateAvailable;
201 | }
202 | string lastWord = result_std.Split(' ').Last().Trim();
203 | var localversion = result_std.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Reverse().Skip(2).Reverse().Last().Trim();
204 | var kv = new KeyValuePair(localversion.ToString(), status);
205 |
206 | installed.Add(lastWord, kv);
207 | Console.WriteLine(lastWord);
208 | }
209 | this.result = installed;
210 | break;
211 |
212 | case "paths":
213 | if (!result_std.Contains("Paths"))
214 | {
215 | string fitlered = string.Join(" ", result_std.Split(' ').Skip(1)).Trim();
216 | paths.Add(fitlered);
217 | Console.WriteLine(fitlered);
218 | }
219 | this.result = paths;
220 | break;
221 | case "install":
222 | case "uninstall":
223 | consolestd = result_std;
224 | break;
225 | }
226 | }
227 |
228 | process.WaitForExit();
229 | return result; // #### TODO process.ExitCode
230 | }
231 | }
232 |
233 |
234 | ///
235 | /// Contains paths used by vsrepo.py
236 | ///
237 | public class Paths
238 | {
239 | public string Definitions;
240 | public string Binaries;
241 | public string Scripts;
242 | public string DistInfos;
243 | }
244 |
245 | }
246 |
--------------------------------------------------------------------------------
/VSRepoGUI/VsRegistry.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Win32;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 |
6 | namespace VSRepoGUI
7 | {
8 | public class VsRegistry
9 | {
10 | public string RegPath { get; set; }
11 |
12 | public string CorePlugins { get; set; }
13 | public string Path { get; set; }
14 | public string Plugins { get; set; }
15 | public string PythonPath { get; set; }
16 | public string VapourSynthDLL { get; set; }
17 | public string Version { get; set; }
18 | public string VSScriptDLL { get; set; }
19 | public string VSPipeEXE { get; set; }
20 | public string VSRepoPY { get; set; }
21 |
22 | public VsRegistry GetRegistry(RegistryKey regkey, string subkey)
23 | {
24 | var key = regkey.OpenSubKey(subkey);
25 | if (key == null)
26 | return null;
27 |
28 | RegPath = subkey;
29 |
30 | foreach (var item in key.GetValueNames())
31 | {
32 | switch (item)
33 | {
34 | case "CorePlugins":
35 | CorePlugins = (string)key.GetValue("CorePlugins"); break;
36 | case "Path":
37 | Path = (string)key.GetValue("Path"); break;
38 | case "Plugins":
39 | Plugins = (string)key.GetValue("Plugins"); break;
40 | case "PythonPath":
41 | PythonPath = (string)key.GetValue("PythonPath"); break;
42 | case "VapourSynthDLL":
43 | VapourSynthDLL = (string)key.GetValue("VapourSynthDLL"); break;
44 | case "Version":
45 | Version = (string)key.GetValue("Version"); break;
46 | case "VSScriptDLL":
47 | VSScriptDLL = (string)key.GetValue("VSScriptDLL"); break;
48 | case "VSPipeEXE":
49 | VSPipeEXE = (string)key.GetValue("VSPipeEXE"); break;
50 | case "VSRepoPY":
51 | VSRepoPY = (string)key.GetValue("VSRepoPY"); break;
52 | }
53 | }
54 | return this;
55 | }
56 | }
57 |
58 | public class VsRegistryHelper
59 | {
60 |
61 | RegistryKey localKey32 = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry32);
62 | RegistryKey localKey64 = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64);
63 | RegistryKey userKey32 = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.CurrentUser, RegistryView.Registry32);
64 | RegistryKey userKey64 = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.CurrentUser, RegistryView.Registry64);
65 |
66 | public Dictionary Registry = new Dictionary();
67 | public string current_vs_installation;
68 |
69 |
70 | public bool SetCurrentVsInstallation(string python_path)
71 | {
72 | foreach(var regitem in Registry)
73 | {
74 | if(regitem.Value.PythonPath.ToLower().TrimEnd('\\') == Path.GetDirectoryName(python_path).ToLower().TrimEnd('\\'))
75 | {
76 | current_vs_installation = regitem.Key;
77 | return true;
78 | }
79 | }
80 | return false;
81 | }
82 |
83 | public string GetCurrentRegPath()
84 | {
85 | if (Registry.Count() > 0)
86 | return Registry[current_vs_installation].Path;
87 |
88 | return null;
89 | }
90 |
91 | public string GetCurrentRegPluginsPath()
92 | {
93 | if (Registry.Count() > 0)
94 | return Registry[current_vs_installation].Plugins;
95 |
96 | return null;
97 | }
98 |
99 | public string GetAvailablePythonPath()
100 | {
101 | if (Registry.Count() > 0)
102 | return Registry[current_vs_installation].PythonPath;
103 |
104 | return null;
105 | }
106 |
107 | public void ReadAllVsRegistryInfos()
108 | {
109 | var dict = new Dictionary();
110 |
111 | var regl32 = new VsRegistry().GetRegistry(localKey32, @"SOFTWARE\VapourSynth-32");
112 | var regl64 = new VsRegistry().GetRegistry(localKey64, @"SOFTWARE\VapourSynth");
113 | var regu32 = new VsRegistry().GetRegistry(userKey32, @"SOFTWARE\VapourSynth-32");
114 | var regu64 = new VsRegistry().GetRegistry(userKey64, @"SOFTWARE\VapourSynth");
115 |
116 | if (regu32 != null)
117 | {
118 | dict["user32"] = regu32;
119 | current_vs_installation = "user32";
120 | }
121 |
122 | if (regu64 != null)
123 | {
124 | dict["user64"] = regu64;
125 | current_vs_installation = "user64";
126 | }
127 |
128 | if (regl32 != null)
129 | {
130 | dict["local32"] = regl32;
131 | current_vs_installation = "local32";
132 | }
133 |
134 | if (regl64 != null)
135 | {
136 | dict["local64"] = regl64;
137 | current_vs_installation = "local64";
138 | }
139 |
140 | this.Registry = dict;
141 | }
142 |
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/VSRepoGUI/Vspackage.cs:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | // To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
4 | //
5 | // using QuickType;
6 | //
7 | // var welcome = VspackageModel.FromJson(jsonString);
8 |
9 | namespace VSRepoGUI
10 | {
11 | using System;
12 | using System.Collections.Generic;
13 | using System.Globalization;
14 | using Newtonsoft.Json;
15 | using Newtonsoft.Json.Converters;
16 |
17 | public partial class Vspackage
18 | {
19 | [JsonProperty("file-format")]
20 | public long FileFormat { get; set; }
21 |
22 | [JsonProperty("packages")]
23 | public Package[] Packages { get; set; }
24 | }
25 |
26 | public partial class Package
27 | {
28 | [System.ComponentModel.DefaultValue(VsApi.PluginStatus.NotInstalled)]
29 | public VsApi.PluginStatus Status { get; set; }
30 |
31 | [JsonProperty("name")]
32 | public string Name { get; set; }
33 |
34 | [JsonProperty("type")]
35 | public TypeEnum Type { get; set; }
36 |
37 | [JsonProperty("description")]
38 | public string Description { get; set; }
39 |
40 | [JsonProperty("website", NullValueHandling = NullValueHandling.Ignore)]
41 | public string Website { get; set; }
42 |
43 | [JsonProperty("category")]
44 | public string Category { get; set; }
45 |
46 | [JsonProperty("identifier")]
47 | public string Identifier { get; set; }
48 |
49 | [JsonProperty("namespace", NullValueHandling = NullValueHandling.Ignore)]
50 | public string Namespace { get; set; }
51 |
52 | [JsonProperty("github", NullValueHandling = NullValueHandling.Ignore)]
53 | public Uri Github { get; set; }
54 |
55 | [JsonProperty("releases")]
56 | public Release[] Releases { get; set; }
57 |
58 | [JsonProperty("modulename", NullValueHandling = NullValueHandling.Ignore)]
59 | public string Modulename { get; set; }
60 |
61 | [JsonProperty("wheelname", NullValueHandling = NullValueHandling.Ignore)]
62 | public string Wheelname { get; set; }
63 |
64 | [JsonProperty("dependencies", NullValueHandling = NullValueHandling.Ignore)]
65 | public string[] Dependencies { get; set; }
66 |
67 | [JsonProperty("doom9", NullValueHandling = NullValueHandling.Ignore)]
68 | public string Doom9 { get; set; }
69 | }
70 |
71 |
72 |
73 | public partial class Release
74 | {
75 | [JsonProperty("version")]
76 | public string Version { get; set; }
77 |
78 | public string VersionLocal { get; set; }
79 |
80 | [JsonProperty("published", NullValueHandling = NullValueHandling.Ignore)]
81 | public string Published { get; set; }
82 |
83 | [JsonProperty("win32", NullValueHandling = NullValueHandling.Ignore)]
84 | public Win32 Win32 { get; set; }
85 |
86 | [JsonProperty("win64", NullValueHandling = NullValueHandling.Ignore)]
87 | public Win64 Win64 { get; set; }
88 |
89 | [JsonProperty("script", NullValueHandling = NullValueHandling.Ignore)]
90 | public Script Script { get; set; }
91 |
92 | [JsonProperty("wheel", NullValueHandling = NullValueHandling.Ignore)]
93 | public Script Wheel { get; set; }
94 | }
95 |
96 | public partial class Script
97 | {
98 | [JsonProperty("url")]
99 | public Uri Url { get; set; }
100 |
101 | [JsonProperty("files")]
102 | public Dictionary Files { get; set; }
103 | }
104 | public partial class Wheel
105 | {
106 | [JsonProperty("url")]
107 | public Uri Url { get; set; }
108 | [JsonProperty("hash")]
109 | public string Hash { get; set; }
110 | }
111 |
112 | public partial class Win32
113 | {
114 | [JsonProperty("url")]
115 | public Uri Url { get; set; }
116 |
117 | [JsonProperty("files")]
118 | public Dictionary Files { get; set; }
119 | }
120 |
121 | public partial class Win64
122 | {
123 | [JsonProperty("url")]
124 | public Uri Url { get; set; }
125 |
126 | [JsonProperty("files")]
127 | public Dictionary Files { get; set; }
128 | }
129 |
130 | public enum TypeEnum { PyScript, VsPlugin, PyWheel };
131 |
132 | public partial class Vspackage
133 | {
134 | public static Vspackage FromJson(string json) => JsonConvert.DeserializeObject(json, Converter.Settings);
135 | }
136 |
137 | public static class Serialize
138 | {
139 | public static string ToJson(this Vspackage self) => JsonConvert.SerializeObject(self, Converter.Settings);
140 | }
141 |
142 | internal static class Converter
143 | {
144 | public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
145 | {
146 | MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
147 | DateParseHandling = DateParseHandling.None,
148 | Converters =
149 | {
150 | TypeEnumConverter.Singleton,
151 | new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
152 | },
153 | };
154 | }
155 |
156 | internal class TypeEnumConverter : JsonConverter
157 | {
158 | public override bool CanConvert(Type t) => t == typeof(TypeEnum) || t == typeof(TypeEnum?);
159 |
160 | public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
161 | {
162 | if (reader.TokenType == JsonToken.Null) return null;
163 | var value = serializer.Deserialize(reader);
164 | switch (value)
165 | {
166 | case "PyScript":
167 | return TypeEnum.PyScript;
168 | case "VSPlugin":
169 | return TypeEnum.VsPlugin;
170 | case "PyWheel":
171 | return TypeEnum.PyWheel;
172 | }
173 | throw new Exception("Cannot unmarshal type TypeEnum");
174 | }
175 |
176 | public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
177 | {
178 | if (untypedValue == null)
179 | {
180 | serializer.Serialize(writer, null);
181 | return;
182 | }
183 | var value = (TypeEnum)untypedValue;
184 | switch (value)
185 | {
186 | case TypeEnum.PyScript:
187 | serializer.Serialize(writer, "PyScript");
188 | return;
189 | case TypeEnum.VsPlugin:
190 | serializer.Serialize(writer, "VSPlugin");
191 | return;
192 | case TypeEnum.PyWheel:
193 | serializer.Serialize(writer, "PyWheel");
194 | return;
195 | }
196 | throw new Exception("Cannot marshal type TypeEnum");
197 | }
198 |
199 | public static readonly TypeEnumConverter Singleton = new TypeEnumConverter();
200 | }
201 | }
202 |
--------------------------------------------------------------------------------