@@ -21,163 +21,194 @@ namespace plugin_Kinect360;
2121
2222internal class SetupData : ICoreSetupData
2323{
24- public object PluginIcon => new PathIcon
25- {
26- Data = ( Geometry ) XamlBindingHelper . ConvertValue ( typeof ( Geometry ) ,
27- "M55.75,3.68a2.27,2.27,0,0,0-2.42-2.4c-8.5.05-17,0-25.5,0H2.38c-.22,0-.44,0-.66,0A1.84,1.84,0,0,0,0,3.12c0,2.4,0,4.81,0,7.21a2.06,2.06,0,0,0,.44,1.12,1.9,1.9,0,0,0,1.66.67H23.76c1.48,0,1.46,0,1.47,1.46,0,.38-.09.54-.52.61-2.79.46-5.57,1-8.35,1.43-.35.06-.47.21-.45.56,0,.64,0,1.28,0,1.92,0,.88.35,1.22,1.25,1.23H38.45c.9,0,1.24-.34,1.25-1.23,0-.64,0-1.28,0-1.92,0-.35-.1-.5-.45-.56L31.68,14.3c-1.28-.22-1.26-.22-1.3-1.51,0-.53.12-.7.68-.69,7.46,0,14.92,0,22.37,0a2.07,2.07,0,0,0,2.3-2.3C55.73,7.77,55.67,5.72,55.75,3.68ZM18.77,9a2.3,2.3,0,1,1,2.3-2.27A2.31,2.31,0,0,1,18.77,9ZM29.66,9a2.3,2.3,0,1,1,2.28-2.3A2.32,2.32,0,0,1,29.66,9ZM37.4,9a2.26,2.26,0,0,1-2.32-2.3,2.25,2.25,0,0,1,2.27-2.29,2.32,2.32,0,0,1,2.34,2.31A2.29,2.29,0,0,1,37.4,9Z" )
28- } ;
29-
30- public string GroupName => "kinect" ;
31- public Type PluginType => typeof ( ITrackingDevice ) ;
24+ public object PluginIcon => new PathIcon
25+ {
26+ Data = ( Geometry ) XamlBindingHelper . ConvertValue ( typeof ( Geometry ) ,
27+ "M55.75,3.68a2.27,2.27,0,0,0-2.42-2.4c-8.5.05-17,0-25.5,0H2.38c-.22,0-.44,0-.66,0A1.84,1.84,0,0,0,0,3.12c0,2.4,0,4.81,0,7.21a2.06,2.06,0,0,0,.44,1.12,1.9,1.9,0,0,0,1.66.67H23.76c1.48,0,1.46,0,1.47,1.46,0,.38-.09.54-.52.61-2.79.46-5.57,1-8.35,1.43-.35.06-.47.21-.45.56,0,.64,0,1.28,0,1.92,0,.88.35,1.22,1.25,1.23H38.45c.9,0,1.24-.34,1.25-1.23,0-.64,0-1.28,0-1.92,0-.35-.1-.5-.45-.56L31.68,14.3c-1.28-.22-1.26-.22-1.3-1.51,0-.53.12-.7.68-.69,7.46,0,14.92,0,22.37,0a2.07,2.07,0,0,0,2.3-2.3C55.73,7.77,55.67,5.72,55.75,3.68ZM18.77,9a2.3,2.3,0,1,1,2.3-2.27A2.31,2.31,0,0,1,18.77,9ZM29.66,9a2.3,2.3,0,1,1,2.28-2.3A2.32,2.32,0,0,1,29.66,9ZM37.4,9a2.26,2.26,0,0,1-2.32-2.3,2.25,2.25,0,0,1,2.27-2.29,2.32,2.32,0,0,1,2.34,2.31A2.29,2.29,0,0,1,37.4,9Z" )
28+ } ;
29+
30+ public string GroupName => "kinect" ;
31+ public Type PluginType => typeof ( ITrackingDevice ) ;
3232}
3333
3434internal class SdkInstaller : IDependencyInstaller
3535{
36- public IDependencyInstaller . ILocalizationHost Host { get ; set ; }
37-
38- public List < IDependency > ListDependencies ( )
39- {
40- return new List < IDependency >
41- {
42- new KinectSdk
43- {
44- Host = Host ,
45- Name = Host ? . RequestLocalizedString ( "/Plugins/Kinect360/Dependencies/Runtime/Name" ) ??
46- "Kinect for Xbox 360 SDK"
47- }
48- } ;
49- }
36+ public IDependencyInstaller . ILocalizationHost Host { get ; set ; }
37+
38+ public List < IDependency > ListDependencies ( )
39+ {
40+ return new List < IDependency >
41+ {
42+ new KinectSdk
43+ {
44+ Host = Host ,
45+ Name = Host ? . RequestLocalizedString ( "/Plugins/Kinect360/Dependencies/Runtime/Name" ) ??
46+ "Kinect for Xbox 360 SDK"
47+ }
48+ } ;
49+ }
50+
51+ public List < IFix > ListFixes ( )
52+ {
53+ return new List < IFix >
54+ {
55+ new NotPoweredFix
56+ {
57+ Host = Host ,
58+ Name = "Not Powered" // Without the "fix" part
59+ // Host?.RequestLocalizedString("/Plugins/Kinect360/Dependencies/Runtime/Name") ?? "Kinect for Xbox 360 SDK"
60+ }
61+ } ;
62+ }
5063}
5164
5265internal class KinectSdk : IDependency
5366{
54- private List < string > SdkFilesToInstall { get ; } = new ( )
55- {
56- "KinectDrivers-v1.8-x64.WHQL.msi" ,
57- "KinectRuntime-v1.8-x64.msi" ,
58- "KinectSDK-v1.8-x64.msi"
59- } ;
60-
61- public IDependencyInstaller . ILocalizationHost Host { get ; set ; }
62-
63- public string Name { get ; set ; }
64- public bool IsMandatory => true ;
65-
66- public bool IsInstalled
67- {
68- get
69- {
70- try
71- {
72- // Well, this is pretty much all we need for the plugin to be loaded
73- return File . Exists ( @"C:\Windows\System32\Kinect10.dll" ) ;
74- }
75- catch ( Exception )
76- {
77- // Access denied?
78- return false ;
79- }
80- }
81- }
82-
83- public string InstallerEula
84- {
85- get
86- {
87- try
88- {
89- return File . ReadAllText ( Path . Join (
90- Directory . GetParent ( Assembly . GetExecutingAssembly ( ) . Location ) ! . FullName ,
91- "Assets" , "Resources" , "eula.md" ) ) ;
92- }
93- catch ( Exception )
94- {
95- return string . Empty ;
96- }
97- }
98- }
99-
100- public async Task < bool > Install ( IProgress < InstallationProgress > progress , CancellationToken cancellationToken )
101- {
102- // Amethyst will handle this exception for us anyway
103- cancellationToken . ThrowIfCancellationRequested ( ) ;
104- var dependenciesFolder = Path . Join ( Directory . GetParent (
105- Assembly . GetExecutingAssembly ( ) . Location ) ! . FullName ,
106- "Assets" , "Resources" , "Dependencies" ) ;
107-
108- // Copy to temp if amethyst is packaged
109- // ReSharper disable once InvertIf
110- if ( PackageUtils . IsAmethystPackaged )
111- {
112- // Create a shared folder with the dependencies
113- var dependenciesFolderInternal = await ApplicationData . Current . TemporaryFolder . CreateFolderAsync (
114- Guid . NewGuid ( ) . ToString ( ) . ToUpper ( ) , CreationCollisionOption . OpenIfExists ) ;
115-
116- // Copy all driver files to Amethyst's local data folder
117- new DirectoryInfo ( Path . Join ( Directory . GetParent ( Assembly . GetExecutingAssembly ( ) . Location ) ! . FullName ,
118- "Assets" , "Resources" , "Dependencies" ) )
119- . CopyToFolder ( dependenciesFolderInternal . Path ) ;
120-
121- // Update the installation paths
122- dependenciesFolder = dependenciesFolderInternal . Path ;
123- }
124-
125- // Finally install the packages
126- return InstallFiles ( SdkFilesToInstall . Select ( x => Path . Join (
127- dependenciesFolder , x ) ) , progress , cancellationToken ) ;
128-
129- // Apply other related fixes, non-critical
130- // ReSharper disable once ConditionIsAlwaysTrueOrFalse
131- // (await SetupPost(progress) || true); // TODO
132- }
133-
134- private bool InstallFiles ( IEnumerable < string > files ,
135- IProgress < InstallationProgress > progress , CancellationToken cancellationToken )
136- {
137- // Amethyst will handle this exception for us anyway
138- cancellationToken . ThrowIfCancellationRequested ( ) ;
139-
140- // Execute each install
141- foreach ( var installFile in files )
142- try
143- {
144- // msi /qn /norestart
145- progress . Report ( new InstallationProgress
146- {
147- IsIndeterminate = true ,
148- StageTitle =
149- ( Host ? . RequestLocalizedString ( "/Plugins/Kinect360/Stages/Installing" ) ??
150- "Installing {0}..." ) . Replace ( "{0}" , Path . GetFileName ( installFile ) )
151- } ) ;
152-
153- var msiExecutableStart = new ProcessStartInfo
154- {
155- FileName = Path . Join ( Environment . GetFolderPath ( Environment . SpecialFolder . Windows ) ,
156- @"System32\msiexec.exe" ) ,
157- WorkingDirectory = Directory . GetParent ( installFile ) ! . FullName ,
158- Arguments = $ "/i { installFile } /quiet /qn /norestart ALLUSERS=1",
159- CreateNoWindow = true ,
160- WindowStyle = ProcessWindowStyle . Hidden ,
161- UseShellExecute = true ,
162- Verb = "runas"
163- } ;
164-
165- var msiExecutable = Process . Start ( msiExecutableStart ) ;
166- msiExecutable ! . WaitForExit ( 60000 ) ;
167- }
168- catch ( Exception e )
169- {
170- progress . Report ( new InstallationProgress
171- {
172- IsIndeterminate = true ,
173- StageTitle =
174- ( Host ? . RequestLocalizedString ( "/Plugins/Kinect360/Stages/Exceptions/Other" ) ??
175- "Exception: {0}" ) . Replace ( "{0}" , e . Message )
176- } ) ;
177-
178- return false ;
179- }
180-
181- return true ;
182- }
67+ private List < string > SdkFilesToInstall { get ; } = new ( )
68+ {
69+ "KinectDrivers-v1.8-x64.WHQL.msi" ,
70+ "KinectRuntime-v1.8-x64.msi" ,
71+ "KinectSDK-v1.8-x64.msi"
72+ } ;
73+
74+ public IDependencyInstaller . ILocalizationHost Host { get ; set ; }
75+
76+ public string Name { get ; set ; }
77+ public bool IsMandatory => true ;
78+
79+ public bool IsInstalled
80+ {
81+ get
82+ {
83+ try
84+ {
85+ // Well, this is pretty much all we need for the plugin to be loaded
86+ return File . Exists ( @"C:\Windows\System32\Kinect10.dll" ) ;
87+ }
88+ catch ( Exception )
89+ {
90+ // Access denied?
91+ return false ;
92+ }
93+ }
94+ }
95+
96+ public string InstallerEula
97+ {
98+ get
99+ {
100+ try
101+ {
102+ return File . ReadAllText ( Path . Join (
103+ Directory . GetParent ( Assembly . GetExecutingAssembly ( ) . Location ) ! . FullName ,
104+ "Assets" , "Resources" , "eula.md" ) ) ;
105+ }
106+ catch ( Exception )
107+ {
108+ return string . Empty ;
109+ }
110+ }
111+ }
112+
113+ public async Task < bool > Install ( IProgress < InstallationProgress > progress , CancellationToken cancellationToken )
114+ {
115+ // Amethyst will handle this exception for us anyway
116+ cancellationToken . ThrowIfCancellationRequested ( ) ;
117+ var dependenciesFolder = Path . Join ( Directory . GetParent (
118+ Assembly . GetExecutingAssembly ( ) . Location ) ! . FullName ,
119+ "Assets" , "Resources" , "Dependencies" ) ;
120+
121+ // Copy to temp if amethyst is packaged
122+ // ReSharper disable once InvertIf
123+ if ( PackageUtils . IsAmethystPackaged )
124+ {
125+ // Create a shared folder with the dependencies
126+ var dependenciesFolderInternal = await ApplicationData . Current . TemporaryFolder . CreateFolderAsync (
127+ Guid . NewGuid ( ) . ToString ( ) . ToUpper ( ) , CreationCollisionOption . OpenIfExists ) ;
128+
129+ // Copy all driver files to Amethyst's local data folder
130+ new DirectoryInfo ( Path . Join ( Directory . GetParent ( Assembly . GetExecutingAssembly ( ) . Location ) ! . FullName ,
131+ "Assets" , "Resources" , "Dependencies" ) )
132+ . CopyToFolder ( dependenciesFolderInternal . Path ) ;
133+
134+ // Update the installation paths
135+ dependenciesFolder = dependenciesFolderInternal . Path ;
136+ }
137+
138+ // Finally install the packages
139+ return InstallFiles ( SdkFilesToInstall . Select ( x => Path . Join (
140+ dependenciesFolder , x ) ) , progress , cancellationToken ) ;
141+
142+ // Apply other related fixes, non-critical
143+ // ReSharper disable once ConditionIsAlwaysTrueOrFalse
144+ // (await SetupPost(progress) || true); // TODO
145+ }
146+
147+ private bool InstallFiles ( IEnumerable < string > files ,
148+ IProgress < InstallationProgress > progress , CancellationToken cancellationToken )
149+ {
150+ // Amethyst will handle this exception for us anyway
151+ cancellationToken . ThrowIfCancellationRequested ( ) ;
152+
153+ // Execute each install
154+ foreach ( var installFile in files )
155+ try
156+ {
157+ // msi /qn /norestart
158+ progress . Report ( new InstallationProgress
159+ {
160+ IsIndeterminate = true ,
161+ StageTitle =
162+ ( Host ? . RequestLocalizedString ( "/Plugins/Kinect360/Stages/Installing" ) ??
163+ "Installing {0}..." ) . Replace ( "{0}" , Path . GetFileName ( installFile ) )
164+ } ) ;
165+
166+ var msiExecutableStart = new ProcessStartInfo
167+ {
168+ FileName = Path . Join ( Environment . GetFolderPath ( Environment . SpecialFolder . Windows ) ,
169+ @"System32\msiexec.exe" ) ,
170+ WorkingDirectory = Directory . GetParent ( installFile ) ! . FullName ,
171+ Arguments = $ "/i { installFile } /quiet /qn /norestart ALLUSERS=1",
172+ CreateNoWindow = true ,
173+ WindowStyle = ProcessWindowStyle . Hidden ,
174+ UseShellExecute = true ,
175+ Verb = "runas"
176+ } ;
177+
178+ var msiExecutable = Process . Start ( msiExecutableStart ) ;
179+ msiExecutable ! . WaitForExit ( 60000 ) ;
180+ }
181+ catch ( Exception e )
182+ {
183+ progress . Report ( new InstallationProgress
184+ {
185+ IsIndeterminate = true ,
186+ StageTitle =
187+ ( Host ? . RequestLocalizedString ( "/Plugins/Kinect360/Stages/Exceptions/Other" ) ??
188+ "Exception: {0}" ) . Replace ( "{0}" , e . Message )
189+ } ) ;
190+
191+ return false ;
192+ }
193+
194+ return true ;
195+ }
196+ }
197+
198+ internal class NotPoweredFix : IFix
199+ {
200+ public IDependencyInstaller . ILocalizationHost Host { get ; set ; }
201+ public string Name { get ; set ; } // Set in ListFixes()
202+
203+ public bool IsMandatory => false ; // Runtime check (set both to 1 to auto-apply during setup)
204+ public bool IsNecessary => false ; // Runtime check (set both to 1 to auto-apply during setup)
205+ public string InstallerEula => string . Empty ; // Don't show, check the KinectSdk's for reference
206+
207+ public async Task < bool > Apply ( IProgress < InstallationProgress > progress , CancellationToken cancellationToken , object arg = null )
208+ {
209+ if ( ! string . IsNullOrEmpty ( arg as string ) )
210+ throw new Exception ( $ "{ Name } fix failed due to \" { ( string ) arg } \" ") ;
211+
212+ return true ;
213+ }
183214}
0 commit comments