├── .gitignore
├── App.xaml
├── App.xaml.cs
├── Brushes.xaml
├── Commands
└── MenuItemClickCommand.cs
├── Converters
├── BitmapSource2VisibilityConverter.cs
├── BoolToGridRowConverter.cs
├── MenuWidthToMarginConverter.cs
├── NameToResourceConverter.cs
├── PiToTooltipConverter.cs
├── Stretch2BoolConverter.cs
└── TextToBoolConverter.cs
├── DataProviders
├── DriveManager.cs
├── ImageManager.cs
├── ImmersiveApp.cs
├── ImmersiveAppsProvider.cs
├── MfuList.cs
├── NetManager.cs
└── PowerItemTree.cs
├── Helpers
├── API.cs
├── Analytics.cs
├── GATracer.cs
├── Log.cs
├── RemovableFileSystemWatcher.cs
├── SettingsManager.cs
└── Util.cs
├── Images
├── PayPal.gif
├── Pin.png
├── Power8Logo.design
├── Power8Logo_Red.ico
├── Power8Logo_Red16x16.ico
├── Power8Logo_Red48x48.ico
├── Unpin.png
├── logo_alfa
│ ├── Power8Logo7_Blue_alfa.png
│ ├── Power8Logo7_Green_alfa.png
│ ├── Power8Logo7_Red_alfa.png
│ ├── Power8Logo7_alfa.png
│ ├── Power8Logo7_marine_alfa.png
│ ├── Power8Logo7_violet_alfa.png
│ └── Power8Logo7_yellow_alfa.png
└── logo_black
│ ├── Power8Logo7_Blue.png
│ ├── Power8Logo7_Green.png
│ ├── Power8Logo7_Red.png
│ ├── Power8Logo7_black.png
│ ├── Power8Logo7_marine.png
│ ├── Power8Logo7_violet.png
│ └── Power8Logo7_yellow.png
├── P8Installer
├── P8Installer.aip
├── P8Installer.aiproj
└── P8Installer.back.aip
├── Power8-VS2010.sln
├── Power8.csproj
├── Power8.manifest
├── Power8.sln
├── PowerItem.cs
├── Properties
├── AssemblyInfo.cs
├── NoLoc.Designer.cs
├── NoLoc.resx
├── Resources.Designer.cs
├── Resources.ar.resx
├── Resources.cs.resx
├── Resources.de.resx
├── Resources.el.resx
├── Resources.es.resx
├── Resources.fi.resx
├── Resources.fr.resx
├── Resources.hr.resx
├── Resources.hu.resx
├── Resources.it.resx
├── Resources.ko.resx
├── Resources.nl.resx
├── Resources.pt.resx
├── Resources.resx
├── Resources.ro.resx
├── Resources.ru.Designer.cs
├── Resources.ru.resx
├── Resources.sl.resx
├── Resources.sr.resx
├── Resources.sv.Designer.cs
├── Resources.sv.resx
├── Resources.tr.resx
├── Resources.uk.resx
├── Resources.zh-Hans.resx
├── Resources.zh-TW.resx
├── Settings.Designer.cs
└── Settings.settings
├── README.md
├── Styles.xaml
├── Views
├── About.xaml
├── About.xaml.cs
├── BtnStck.xaml
├── BtnStck.xaml.cs
├── ComputerList.xaml
├── ComputerList.xaml.cs
├── ConfirmActionWindow.xaml
├── ConfirmActionWindow.xaml.cs
├── DisposableLinkWindow.cs
├── DisposableWindow.cs
├── Donate.xaml
├── Donate.xaml.cs
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── MenuedButton.xaml
├── MenuedButton.xaml.cs
├── RestartExplorer.Designer.cs
├── RestartExplorer.cs
├── SettingsWnd.xaml
├── SettingsWnd.xaml.cs
├── UpdateNotifier.xaml
├── UpdateNotifier.xaml.cs
├── WelcomeArrow.xaml
└── WelcomeArrow.xaml.cs
└── app.config
/.gitignore:
--------------------------------------------------------------------------------
1 | ################################################################################
2 | # This .gitignore file was automatically created by Microsoft(R) Visual Studio.
3 | ################################################################################
4 |
5 | /obj
6 | *.suo
7 | /P8Installer/P8Installer-cache
8 | /P8Installer/P8Installer-SetupFiles
9 | /bin/Debug
10 | /bin/Release
11 | *.user
12 | /.vs
13 |
--------------------------------------------------------------------------------
/App.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
42 |
43 |
44 |
46 |
48 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Net;
3 | using Power8.Helpers;
4 | using Power8.Views;
5 | using System;
6 | using System.Diagnostics;
7 | using System.IO;
8 | using System.Runtime.InteropServices;
9 | using System.Windows;
10 | using System.Windows.Controls;
11 | using System.Windows.Interop;
12 | #if DEBUG
13 | using System.Runtime.ExceptionServices;
14 | #endif
15 |
16 |
17 | namespace Power8
18 | {
19 | ///
20 | /// Bootstrapper for the application
21 | ///
22 | public partial class App
23 | {
24 | public readonly Process Proc = Process.GetCurrentProcess();
25 |
26 | ///
27 | /// Application initializer. Performs compatibility check,
28 | /// starts diagnostics if required, works settings around,
29 | /// and initializes the process of generating of internal data structures.
30 | ///
31 | public App()
32 | {
33 | if(Util.OsIs.VistaExact) //If run on shit
34 | {
35 | MessageBox.Show(
36 | Power8.Properties.Resources.Err_VistaDetected,
37 | Power8.Properties.NoLoc.Stg_AppShortName, MessageBoxButton.OK, MessageBoxImage.Error);
38 | Environment.Exit(2); //means: OS not found
39 | }
40 | //Global error mode setter - in 1st place to fix nasty startup error on Win10x86
41 | API.SetErrorMode(API.ErrMode.FailCriticalErrors);
42 |
43 | //Power8s in our session but with different pid
44 | foreach (var p in Process.GetProcessesByName("Power8")
45 | .Where(p => p.SessionId == Proc.SessionId && p.Id != Proc.Id))
46 | {
47 | p.Kill();
48 | }
49 |
50 | Util.MainDisp = Dispatcher; //store main thread dispatcher. Widely used in Application.
51 |
52 | #if DEBUG
53 | //System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo("ru");
54 |
55 | //Error handling and detection
56 | var l = new TextWriterTraceListener(Environment.ExpandEnvironmentVariables(@"%temp%\p8log.txt"));
57 | l.Write("\r\n\r\nPower8 Log opened at " + DateTime.Now + "\r\n\r\n");
58 | Debug.AutoFlush = true;
59 | Debug.Listeners.Add(l);
60 | #endif
61 |
62 | DispatcherUnhandledException += (sender, e) => Util.DispatchUnhandledException(e.Exception);
63 | AppDomain.CurrentDomain.UnhandledException += HandleUnhandled;
64 |
65 | ServicePointManager.SecurityProtocol |= (SecurityProtocolType) 3840; //Support for TLS 1.1 and TLS 1.2
66 |
67 | var dbRoot = Util.GetSettingsIndependentDbRoot();
68 | try
69 | {
70 | var ids = Directory.GetFiles(dbRoot, "*" + ClientIDExtension);
71 | string clientId;
72 | if (ids.Length == 0)
73 | {
74 | clientId = Guid.NewGuid().ToString();
75 | File.Create(dbRoot + "\\" + clientId + ClientIDExtension);
76 | }
77 | else
78 | {
79 | clientId = Path.GetFileNameWithoutExtension(ids[0]);
80 | }
81 | Analytics.Init(TrackID, clientId, Power8.Properties.NoLoc.Stg_AppShortName,
82 | Util.GetAppVersion().ToString());
83 | }
84 | catch (Exception ex)
85 | {
86 | Log.Raw("Unable to read client ID to init analytics: " + ex);
87 | }
88 |
89 | //Move settings from previous ver
90 | var std = Power8.Properties.Settings.Default;
91 | if (!std.FirstRunDone)
92 | {
93 | try
94 | {
95 | std.Upgrade();
96 | }
97 | catch (Exception ex)
98 | {
99 | Log.Raw("Unable to upgrade settings: " + ex);
100 | }
101 | std.Save();//FirstRunDone is updated later in Main Window code
102 | Analytics.PostEvent(Analytics.Category.Deploy, std.FirstRunDone ? "Update" : "Fresh", null, 1);
103 | BtnStck.Instanciated += (o, e) => Util.InstanciateClass(t: typeof (Donate));
104 | }
105 |
106 | //Initialize standard folder icon
107 | ImageManager.GetImageContainerSync(new PowerItem { Argument = dbRoot, IsFolder = true }, API.Shgfi.SMALLICON);
108 |
109 | //Build tree
110 | Util.ForkPool(PowerItemTree.InitTree, "InitTree");
111 |
112 | //react on DwmCompositionChanged event
113 | ComponentDispatcher.ThreadFilterMessage += WndProc;
114 | }
115 | ///
116 | /// Gets the running instance of App
117 | ///
118 | public static new App Current
119 | {
120 | get { return (App) Application.Current; }
121 | }
122 |
123 | private const string ClientIDExtension = ".clientid";
124 | private const string TrackID = "UA-30314159-2";
125 |
126 | ///
127 | /// Handles Unhandled appdomain exception and calls the code to write that down everywhere.
128 | /// Undr DEBUG it also catches uncatchable exceptions
129 | ///
130 | #if DEBUG
131 | [HandleProcessCorruptedStateExceptions]
132 | #endif
133 | public void HandleUnhandled(object sender, UnhandledExceptionEventArgs e)
134 | {
135 | Util.DispatchUnhandledException(e.ExceptionObject as Exception);
136 | }
137 |
138 | #region DWM CompositionChanged event
139 |
140 | // ReSharper disable RedundantAssignment
141 | ///
142 | /// App WndProc. Filter. Used only to hande DWMCOMPOSITIONCHANGED event.
143 | ///
144 | /// Structure with message, lparame, wparam, etc.
145 | /// IntPtr wrapped to bool as 1/0. Retval of WndProc.
146 | private void WndProc(ref MSG msg, ref bool handled)
147 | {
148 | if (msg.message == (int)API.WM.DWMCOMPOSITIONCHANGED)
149 | {
150 | var h = DwmCompositionChanged;
151 | if (h != null)
152 | h(this, null);
153 | handled = true;
154 | return;
155 | }
156 | handled = false;
157 | }
158 | // ReSharper restore RedundantAssignment
159 | ///
160 | /// WM_DWMCOMPOSITIONCHANGED converted to event model. e is always null.
161 | /// Sender is this App.
162 | ///
163 | public event EventHandler DwmCompositionChanged;
164 |
165 | #endregion
166 |
167 | //App stores global context menu as resource.
168 | #region Global Context menu
169 |
170 | ///
171 | /// Handles Run/Run As/Open/Open all users folder commands
172 | ///
173 | private void RunRunasOpenOpencommonClick(object sender, RoutedEventArgs e)
174 | {
175 | try
176 | {
177 | var n = ((MenuItem) sender).Name;
178 | if (n == "AppRun" || n == "AppOpenFolder") //TODO: maybe compare byref to menuitems?
179 | Util.ExtractRelatedPowerItem(e).Invoke();
180 | else //Open common folder is also handled via "RunAsAdmin" command. See below.
181 | Util.ExtractRelatedPowerItem(e).InvokeVerb(API.SEVerbs.RunAsAdmin);
182 | //This was done to simplify the implementation. Passing this command switches
183 | //the flag in ResolveItem() that exchanges discovered Common item (if exists)
184 | //with User one. This relates to Start menu _folders_ explicitly and only.
185 | //Along with that, this flag is passed to process start info, regardless of PowerItem
186 | //type (file/folder/link...). That type, however, influences the enabled state of
187 | //menu items, so you shouldn't be able to do something wrong.
188 | }
189 | catch (Exception ex)
190 | {
191 | Util.DispatchCaughtException(ex);
192 | }
193 | }
194 | ///
195 | /// Displays properties of a clicked object. Depending on which item
196 | /// was clicked, the automatic link resolution may take place.
197 | ///
198 | private void ShowPropertiesClick(object sender, RoutedEventArgs e)
199 | {
200 | try
201 | {
202 | var info = new API.ShellExecuteInfo
203 | {
204 | fMask = //need all them for Properties verb
205 | API.SEIFlags.SEE_MASK_INVOKEIDLIST | API.SEIFlags.SEE_MASK_NOCLOSEPROCESS |
206 | API.SEIFlags.SEE_MASK_FLAG_NO_UI | API.SEIFlags.SEE_MASK_NOASYNC,
207 | hwnd = BtnStck.Instance.GetHandle(), //otherwise will be in background
208 | nShow = API.SWCommands.HIDE, //hides some other window, kind of worker one
209 | lpVerb = API.SEVerbs.Properties,
210 | lpFile = Args4PropsAndCont(Util.ExtractRelatedPowerItem(e), ((MenuItem)sender).Name)
211 | };
212 | var executer = new Util.ShellExecuteHelper(info); //Needed to be executed on STA htread
213 | if (!executer.ShellExecuteOnSTAThread())
214 | throw new ExternalException(string.Format(
215 | Power8.Properties.Resources.Err_ShellExecExErrorFormatString, executer.ErrorCode, executer.ErrorText));
216 | }
217 | catch (Exception ex)
218 | {
219 | Util.DispatchCaughtException(ex);
220 | }
221 | }
222 | ///
223 | /// Shows source PowerItem in a folder
224 | ///
225 | private void OpenContainerClick(object sender, RoutedEventArgs e)
226 | {
227 | try
228 | {
229 | Util.StartExplorerSelect(Args4PropsAndCont(Util.ExtractRelatedPowerItem(e), ((MenuItem) sender).Name));
230 | }
231 | catch (Exception ex)
232 | {
233 | Util.DispatchCaughtException(ex);
234 | }
235 | }
236 | ///
237 | /// Handles click on "Remove item". Adds an exclusion to exclusions list.
238 | ///
239 | private void RemoveItemClick(object sender, RoutedEventArgs e)
240 | {
241 | MfuList.AddExclusion(Util.ExtractRelatedPowerItem(e));
242 | }
243 | ///
244 | /// Handles click on "Add item to custom list". Adds an item to user's custom MFU list.
245 | ///
246 | private void IncludeCustom(object sender, RoutedEventArgs e)
247 | {
248 | MfuList.Add2Custom(Util.ExtractRelatedPowerItem(e));
249 | }
250 | ///
251 | /// Handles click on "Remove item from custom list". Removes an item to user's custom MFU list.
252 | ///
253 | private void ExcludeCustom(object sender, RoutedEventArgs e)
254 | {
255 | MfuList.RemoveCustom(Util.ExtractRelatedPowerItem(e));
256 | }
257 | ///
258 | /// Returns string, of a Path kind, that can be passed to a system, and will
259 | /// represent the passed PowerItem. Depending on Caller Name, may invoke
260 | /// automatic Link resolution for Link PowerItems. "Denamespaces" the
261 | /// passed ControlPanel item returning open command for it.
262 | ///
263 | /// The PowerItem which has to be located/properties for
264 | /// which have to be shown.
265 | /// String, the name of clicked menu item, hendler
266 | /// of which is calling this method. Recognizes "AppOpenTargetContainer" and
267 | /// "AppShowTargetProperties".
268 | /// Path to binary FS object that represents the passed PowerItem or
269 | /// the target of its link.
270 | private static string Args4PropsAndCont(PowerItem item, string callerName)
271 | {
272 | string arg = null;
273 | if (item.IsControlPanelChildItem)
274 | {
275 | var executor = Util.GetOpenCommandForClass(item.Argument);
276 | if (executor != null && File.Exists(executor.Item1))
277 | arg = executor.Item1;
278 | }
279 | if (arg == null)
280 | arg = PowerItemTree.GetResolvedArgument(item);
281 | if (item.IsLink && (callerName == "AppOpenTargetContainer"
282 | || callerName == "AppShowTargetProperties"))
283 | arg = item.ResolvedLink;
284 | return arg;
285 | }
286 | ///
287 | /// Gets or sets Data Context for the whole menu. MUST be called in ALL
288 | /// ContextMenuOpening event handlers with something like:
289 | /// App.Current.MDC = Util.ExtractRelatedPowerItem(e);
290 | ///
291 | public object MenuDataContext
292 | {
293 | get { return ((ContextMenu) Resources["fsMenuItemsContextMenu"]).DataContext; }
294 | set { ((ContextMenu) Resources["fsMenuItemsContextMenu"]).DataContext = value; }
295 | }
296 |
297 | #endregion
298 |
299 | }
300 | }
301 |
--------------------------------------------------------------------------------
/Brushes.xaml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/Commands/MenuItemClickCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Input;
3 | using Power8.Properties;
4 | using Power8.Views;
5 |
6 | namespace Power8.Commands
7 | {
8 | ///
9 | /// Standard PowerItem invoker, used thoughout all the menus
10 | /// (not the context menus though). Parameter should be bound to data item.
11 | ///
12 | public class MenuItemClickCommand : ICommand
13 | {
14 | public void Execute(object parameter)
15 | {
16 | var powerItem = parameter as PowerItem;
17 | try
18 | {
19 | if (powerItem == null)
20 | throw new Exception(Resources.Err_NoPiExtracted);
21 | powerItem.Invoke();
22 | }
23 | catch (Exception ex)
24 | {
25 | Util.DispatchCaughtException(ex);
26 | }
27 | BtnStck.Instance.Hide();
28 | }
29 |
30 | public bool CanExecute(object parameter)
31 | {
32 | return true;
33 | }
34 | #pragma warning disable 0067 //Unused event
35 | public event EventHandler CanExecuteChanged;
36 | #pragma warning restore 0067
37 | }
38 | }
--------------------------------------------------------------------------------
/Converters/BitmapSource2VisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Globalization;
4 | using System.Windows;
5 | using System.Windows.Data;
6 | using System.Windows.Media.Imaging;
7 |
8 | namespace Power8.Converters
9 | {
10 | ///
11 | /// This class is used to switch visibility of Main Start Button grids On and Off.
12 | /// It behaves depending on the fact is the value null, and what parameter is passed.
13 | ///
14 | [ValueConversion(typeof(BitmapSource), typeof(Visibility))]
15 | [TypeConverter(typeof(BitmapSource))]
16 | class BitmapSource2VisibilityConverter : IValueConverter
17 | {
18 | ///
19 | /// Converts the fact of value existence and parameter into visibility
20 | ///
21 | /// Something or null. Treat null as false.
22 | /// Not used
23 | /// String, "true" or something else, e.g. "false". The "true"
24 | /// parameter preserves the conversion logic straightforward (needed only for one UI element)
25 | /// and other ones invert it.
26 | /// Not used
27 | /// When using normal logic, returns Visibility.Hidden
when value is null
28 | /// and Visibility.Visible
otherwise. Inverts tre return pair for the inverted
29 | /// logic.
30 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
31 | {
32 | if (((string)parameter) == "true")
33 | return value == null ? Visibility.Hidden : Visibility.Visible;
34 | return value == null ? Visibility.Visible : Visibility.Hidden;
35 | }
36 |
37 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
38 | {
39 | throw new NotImplementedException();
40 | }
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/Converters/BoolToGridRowConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Globalization;
4 | using System.Windows.Data;
5 |
6 | namespace Power8.Converters
7 | {
8 | [ValueConversion(typeof(bool), typeof(int))]
9 | [TypeConverter(typeof(bool))]
10 | class BoolToGridRowConverter : IValueConverter
11 | {
12 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
13 | {
14 | var v = (bool) value; //true means window is above middle of the screen
15 | var p = bool.Parse(((string)parameter) ?? "false"); //true means start menu
16 | return v ^ p ? 2 : 0;
17 | }
18 |
19 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
20 | {
21 | throw new NotImplementedException();
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Converters/MenuWidthToMarginConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Globalization;
4 | using System.Windows;
5 | using System.Windows.Data;
6 | using Power8.Helpers;
7 |
8 | namespace Power8.Converters
9 | {
10 | ///
11 | /// Reimplement system menu style together with control template is too complex task.
12 | /// The data templates were the solution to get rid of Image generator.
13 | /// On the other hand, all data template stuff goes to Content property of MenuItem.
14 | /// So we need to shift data to the left to show Icon properly. Here comes the converter.
15 | /// One way converter. No data/parameters are considered. Returns Thickness shift for
16 | /// current OS.
17 | ///
18 | [ValueConversion(typeof(double), typeof(Thickness))]
19 | [TypeConverter(typeof(double))]
20 | class MenuWidthToMarginConverter : IValueConverter
21 | {
22 | ///
23 | /// Predefined shift values. W8RP hack is because templates and styles are
24 | /// treated in different way on W8.
25 | ///
26 | private static readonly Thickness Classic = new Thickness(-14, 2, 0, 2),
27 | Regular = new Thickness(-30, 0, 0, 0),
28 | W8RPMenuHack = new Thickness(-42, 0, 0, 0);
29 |
30 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
31 | {
32 | var dbl = (int) SystemParameters.MenuWidth;
33 | if (dbl == 18 /*XP/7 Classic*/ || //following is the definition of HighContrast on 8
34 | (Util.OsIs.EightOrMore && !API.DwmIsCompositionEnabled()))
35 | {
36 | return Classic;
37 | }
38 | if (dbl == 19) //Aero/7 basic/XP theme
39 | {
40 | return Util.OsIs.EightRpOrMore ? W8RPMenuHack : Regular;
41 | }
42 | Log.Raw("dbl=" + dbl);
43 | return new Thickness(0, 0, 0, 0);
44 | }
45 |
46 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
47 | {
48 | throw new NotImplementedException();
49 | }
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/Converters/NameToResourceConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Globalization;
4 | using System.Windows.Data;
5 |
6 | namespace Power8.Converters
7 | {
8 | ///
9 | /// There's no easy way to have localization in XAML. MS suggests to use additional proxy class
10 | /// with a number of properties. I dislike this way, so let's just use a converter that is able
11 | /// to find localized content based on element's name (by default) or any other stuff.
12 | /// One way converter. Data: string (usually name of element). Returns (CR_+ data) resource.
13 | ///
14 | [ValueConversion(typeof(string), typeof(string))]
15 | [TypeConverter(typeof(string))]
16 | class NameToResourceConverter:IValueConverter
17 | {
18 | ///
19 | /// Converts the control name given into a localized control text.
20 | ///
21 | /// String, the name of control. "CR_" is added to it and is searched in resources.
22 | /// Not used
23 | /// Not used
24 | /// Not used
25 | /// String to be put into control Content or Text or similar property
26 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
27 | {
28 | return Properties.Resources.ResourceManager.GetString("CR_" + (string) value);
29 | }
30 |
31 | /// Shortcut to be used from the code
32 | /// String, the name of control. "CR_" is added to it and is searched in resources.
33 | /// String to be put into control Content or Text or similar property
34 | public string Convert(string controlName)
35 | {
36 | return (string) Convert(controlName, null, null, null);
37 | }
38 |
39 | /// Not implemented
40 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
41 | {
42 | throw new NotImplementedException();
43 | }
44 |
45 | ///
46 | /// Static instance to be used from code-behind
47 | ///
48 | public static NameToResourceConverter Instance = new NameToResourceConverter();
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Converters/PiToTooltipConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Globalization;
4 | using System.IO;
5 | using System.Windows.Data;
6 | using Power8.Properties;
7 |
8 | namespace Power8.Converters
9 | {
10 | ///
11 | /// This converter tries to get tooltip fo PowerItem passed in various ways. In general,
12 | /// it is the resolved argument of PowerItem, but other options available as well.
13 | /// One-way converter. Data: PowerItem. Returns: the descriptive tooltip.
14 | /// 2nd option: when "pin" is passed as parameter, returns pinned/unpinned string
15 | /// for boolean passed as data item.
16 | ///
17 | [ValueConversion(typeof(PowerItem), typeof(string))]
18 | [TypeConverter(typeof(PowerItem))]
19 | class PiToTooltipConverter : IValueConverter
20 | {
21 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
22 | {
23 | if (parameter != null && (string)parameter == "pin")
24 | return (bool?) value == true ? Resources.Str_Unpin : Resources.Str_Pin;
25 | var pi = value as PowerItem;
26 | if (pi == null)
27 | return Resources.Err_CantGetTooltip;
28 | if (!pi.IsNotPureControlPanelFlowItem)
29 | return Resources.Str_CplElement;
30 | if (pi.IsSpecialObject)
31 | {
32 | var cmd = Util.GetOpenCommandForClass(pi.Argument);
33 | return cmd == null ? pi.FriendlyName + GetSuffixForSpecialObject(pi) : cmd.Item1;
34 | }
35 | try
36 | {
37 | return PowerItemTree.GetResolvedArgument(pi);
38 | }
39 | catch (IOException)
40 | {
41 | return Resources.Err_CantGetTooltip;
42 | }
43 | }
44 |
45 | private static string GetSuffixForSpecialObject(PowerItem item)
46 | {
47 | if (item.IsLibrary) return Resources.Str_Library;
48 | if (item.SpecialFolderId == API.Csidl.POWER8IMMERSIVE) return " (" + item.Argument + ")";
49 | return null;
50 | }
51 |
52 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
53 | {
54 | throw new NotImplementedException();
55 | }
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/Converters/Stretch2BoolConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Globalization;
4 | using System.Windows.Data;
5 | using System.Windows.Media;
6 |
7 | namespace Power8.Converters
8 | {
9 | ///
10 | /// This class is used to switch UseLayoutRounding on Image of MainButton
11 | /// to True when "No scale" chosen by user in app settings. This makes picture sharper
12 | /// but makes no sense when applied to scaled image.
13 | ///
14 | [ValueConversion(typeof(Stretch), typeof(bool))]
15 | [TypeConverter(typeof(Stretch))]
16 | class Stretch2BoolConverter : IValueConverter
17 | {
18 | ///
19 | /// Returns true when Stretch.None is passed.
20 | ///
21 | /// System.Windows.Media.Stretch of image chosen.
22 | /// Not used
23 | /// Not used
24 | /// Not used
25 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
26 | {
27 | return ((Stretch) value) == Stretch.None;
28 | }
29 |
30 | ///
31 | /// Not implemented
32 | ///
33 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
34 | {
35 | throw new NotImplementedException();
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Converters/TextToBoolConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Globalization;
4 | using System.Windows.Data;
5 |
6 | namespace Power8.Converters
7 | {
8 | ///
9 | /// This converter returns !String.IsNullOrWhiteSpace(of value passed)
10 | /// Used to dynamically enabled/disable UI elements in case they're logically tied to
11 | /// some textual field
12 | ///
13 | [ValueConversion(typeof(String), typeof(Boolean))]
14 | [TypeConverter(typeof(String))]
15 | class TextToBoolConverter : IValueConverter
16 | {
17 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
18 | {
19 | return !String.IsNullOrWhiteSpace((string)value);
20 | }
21 |
22 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
23 | {
24 | throw new NotImplementedException();
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/DataProviders/ImageManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Concurrent;
4 | using System.IO;
5 | using System.Runtime.InteropServices;
6 | using System.Threading;
7 | using System.Windows.Interop;
8 | using System.Windows.Media;
9 | using System.Windows.Media.Imaging;
10 | using Power8.Helpers;
11 |
12 | namespace Power8
13 | {
14 | ///
15 | /// Maintains cached lists of icons, resolves icons from resources and so on...
16 | ///
17 | public static class ImageManager
18 | {
19 | //Image cache
20 | private static readonly Hashtable Cache = new Hashtable();
21 | //Image processing queue
22 | private static readonly ConcurrentQueue> ImageQueue =
23 | new ConcurrentQueue>();
24 |
25 | static ImageManager()
26 | {
27 | Util.ForkStart(ImageProcessor, "Image processsor");
28 | }
29 |
30 | private static void ImageProcessor()
31 | {
32 | begin:
33 |
34 | while (ImageQueue.Count > 0)
35 | {
36 | Tuple e;
37 | if (ImageQueue.TryDequeue(out e))
38 | {
39 | var asyncContainer = GetImageContainerSync(e.Item1, e.Item2);
40 | Util.Send(() => e.Item1.Icon = asyncContainer);
41 | }
42 | else
43 | {
44 | break;
45 | }
46 | }
47 |
48 | if (!Util.MainDisp.HasShutdownStarted)
49 | {
50 | Thread.Sleep(333);
51 | goto begin; //just don't want unneeded code nesting here, anyway IL will be same.
52 | }
53 | }
54 |
55 | ///
56 | /// Gets a string that represents a kind of tag for icon for PowerItem passed
57 | ///
58 | /// PowerItem which we need icon for
59 | /// Resolved argument for item.
60 | private static string GetObjectDescriptor(PowerItem item, string resolved)
61 | {
62 | if (item.IsFolder || item.IsSpecialObject)
63 | return item.NonCachedIcon ? resolved : "*";
64 | var rl = resolved.ToLower();
65 | return rl.EndsWith(".lnk")
66 | || rl.EndsWith(".exe")
67 | || rl.EndsWith(".cpl")
68 | ? resolved : Path.GetExtension(resolved);
69 | }
70 |
71 | ///
72 | /// Starts asynchronous extraction of ImageContainer for PowerItem
73 | ///
74 | /// PowerItem we need icon extracted for
75 | /// type of icon needed - small or large
76 | /// Always null
77 | public static ImageContainer GetImageContainer(PowerItem item, API.Shgfi iconNeeded)
78 | {
79 | ImageQueue.Enqueue(new Tuple(item, iconNeeded));
80 | return null;
81 | }
82 |
83 | ///
84 | /// Synchronous getter of an icon for PowerItem
85 | ///
86 | /// PowerItem we need icon extracted for
87 | /// type of icon needed - small or large
88 | /// ImageContainer with ImageSources extracted. Can be null.
89 | public static ImageContainer GetImageContainerSync(PowerItem item, API.Shgfi iconNeeded)
90 | {
91 | Log.Raw("begin>>>>>>>>>>>>>>>", item.FriendlyName);
92 | //Checking if there's cached ImageContainer
93 | string resolvedArg, descr;
94 | try
95 | {
96 | resolvedArg = PowerItemTree.GetResolvedArgument(item);
97 | descr = GetObjectDescriptor(item, resolvedArg);
98 | }
99 | catch (IOException)
100 | {
101 | return null;
102 | }
103 | lock (Cache)
104 | {
105 | var container = (ImageContainer)(Cache.ContainsKey(descr) ? Cache[descr] : null);
106 | Log.Fmt("arg<={0}, descr<={1}, container<={2}", resolvedArg, descr,
107 | (container != null ? "not " : "") + "null");
108 | if (container == null) //No cached instance
109 | {
110 | container = new ImageContainer(resolvedArg, descr, item.SpecialFolderId);
111 | Cache.Add(descr, container);
112 | if (iconNeeded == API.Shgfi.SMALLICON)
113 | container.ExtractSmall();
114 | else
115 | container.ExtractLarge();
116 | }
117 | #if DEBUG
118 | Log.Raw("end<<<<<<<<<<<<<<", item.FriendlyName);
119 | #endif
120 | return container;
121 | }
122 | }
123 | //todo: change description
124 | ///
125 | /// Returns ImageContainer for hIcon provided
126 | ///
127 | /// Object description, tag, under which the container will be stored in cache
128 | /// HICON you obtained after some unmanaged interactions. DestroyIcon() is NOT being
129 | /// called automatically
130 | /// ImageContainer with ImageSource`s for the given hIcon
131 | public static ImageContainer GetImageContainerForIconSync(string description, IntPtr unmanagedIcon)
132 | {
133 | Log.Raw("Wrapping HICON " + unmanagedIcon, description);
134 | lock (Cache)
135 | {
136 | if (Cache.ContainsKey(description))
137 | return (ImageContainer)Cache[description];
138 | var container = unmanagedIcon == IntPtr.Zero
139 | ? new ImageContainer(description)
140 | : new ImageContainer(unmanagedIcon);
141 | Cache.Add(description, container);
142 | return container;
143 | }
144 | }
145 |
146 |
147 | ///
148 | /// Holds the cached instance of bitmap sources for big and large icons to be displayed.
149 | /// Can automatically extract icons from the file or special object given.
150 | ///
151 | public class ImageContainer
152 | {
153 | // ReSharper disable NotAccessedField.Local
154 | private readonly string _objectDescriptor; //needed for debug purposes
155 | // ReSharper restore NotAccessedField.Local
156 | private readonly string _initialObject; //Path to file or special object
157 | private readonly API.Csidl _id; //SpecialFolderId from source PowerItem, if any
158 | private ImageSource _smallBitmap, _largeBitmap;
159 | private bool _smallExtracted, _largeExtracted;
160 | private Brush _background = Brushes.Transparent, _foreground = Brushes.Black;
161 |
162 | ///
163 | /// Gets 16x16 BitmapSource-representation of target icon
164 | ///
165 | public ImageSource SmallBitmap
166 | {
167 | get
168 | {
169 | if (!_smallExtracted)
170 | ExtractSmall();
171 | return _smallBitmap;
172 | }
173 | private set { _smallBitmap = value; }
174 | }
175 | ///
176 | /// Gets 32x32 BitmapSource-representation of target icon
177 | ///
178 | public ImageSource LargeBitmap
179 | {
180 | get
181 | {
182 | if (!_largeExtracted)
183 | ExtractLarge();
184 | return _largeBitmap;
185 | }
186 | private set { _largeBitmap = value; }
187 | }
188 |
189 | ///
190 | /// Constructs the instance of ImageContainer from data from PowerItem
191 | ///
192 | /// Path to file or special object
193 | /// Tag that will be set in cache for this ImageContainer. Used for debugging.
194 | /// SpecialFolderId from source PowerItem
195 | public ImageContainer(string objectToGetIcons, string typeDescriptor, API.Csidl specialId)
196 | {
197 | _initialObject = objectToGetIcons;
198 | _objectDescriptor = typeDescriptor;
199 | _id = specialId;
200 | }
201 | ///
202 | /// Constructs the instance of ImageContainer from the HICON extracted already
203 | ///
204 | /// HICON you have already extracted
205 | public ImageContainer(IntPtr unmanagedIcon)
206 | {
207 | SmallBitmap = ExtractInternal(unmanagedIcon);
208 | LargeBitmap = SmallBitmap;
209 | }
210 | ///
211 | /// Constructs the instance of ImageContainer for existing image file
212 | ///
213 | /// path to image file
214 | public ImageContainer(string imagePath)
215 | {
216 | SmallBitmap = ExtractInternal(imagePath);
217 | LargeBitmap = SmallBitmap;
218 | }
219 |
220 | ///
221 | /// Extracts 16*16 icon when ImageContainer is constructed with PowerItem data
222 | ///
223 | public void ExtractSmall()
224 | {
225 | if (_smallBitmap != null)
226 | return;
227 | var smallIconHandle = GetUnmanagedIcon(API.Shgfi.SMALLICON);
228 | if (smallIconHandle != IntPtr.Zero)
229 | {
230 | SmallBitmap = ExtractInternal(smallIconHandle);
231 | SmallBitmap.Freeze();
232 | Util.PostBackgroundIconDestroy(smallIconHandle);
233 | }
234 | #if DEBUG
235 | else
236 | {
237 | Log.Raw("FAILED with code " + Marshal.GetLastWin32Error(), _initialObject);
238 | }
239 | #endif
240 | _smallExtracted = true;
241 | }
242 | ///
243 | /// Extracts 32*32 icon when ImageContainer is constructed with PowerItem data
244 | ///
245 | public void ExtractLarge()
246 | {
247 | if(_largeBitmap != null)
248 | return;
249 | var largeIconHandle = GetUnmanagedIcon(API.Shgfi.LARGEICON);
250 | if (largeIconHandle != IntPtr.Zero)
251 | {
252 | LargeBitmap = ExtractInternal(largeIconHandle);
253 | LargeBitmap.Freeze();
254 | Util.PostBackgroundIconDestroy(largeIconHandle);
255 | }
256 | #if DEBUG
257 | else
258 | {
259 | Log.Raw("FAILED with code " + Marshal.GetLastWin32Error(), _initialObject);
260 | }
261 | #endif
262 | _largeExtracted = true;
263 | }
264 |
265 | ///
266 | /// Converts HICON to BitmapSource, without calling of DestroyIcon()
267 | ///
268 | /// HICON that is already extracted
269 | private static BitmapSource ExtractInternal(IntPtr handle)
270 | {
271 | var bs = Imaging.CreateBitmapSourceFromHIcon(handle, System.Windows.Int32Rect.Empty,
272 | BitmapSizeOptions.FromEmptyOptions());
273 | bs.Freeze();
274 | return bs;
275 | }
276 |
277 | ///
278 | /// Returns BitmapSource for image file
279 | ///
280 | /// path to image file
281 | private static BitmapSource ExtractInternal(string imagePath)
282 | {
283 | var bs = new BitmapImage(new Uri(imagePath));
284 | bs.Freeze();
285 | return bs;
286 | }
287 | ///
288 | /// Returns HICON of provided size (or of default size if requested one isn't available)
289 | ///
290 | ///
291 | private IntPtr GetUnmanagedIcon(API.Shgfi iconType)
292 | {
293 | Log.Raw("begin", _initialObject);
294 | //Way 1, straightforward: "Hey shell, give me an icon for that file!"
295 | var shinfo = new API.ShfileinfoW();
296 | var zeroFails = API.SHGetFileInfo(_initialObject, 0, ref shinfo, (uint) Marshal.SizeOf(shinfo), API.Shgfi.ICON | iconType);
297 | Log.Raw("ShGetFileInfo returned " + zeroFails);
298 | if (zeroFails == IntPtr.Zero) //lot of stuff will work via this
299 | {
300 | //Shell failed
301 | //Way 2: way around: "Hey registry, and how should display the stuff of a kind?"
302 | var temp = Util.GetDefaultIconResourceIdForClass(_initialObject);
303 | Log.Raw("GetDefaultIconResourceIdForClass returned " + (temp ?? "NULL!!"));
304 | if (!string.IsNullOrEmpty(temp))
305 | {
306 | zeroFails = Util.ResolveIconicResource(temp);
307 | Log.Raw("ResolveIconicResource returned " + zeroFails);
308 | }
309 | if(zeroFails != IntPtr.Zero)//ResolveIconicResource() succeeded and zeroFails contains required handle
310 | {
311 | shinfo.hIcon = zeroFails;
312 | }
313 | else if (_id != API.Csidl.INVALID)//For PowerItems initialized without argument but with folderId
314 | {//No icon, or Registry doesn't know
315 | //Way 3, cumbersome: "Hey shell, I know that stuff means something for ya. Give me the icon for the thing this staff means!"
316 | var ppIdl = IntPtr.Zero;
317 | var hRes = API.SHGetSpecialFolderLocation(IntPtr.Zero, _id, ref ppIdl); //I know, obsolete, but works ;)
318 | Log.Fmt("SHGetSp.F.Loc. for id<={0} returned result code {1}", _id, hRes);
319 | zeroFails = (hRes != 0
320 | ? IntPtr.Zero
321 | : API.SHGetFileInfo(ppIdl, 0, ref shinfo, (uint) Marshal.SizeOf(shinfo),
322 | API.Shgfi.ICON | API.Shgfi.PIDL | API.Shgfi.USEFILEATTRIBUTES | iconType));
323 | Marshal.FreeCoTaskMem(ppIdl);
324 | Log.Raw("ShGetFileInfo (2p) returned " + zeroFails);
325 | }
326 | }
327 | Log.Fmt("end<<<<<, zf={0}, hi={1}", zeroFails, shinfo.hIcon);
328 | return zeroFails == IntPtr.Zero || shinfo.hIcon == IntPtr.Zero ? IntPtr.Zero : shinfo.hIcon;
329 | }
330 |
331 | public Brush Background
332 | {
333 | get { return _background; }
334 | set { _background = value; }
335 | }
336 |
337 | public Brush Foreground
338 | {
339 | get { return _foreground; }
340 | set { _foreground = value; }
341 | }
342 | }
343 | }
344 | }
345 |
--------------------------------------------------------------------------------
/DataProviders/ImmersiveApp.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Windows.Media;
5 |
6 | namespace Power8.DataProviders
7 | {
8 | public class ImmersiveApp
9 | {
10 | public string ApplicationCompany { get; set; }
11 | public string ApplicationDescription { get; set; }
12 | //----
13 | public string ApplicationName { get; set; }
14 | public string ApplicationDisplayName { get; set; }
15 |
16 | public string DisplayName
17 | {
18 | get { return string.IsNullOrWhiteSpace(ApplicationDisplayName) ? ApplicationName : ApplicationDisplayName; }
19 | }
20 |
21 | public string AppUserModelID { get; set; }
22 | public string PackageId { get; set; }
23 | //------
24 | public string ApplicationPath { get; set; }
25 | public string File { get; set; }
26 | //------
27 | public string Logo
28 | {
29 | get { return Logos.Count > 0 ? Logos.First().Value : null; }
30 | }
31 | public Dictionary Logos { get; set; }
32 | public Color Background { get; set; }
33 | public Color Foreground { get; set; }
34 | public Brush BackgroundBrush { get { return new SolidColorBrush(Background); } }
35 | public Brush ForegroundBrush { get { return new SolidColorBrush(Foreground); } }
36 | public string DisplayState { get; set; }
37 |
38 | private readonly string[] _blackList = { "Windows.ImmersiveControlPanel", "Microsoft.Windows.Cortana", "BrowserChoice" };
39 | public bool IsSystemApp()
40 | {
41 | return DisplayState == "none" || _blackList.Any(bl => PackageId.StartsWith(bl, StringComparison.OrdinalIgnoreCase));
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/DataProviders/NetManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Management;
4 | using System.Net;
5 | #if !DEBUG
6 | using System.DirectoryServices;
7 | using System.Linq;
8 | #endif
9 | using Power8.Helpers;
10 |
11 | namespace Power8
12 | {
13 | ///
14 | /// Provides data related to the network activity PC might have
15 | ///
16 | static class NetManager
17 | {
18 | private static string _host, _wg;
19 |
20 | ///
21 | /// Gets the computer name
22 | ///
23 | public static string Hostname
24 | {
25 | get { return _host ?? (_host = Dns.GetHostName()); }
26 | }
27 |
28 | ///
29 | /// Gets the name of domain or workgroup
30 | ///
31 | public static string DomainOrWorkgroup
32 | {
33 | get
34 | {
35 | if (_wg == null)
36 | {
37 | try
38 | {
39 | using (var m = new ManagementObjectSearcher("select Domain from Win32_ComputerSystem"))
40 | using (var e = m.Get().GetEnumerator())
41 | {
42 | if (e.MoveNext())
43 | _wg = e.Current.GetPropertyValue("Domain").ToString();
44 | }
45 | }
46 | catch (Exception ex){Log.Raw(ex.Message);}
47 | finally
48 | {
49 | if (string.IsNullOrWhiteSpace(_wg)) //modern
50 | _wg = Environment.GetEnvironmentVariable("USERDOMAIN");
51 | if (string.IsNullOrWhiteSpace(_wg)) //old
52 | _wg = Environment.GetEnvironmentVariable("COMPUTERNAME");
53 | }
54 | }
55 | return _wg;
56 | }
57 | }
58 |
59 | private static readonly List ComputerNames = new List();
60 | ///
61 | /// Returns the list of UPPERCASED computer names which are visible in domain or workgroup.
62 | /// In debug, returns "Computer1"..."Computer3000"
63 | ///
64 | public static List ComputersNearby
65 | {
66 | get
67 | {
68 | if (ComputerNames.Count == 0)
69 | {
70 | #if DEBUG
71 | for (int i = 0; i < 3000; i++)
72 | {
73 | ComputerNames.Add("COMPUTER" + i);
74 | }
75 | #else
76 | try
77 | {
78 | using (var workgroup = new DirectoryEntry("WinNT://" + DomainOrWorkgroup))
79 | {
80 | ComputerNames.AddRange(workgroup.Children
81 | .Cast()
82 | .Where(e => e.SchemaClassName == "Computer")
83 | .Select(e => e.Name.ToUpper()));
84 | }
85 | }
86 | catch (Exception ex)
87 | {
88 | Util.DispatchCaughtException(ex);
89 | ComputerNames.Add(Hostname);
90 | }
91 | #endif
92 | }
93 | return ComputerNames;
94 | }
95 | }
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/Helpers/Analytics.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.Specialized;
4 | using System.Net;
5 | using System.Text;
6 | using System.Threading;
7 |
8 | namespace Power8.Helpers
9 | {
10 | public static class Analytics
11 | {
12 | private static AnalyticsClient _web;
13 |
14 | public static void Init(string trackingId, string clientId, string appName, string appVersion)
15 | {
16 | _web = new AnalyticsClient(trackingId, clientId, appName, appVersion);
17 | }
18 |
19 | public static void PostEvent(Category category, string action, string label, int? value)
20 | {
21 | AnalyticsCallAsync("event", new Dictionary
22 | {
23 | {"ec", category.ToString()},
24 | {"ea", Cut(action, 500)},
25 | {"el", Cut(label, 500)},
26 | {"ev", value.HasValue ? value.ToString() : null}
27 | });
28 | }
29 |
30 | public static void PostException(Exception ex, bool isFatal)
31 | {
32 | var exType =
33 | #if DEBUG
34 | "DBG" +
35 | #endif
36 | ex.GetType().Name;
37 |
38 | AnalyticsCallAsync("exception", new Dictionary
39 | {
40 | {"exd", Cut(exType, 150)},
41 | {"exf", isFatal ? "1" : "0"}
42 | });
43 |
44 | if (isFatal)
45 | {
46 | PostEvent(Category.Error, exType, ex.ToString(), null);
47 | }
48 | }
49 |
50 | private static string Cut(String original, int maxLength)
51 | {
52 | if (original == null)
53 | return null;
54 | return original.Length > maxLength ? original.Substring(0, maxLength) : original;
55 | }
56 |
57 | public enum Category
58 | {
59 | Deploy, Runtime, Error
60 | }
61 |
62 | private static void AnalyticsCallAsync(string hitType, Dictionary args)
63 | {
64 | if (_web == null)
65 | {
66 | Log.Raw("Analytics subsystem is not initialized");
67 | return;
68 | }
69 | Util.ForkPool(() =>
70 | {
71 | try
72 | {
73 | lock (_web)
74 | {
75 | var result = _web.PostAnalyticsHit(hitType, args);
76 | Log.Fmt("Code: {0}, data: {1}", _web.ResponseCode, new string(Encoding.Default.GetChars(result)).Replace('\0', ' '));
77 | }
78 | }
79 | catch (Exception ex)
80 | {
81 | Log.Raw(ex.ToString());
82 | }
83 | }, "Google Analytics call for " + hitType);
84 | }
85 |
86 | private class AnalyticsClient : WebClient
87 | {
88 | public AnalyticsClient(string resourceId, string clientId, string appName, string appVersion)
89 | {
90 | Encoding = Encoding.UTF8;
91 | _resourceId = resourceId;
92 | _clientId = clientId;
93 | _appName = appName;
94 | _appVer = appVersion;
95 | Headers[HttpRequestHeader.UserAgent] =
96 | string.Format("{0}/{1} ({2})", _appName, _appVer, Environment.OSVersion);
97 | _responseCodeHolder = new ThreadLocal();
98 | }
99 | public byte[] PostAnalyticsHit(string hitType, Dictionary hitArgs)
100 | {
101 | var data = new NameValueCollection();
102 | data["v"] = "1";
103 | data["tid"] = _resourceId;
104 | data["cid"] = _clientId;
105 | data["an"] = _appName;
106 | data["av"] = _appVer;
107 | data["t"] = hitType;
108 | data["ul"] = Thread.CurrentThread.CurrentUICulture.Name;
109 | if (1 == Interlocked.CompareExchange(ref _sessionStarting, 0, 1))
110 | {
111 | data["sc"] = "start";
112 | }
113 | foreach (var a in hitArgs)
114 | {
115 | if (a.Value != null)
116 | data[a.Key] = a.Value;
117 | }
118 | return UploadValues(@"https://ssl.google-analytics.com/collect", WebRequestMethods.Http.Post, data);
119 | }
120 |
121 | public HttpStatusCode ResponseCode
122 | {
123 | get
124 | {
125 | return _responseCodeHolder.Value;
126 | }
127 | private set
128 | {
129 | _responseCodeHolder.Value = value;
130 | }
131 | }
132 |
133 | private readonly ThreadLocal _responseCodeHolder;
134 | private readonly string _resourceId, _clientId, _appName, _appVer;
135 |
136 | protected override WebResponse GetWebResponse(WebRequest request)
137 | {
138 | var resp = base.GetWebResponse(request);
139 | var hResp = resp as HttpWebResponse;
140 | if (hResp != null)
141 | {
142 | ResponseCode = hResp.StatusCode;
143 | }
144 | return resp;
145 | }
146 |
147 | private int _sessionStarting = 1;
148 | }
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/Helpers/GATracer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Text;
5 |
6 | namespace Power8.Helpers
7 | {
8 | public class GATracer: Exception
9 | {
10 | private readonly int _id;
11 | private readonly Exception _original;
12 | private readonly Dictionary _data;
13 | private GATracer(int id, Exception original, Dictionary traceData)
14 | {
15 | _id = id;
16 | _original = original;
17 | _data = traceData;
18 | }
19 |
20 | public override string ToString()
21 | {
22 | var b = new StringBuilder("TID:");
23 | b.Append(_id).Append(".");
24 | foreach (var data in _data)
25 | {
26 | b.AppendFormat("{0}:{1};", data.Key, data.Value);
27 | }
28 | b.Append("@");
29 | int pos = 0, len = 0;
30 | bool first = true;
31 | var orig = _original.ToString();
32 | using (var r = new StringReader(orig))
33 | {
34 | do
35 | {
36 | var l = r.ReadLine() ?? string.Empty;
37 | if (l.Contains("Power8"))
38 | break;
39 | if (first)
40 | first = false;
41 | else
42 | pos += len; //position of PRE-last line
43 | len = l.Length; //length of LAST line
44 | len += Environment.NewLine.Length;
45 | } while (r.Peek() > -1);
46 | }
47 | if (pos < orig.Length)
48 | b.Append(orig.Substring(pos));
49 | b.Append(_original);
50 | return b.ToString();
51 | }
52 |
53 | public static void PostTraceData(Trace id, Exception original, Dictionary traceData)
54 | {
55 | Analytics.PostException(new GATracer((int)id, original, traceData), true);
56 | }
57 |
58 | public enum Trace
59 | {
60 | ArgumentExceptionInScanFolderSync,
61 | Win32ExceptionInRestart,
62 | Next
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Helpers/Log.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Text;
4 | using System.Threading;
5 |
6 | namespace Power8.Helpers
7 | {
8 | public static class Log
9 | {
10 | ///
11 | /// Logs message passed to the current debug log.
12 | /// Prepends calling method name, date, time and thread id.
13 | /// Optionally adds info on object which the callee was invoked to serve for.
14 | ///
15 | /// Text to log
16 | /// Description or name of the object calling method is working on.
17 | /// If the method doesn't serve any particular object at the moment, leave it unset.
18 | [Conditional("DEBUG")]
19 | public static void Raw(string message, string obj = null)
20 | {
21 | var b = new StringBuilder(DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss.ffff\t"));
22 | var mtd = new StackTrace().GetFrame(obj == string.Empty ? 2 : 1).GetMethod();
23 | var loc = mtd.DeclaringType == null ? "global" : mtd.DeclaringType.Name;
24 | b.AppendFormat("{0}\t{1}::{2}", Thread.CurrentThread.ManagedThreadId, loc, mtd.Name);
25 | if(!string.IsNullOrEmpty(obj))
26 | b.Append(" for " + obj);
27 | b.Append("\t" + message);
28 | Debug.WriteLine(b.ToString());
29 | }
30 | ///
31 | /// Logs message passed to the current debug log.
32 | /// Prepends calling method name, date, time and thread id.
33 | ///
34 | /// Format string as used by String.Format().
35 | /// Format string args as used by String.Format().
36 | [Conditional("DEBUG")]
37 | public static void Fmt(string format, params object[] args)
38 | {
39 | Raw(string.Format(format, args), string.Empty);
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Helpers/RemovableFileSystemWatcher.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Linq;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace Power8.Helpers
7 | {
8 | ///
9 | /// This is the FileSystemWatcher that can react on the system "undock device" notifications.
10 | /// To work it requires:
11 | /// 1) a window with WndProc to Register the notifications
12 | /// 2) this window to call ProcessDeviceNotification when corresponding event arrives
13 | /// Currently this bind is done via DriveManager.
14 | ///
15 | class RemovableFileSystemWatcher : FileSystemWatcher
16 | {
17 | private readonly IntPtr _reporter;
18 | ///
19 | /// Constructor
20 | ///
21 | /// Root of what to watch. See parent class docs for help
22 | /// on this parameter.
23 | /// HWND of the window that will be used as reporting
24 | /// proxy. See ProcessDeviceNotification() method documentation, and also the
25 | /// DriveManager class for more info.
26 | public RemovableFileSystemWatcher(string path, IntPtr reportingHwnd) : base(path)
27 | {
28 | _reporter = reportingHwnd;
29 | }
30 |
31 | new public bool EnableRaisingEvents
32 | {
33 | get { return base.EnableRaisingEvents; }
34 | set
35 | {
36 | Log.Raw("Value passed: " + value);
37 | base.EnableRaisingEvents = value;
38 | if (value) Lock();
39 | else Unlock();
40 | }
41 | }
42 |
43 | private IntPtr _hNotification = IntPtr.Zero, _hDrive = IntPtr.Zero;
44 | private static readonly IntPtr InvalidHandle = new IntPtr(-1);
45 |
46 | private void Unlock()
47 | {
48 | if (_hNotification != IntPtr.Zero)
49 | {
50 | API.UnregisterDeviceNotification(_hNotification);
51 | _hNotification = IntPtr.Zero;
52 | }
53 | if (_hDrive != IntPtr.Zero)
54 | {
55 | API.CloseHandle(_hDrive);
56 | _hDrive = IntPtr.Zero;
57 | }
58 | Log.Raw("Unlocked " + Path);
59 | }
60 |
61 | private void Lock()
62 | {
63 | var file = API.CreateFile(string.Format(@"\\.\{0}:", Path[0]),
64 | API.FileAccessRights.GENERIC_READ,
65 | FileShare.ReadWrite,
66 | IntPtr.Zero,
67 | FileMode.Open,
68 | API.CreateFileOptions.FILE_OPTIONS_NOT_SET,
69 | IntPtr.Zero);
70 | if (file == IntPtr.Zero || file == InvalidHandle)
71 | {
72 | Log.Raw("Cannot CreateFile " + Path);
73 | return; //might be real fixed drive
74 | }
75 |
76 | _hDrive = file;
77 |
78 | var msg = new API.DEV_BROADCAST_HANDLE { dbch_handle = file };
79 | _hNotification = API.RegisterDeviceNotification(_reporter, msg, API.RDNFlags.DEVICE_NOTIFY_WINDOW_HANDLE);
80 |
81 | if (_hNotification == IntPtr.Zero || _hNotification == InvalidHandle)
82 | {
83 | Log.Raw("Cannot lock " + Path);
84 | Unlock(); //this drive appears to be non-notifiable
85 | }
86 | else
87 | {
88 | Log.Raw("Locked " + Path);
89 | }
90 | }
91 |
92 | ///
93 | /// This method must be called from the WndProcof a window identified by HWND passed to
94 | /// constructor of this class in case of WM_DEVICECHANGE event occurs. See DriveManager
95 | /// class for more details on parameters.
96 | ///
97 | /// The wParam from message, as is
98 | /// The lParam from message, as is
99 | /// Logical value, indicating whether this instance should be the last one
100 | /// that processes the message. True may be returned because the message itself doesn't
101 | /// satisfy the requirements of a class, or because this instance is identified itself
102 | /// against the message and performed targeted processing. False means that the message
103 | /// should be also passed for processing to some other instance of this class within the
104 | /// application.
105 | public bool ProcessDeviceNotification(IntPtr wParam, IntPtr lParam)
106 | {
107 | var code = (API.DeviceChangeMessages) wParam;
108 |
109 | switch (code)
110 | {
111 | case API.DeviceChangeMessages.DBT_DEVICEQUERYREMOVE:
112 | case API.DeviceChangeMessages.DBT_DEVICEQUERYREMOVEFAILED:
113 | case API.DeviceChangeMessages.DBT_CUSTOMEVENT:
114 | return Process(code, lParam);
115 | default:
116 | return true;
117 | }
118 | }
119 |
120 | private bool Process(API.DeviceChangeMessages wParam, IntPtr lParam)
121 | {
122 | var o = new API.DEV_BROADCAST_HANDLE();
123 | if (lParam != IntPtr.Zero) Marshal.PtrToStructure(lParam, o);
124 |
125 | if (o.dbch_hdevnotify != _hNotification)
126 | {
127 | return false;
128 | }
129 |
130 | Log.Fmt("Device event {0}, custom event guid {1}", wParam, o.dbch_eventguid);
131 |
132 | switch (wParam)
133 | {
134 | case API.DeviceChangeMessages.DBT_DEVICEQUERYREMOVE:
135 | EnableRaisingEvents = false;
136 | break;
137 | case API.DeviceChangeMessages.DBT_DEVICEQUERYREMOVEFAILED:
138 | EnableRaisingEvents = true;
139 | break;
140 | case API.DeviceChangeMessages.DBT_CUSTOMEVENT:
141 | if (API.DevEvent.Queryable.Contains(o.dbch_eventguid))
142 | {
143 | EnableRaisingEvents = false;
144 | }
145 | else if (API.DevEvent.Failed.Contains(o.dbch_eventguid))
146 | {
147 | EnableRaisingEvents = true;
148 | }
149 | break;
150 | }
151 | return true;
152 | }
153 |
154 | protected override void Dispose(bool disposing)
155 | {
156 | Log.Raw("Dispose called");
157 | try
158 | {
159 | Unlock();
160 | }
161 | finally
162 | {
163 | base.Dispose(disposing);
164 | WasDisposed = true;
165 | }
166 | }
167 |
168 | public bool WasDisposed { get; private set; }
169 | }
170 | }
--------------------------------------------------------------------------------
/Images/PayPal.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgentMC/power8/ed47d2dd8ec2ba7a5092e910d26a411a95de123b/Images/PayPal.gif
--------------------------------------------------------------------------------
/Images/Pin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgentMC/power8/ed47d2dd8ec2ba7a5092e910d26a411a95de123b/Images/Pin.png
--------------------------------------------------------------------------------
/Images/Power8Logo.design:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgentMC/power8/ed47d2dd8ec2ba7a5092e910d26a411a95de123b/Images/Power8Logo.design
--------------------------------------------------------------------------------
/Images/Power8Logo_Red.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgentMC/power8/ed47d2dd8ec2ba7a5092e910d26a411a95de123b/Images/Power8Logo_Red.ico
--------------------------------------------------------------------------------
/Images/Power8Logo_Red16x16.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgentMC/power8/ed47d2dd8ec2ba7a5092e910d26a411a95de123b/Images/Power8Logo_Red16x16.ico
--------------------------------------------------------------------------------
/Images/Power8Logo_Red48x48.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgentMC/power8/ed47d2dd8ec2ba7a5092e910d26a411a95de123b/Images/Power8Logo_Red48x48.ico
--------------------------------------------------------------------------------
/Images/Unpin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgentMC/power8/ed47d2dd8ec2ba7a5092e910d26a411a95de123b/Images/Unpin.png
--------------------------------------------------------------------------------
/Images/logo_alfa/Power8Logo7_Blue_alfa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgentMC/power8/ed47d2dd8ec2ba7a5092e910d26a411a95de123b/Images/logo_alfa/Power8Logo7_Blue_alfa.png
--------------------------------------------------------------------------------
/Images/logo_alfa/Power8Logo7_Green_alfa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgentMC/power8/ed47d2dd8ec2ba7a5092e910d26a411a95de123b/Images/logo_alfa/Power8Logo7_Green_alfa.png
--------------------------------------------------------------------------------
/Images/logo_alfa/Power8Logo7_Red_alfa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgentMC/power8/ed47d2dd8ec2ba7a5092e910d26a411a95de123b/Images/logo_alfa/Power8Logo7_Red_alfa.png
--------------------------------------------------------------------------------
/Images/logo_alfa/Power8Logo7_alfa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgentMC/power8/ed47d2dd8ec2ba7a5092e910d26a411a95de123b/Images/logo_alfa/Power8Logo7_alfa.png
--------------------------------------------------------------------------------
/Images/logo_alfa/Power8Logo7_marine_alfa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgentMC/power8/ed47d2dd8ec2ba7a5092e910d26a411a95de123b/Images/logo_alfa/Power8Logo7_marine_alfa.png
--------------------------------------------------------------------------------
/Images/logo_alfa/Power8Logo7_violet_alfa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgentMC/power8/ed47d2dd8ec2ba7a5092e910d26a411a95de123b/Images/logo_alfa/Power8Logo7_violet_alfa.png
--------------------------------------------------------------------------------
/Images/logo_alfa/Power8Logo7_yellow_alfa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgentMC/power8/ed47d2dd8ec2ba7a5092e910d26a411a95de123b/Images/logo_alfa/Power8Logo7_yellow_alfa.png
--------------------------------------------------------------------------------
/Images/logo_black/Power8Logo7_Blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgentMC/power8/ed47d2dd8ec2ba7a5092e910d26a411a95de123b/Images/logo_black/Power8Logo7_Blue.png
--------------------------------------------------------------------------------
/Images/logo_black/Power8Logo7_Green.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgentMC/power8/ed47d2dd8ec2ba7a5092e910d26a411a95de123b/Images/logo_black/Power8Logo7_Green.png
--------------------------------------------------------------------------------
/Images/logo_black/Power8Logo7_Red.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgentMC/power8/ed47d2dd8ec2ba7a5092e910d26a411a95de123b/Images/logo_black/Power8Logo7_Red.png
--------------------------------------------------------------------------------
/Images/logo_black/Power8Logo7_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgentMC/power8/ed47d2dd8ec2ba7a5092e910d26a411a95de123b/Images/logo_black/Power8Logo7_black.png
--------------------------------------------------------------------------------
/Images/logo_black/Power8Logo7_marine.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgentMC/power8/ed47d2dd8ec2ba7a5092e910d26a411a95de123b/Images/logo_black/Power8Logo7_marine.png
--------------------------------------------------------------------------------
/Images/logo_black/Power8Logo7_violet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgentMC/power8/ed47d2dd8ec2ba7a5092e910d26a411a95de123b/Images/logo_black/Power8Logo7_violet.png
--------------------------------------------------------------------------------
/Images/logo_black/Power8Logo7_yellow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgentMC/power8/ed47d2dd8ec2ba7a5092e910d26a411a95de123b/Images/logo_black/Power8Logo7_yellow.png
--------------------------------------------------------------------------------
/P8Installer/P8Installer.aiproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | All
5 | 2.0
6 | d8e31d82-456e-4e4e-8cb7-722b9975754b
7 | msi
8 | .
9 | P8Installer.aip
10 |
11 |
12 | .
13 | True
14 | P8Installer
15 | P8Installer
16 | P8Installer
17 | C:\Program Files (x86)\Caphyon\Advanced Installer 11.6.3\bin\x86\AdvancedInstaller.com
18 | -buildslist DefaultBuild
19 |
20 |
21 |
22 |
23 | Code
24 |
25 |
26 |
27 |
28 | Power8
29 | {010d2da1-c477-4cfe-8171-eee326e29fa0}
30 | True
31 | Built
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/Power8-VS2010.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual Studio 2010
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Power8", "Power8.csproj", "{010D2DA1-C477-4CFE-8171-EEE326E29FA0}"
5 | EndProject
6 | Project("{840C416C-B8F3-42BC-B0DD-F6BB14C9F8CB}") = "P8Installer", "P8Installer\P8Installer.aiproj", "{D8E31D82-456E-4E4E-8CB7-722B9975754B}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | All|Any CPU = All|Any CPU
11 | All|x86 = All|x86
12 | Debug|Any CPU = Debug|Any CPU
13 | Debug|x86 = Debug|x86
14 | DefaultBuild|Any CPU = DefaultBuild|Any CPU
15 | DefaultBuild|x86 = DefaultBuild|x86
16 | Release|Any CPU = Release|Any CPU
17 | Release|x86 = Release|x86
18 | EndGlobalSection
19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
20 | {010D2DA1-C477-4CFE-8171-EEE326E29FA0}.All|Any CPU.ActiveCfg = Release|Any CPU
21 | {010D2DA1-C477-4CFE-8171-EEE326E29FA0}.All|Any CPU.Build.0 = Release|Any CPU
22 | {010D2DA1-C477-4CFE-8171-EEE326E29FA0}.All|x86.ActiveCfg = Release|Any CPU
23 | {010D2DA1-C477-4CFE-8171-EEE326E29FA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
24 | {010D2DA1-C477-4CFE-8171-EEE326E29FA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
25 | {010D2DA1-C477-4CFE-8171-EEE326E29FA0}.Debug|x86.ActiveCfg = Debug|x86
26 | {010D2DA1-C477-4CFE-8171-EEE326E29FA0}.Debug|x86.Build.0 = Debug|x86
27 | {010D2DA1-C477-4CFE-8171-EEE326E29FA0}.DefaultBuild|Any CPU.ActiveCfg = Debug|Any CPU
28 | {010D2DA1-C477-4CFE-8171-EEE326E29FA0}.DefaultBuild|Any CPU.Build.0 = Debug|Any CPU
29 | {010D2DA1-C477-4CFE-8171-EEE326E29FA0}.DefaultBuild|x86.ActiveCfg = Debug|Any CPU
30 | {010D2DA1-C477-4CFE-8171-EEE326E29FA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
31 | {010D2DA1-C477-4CFE-8171-EEE326E29FA0}.Release|Any CPU.Build.0 = Release|Any CPU
32 | {010D2DA1-C477-4CFE-8171-EEE326E29FA0}.Release|x86.ActiveCfg = Release|x86
33 | {010D2DA1-C477-4CFE-8171-EEE326E29FA0}.Release|x86.Build.0 = Release|x86
34 | {D8E31D82-456E-4E4E-8CB7-722B9975754B}.All|Any CPU.ActiveCfg = All|x86
35 | {D8E31D82-456E-4E4E-8CB7-722B9975754B}.All|x86.ActiveCfg = All|x86
36 | {D8E31D82-456E-4E4E-8CB7-722B9975754B}.All|x86.Build.0 = All|x86
37 | {D8E31D82-456E-4E4E-8CB7-722B9975754B}.Debug|Any CPU.ActiveCfg = DefaultBuild|x86
38 | {D8E31D82-456E-4E4E-8CB7-722B9975754B}.Debug|x86.ActiveCfg = DefaultBuild|x86
39 | {D8E31D82-456E-4E4E-8CB7-722B9975754B}.Debug|x86.Build.0 = DefaultBuild|x86
40 | {D8E31D82-456E-4E4E-8CB7-722B9975754B}.DefaultBuild|Any CPU.ActiveCfg = DefaultBuild|x86
41 | {D8E31D82-456E-4E4E-8CB7-722B9975754B}.DefaultBuild|x86.ActiveCfg = DefaultBuild|x86
42 | {D8E31D82-456E-4E4E-8CB7-722B9975754B}.DefaultBuild|x86.Build.0 = DefaultBuild|x86
43 | {D8E31D82-456E-4E4E-8CB7-722B9975754B}.Release|Any CPU.ActiveCfg = DefaultBuild|x86
44 | {D8E31D82-456E-4E4E-8CB7-722B9975754B}.Release|Any CPU.Build.0 = DefaultBuild|x86
45 | {D8E31D82-456E-4E4E-8CB7-722B9975754B}.Release|x86.ActiveCfg = DefaultBuild|x86
46 | {D8E31D82-456E-4E4E-8CB7-722B9975754B}.Release|x86.Build.0 = DefaultBuild|x86
47 | EndGlobalSection
48 | GlobalSection(SolutionProperties) = preSolution
49 | HideSolutionNode = FALSE
50 | EndGlobalSection
51 | EndGlobal
52 |
--------------------------------------------------------------------------------
/Power8.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/Power8.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.2.32630.192
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Power8", "Power8.csproj", "{010D2DA1-C477-4CFE-8171-EEE326E29FA0}"
7 | EndProject
8 | Project("{840C416C-B8F3-42BC-B0DD-F6BB14C9F8CB}") = "P8Installer", "P8Installer\P8Installer.aiproj", "{D8E31D82-456E-4E4E-8CB7-722B9975754B}"
9 | ProjectSection(ProjectDependencies) = postProject
10 | {010D2DA1-C477-4CFE-8171-EEE326E29FA0} = {010D2DA1-C477-4CFE-8171-EEE326E29FA0}
11 | EndProjectSection
12 | EndProject
13 | Global
14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
15 | Debug|Any CPU = Debug|Any CPU
16 | Debug|x86 = Debug|x86
17 | Release|Any CPU = Release|Any CPU
18 | Release|x86 = Release|x86
19 | EndGlobalSection
20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
21 | {010D2DA1-C477-4CFE-8171-EEE326E29FA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22 | {010D2DA1-C477-4CFE-8171-EEE326E29FA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
23 | {010D2DA1-C477-4CFE-8171-EEE326E29FA0}.Debug|x86.ActiveCfg = Debug|x86
24 | {010D2DA1-C477-4CFE-8171-EEE326E29FA0}.Debug|x86.Build.0 = Debug|x86
25 | {010D2DA1-C477-4CFE-8171-EEE326E29FA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
26 | {010D2DA1-C477-4CFE-8171-EEE326E29FA0}.Release|Any CPU.Build.0 = Release|Any CPU
27 | {010D2DA1-C477-4CFE-8171-EEE326E29FA0}.Release|x86.ActiveCfg = Release|x86
28 | {010D2DA1-C477-4CFE-8171-EEE326E29FA0}.Release|x86.Build.0 = Release|x86
29 | {D8E31D82-456E-4E4E-8CB7-722B9975754B}.Debug|Any CPU.ActiveCfg = DefaultBuild
30 | {D8E31D82-456E-4E4E-8CB7-722B9975754B}.Debug|x86.ActiveCfg = DefaultBuild
31 | {D8E31D82-456E-4E4E-8CB7-722B9975754B}.Release|Any CPU.ActiveCfg = DefaultBuild
32 | {D8E31D82-456E-4E4E-8CB7-722B9975754B}.Release|Any CPU.Build.0 = DefaultBuild
33 | {D8E31D82-456E-4E4E-8CB7-722B9975754B}.Release|x86.ActiveCfg = DefaultBuild
34 | {D8E31D82-456E-4E4E-8CB7-722B9975754B}.Release|x86.Build.0 = DefaultBuild
35 | EndGlobalSection
36 | GlobalSection(SolutionProperties) = preSolution
37 | HideSolutionNode = FALSE
38 | EndGlobalSection
39 | GlobalSection(ExtensibilityGlobals) = postSolution
40 | SolutionGuid = {0328D4E2-8321-470B-A495-D1871BDECE3D}
41 | EndGlobalSection
42 | EndGlobal
43 |
--------------------------------------------------------------------------------
/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 | using System.Windows;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Power8")]
9 | [assembly: AssemblyDescription("Start menu replacer for Windows XP, 7, 8 and 10")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Power8 Team")]
12 | [assembly: AssemblyProduct("Power8")]
13 | [assembly: AssemblyCopyright("© Power8 Team 2012-2022")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | //In order to begin building localizable applications, set
23 | //CultureYouAreCodingWith in your .csproj file
24 | //inside a . For example, if you are using US english
25 | //in your source files, set the to en-US. Then uncomment
26 | //the NeutralResourceLanguage attribute below. Update the "en-US" in
27 | //the line below to match the UICulture setting in the project file.
28 |
29 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
30 |
31 |
32 | [assembly: ThemeInfo(
33 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
34 | //(used if a resource is not found in the page,
35 | // or application resource dictionaries)
36 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
37 | //(used if a resource is not found in the page,
38 | // app, or any theme specific resource dictionaries)
39 | )]
40 |
41 |
42 | // Version information for an assembly consists of the following four values:
43 | //
44 | // Major Version
45 | // Minor Version
46 | // Build Number
47 | // Revision
48 | //
49 | // You can specify all the values or you can default the Build and Revision Numbers
50 | // by using the '*' as shown below:
51 | // [assembly: AssemblyVersion("1.0.*")]
52 | [assembly: AssemblyVersion("1.6.4.1640")]
53 | [assembly: AssemblyFileVersion("1.6.4.1640")]
54 | //7zuri=https://github.com/AgentMC/power8/releases/download/v.1.6.4.1640/Power8_v.1.6.4.1640.7z
55 | //msuri=https://github.com/AgentMC/power8/releases/download/v.1.6.4.1640/Power8_v.1.6.4.1640.msi
56 |
--------------------------------------------------------------------------------
/Properties/NoLoc.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace Power8.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class NoLoc {
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 NoLoc() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Power8.Properties.NoLoc", typeof(NoLoc).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized string similar to The Programs system folder ({0}) cannot be located under StartMenu folder ({2}). {1} may be unstable. .
65 | ///
66 | internal static string Err_CantFindProgramsDir {
67 | get {
68 | return ResourceManager.GetString("Err_CantFindProgramsDir", resourceCulture);
69 | }
70 | }
71 |
72 | ///
73 | /// Looks up a localized string similar to Type constructor did not return the type object..
74 | ///
75 | internal static string Err_GotNoTypeObject {
76 | get {
77 | return ResourceManager.GetString("Err_GotNoTypeObject", resourceCulture);
78 | }
79 | }
80 |
81 | ///
82 | /// Looks up a localized string similar to Type disposition event cannot be reacted on..
83 | ///
84 | internal static string Err_TypeIsNotIComponent {
85 | get {
86 | return ResourceManager.GetString("Err_TypeIsNotIComponent", resourceCulture);
87 | }
88 | }
89 |
90 | ///
91 | /// Looks up a localized string similar to an unhandled exceptoion occured in Power8. Details are below.
92 | ///.
93 | ///
94 | internal static string Err_UnhandledGeneric {
95 | get {
96 | return ResourceManager.GetString("Err_UnhandledGeneric", resourceCulture);
97 | }
98 | }
99 |
100 | ///
101 | /// Looks up a localized string similar to Power8.
102 | ///
103 | internal static string Stg_AppShortName {
104 | get {
105 | return ResourceManager.GetString("Stg_AppShortName", resourceCulture);
106 | }
107 | }
108 |
109 | ///
110 | /// Looks up a localized string similar to raw/master/Properties/AssemblyInfo.cs.
111 | ///
112 | internal static string Stg_AssemblyInfoURI {
113 | get {
114 | return ResourceManager.GetString("Stg_AssemblyInfoURI", resourceCulture);
115 | }
116 | }
117 |
118 | ///
119 | /// Looks up a localized string similar to wiki/Donate.
120 | ///
121 | internal static string Stg_DonateUri {
122 | get {
123 | return ResourceManager.GetString("Stg_DonateUri", resourceCulture);
124 | }
125 | }
126 |
127 | ///
128 | /// Looks up a localized string similar to wiki/DuplicatedIconsHack.
129 | ///
130 | internal static string Stg_DuplicatedIconsHackUri {
131 | get {
132 | return ResourceManager.GetString("Stg_DuplicatedIconsHackUri", resourceCulture);
133 | }
134 | }
135 |
136 | ///
137 | /// Looks up a localized string similar to https://github.com/AgentMC/power8/.
138 | ///
139 | internal static string Stg_Power8URI {
140 | get {
141 | return ResourceManager.GetString("Stg_Power8URI", resourceCulture);
142 | }
143 | }
144 |
145 | ///
146 | /// Looks up a localized string similar to Software\Microsoft\Windows\CurrentVersion\Run.
147 | ///
148 | internal static string Stg_RegKeyRun {
149 | get {
150 | return ResourceManager.GetString("Stg_RegKeyRun", resourceCulture);
151 | }
152 | }
153 |
154 | ///
155 | /// Looks up a localized string similar to Exiting because {0}.
156 | ///
157 | internal static string Str_FailFastFormat {
158 | get {
159 | return ResourceManager.GetString("Str_FailFastFormat", resourceCulture);
160 | }
161 | }
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/Properties/NoLoc.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 | The Programs system folder ({0}) cannot be located under StartMenu folder ({2}). {1} may be unstable.
122 |
123 |
124 | Type constructor did not return the type object.
125 |
126 |
127 | Type disposition event cannot be reacted on.
128 |
129 |
130 | an unhandled exceptoion occured in Power8. Details are below.
131 |
132 | String written to App event log. May not be localized. If you touch it, leave ending paragraph sign.
133 |
134 |
135 | Power8
136 | Default message box title. May not be localized.
137 |
138 |
139 | raw/master/Properties/AssemblyInfo.cs
140 | May not be localized.
141 |
142 |
143 | wiki/Donate
144 |
145 |
146 | wiki/DuplicatedIconsHack
147 |
148 |
149 | https://github.com/AgentMC/power8/
150 | May not be localized.
151 |
152 |
153 | Software\Microsoft\Windows\CurrentVersion\Run
154 | May not be localized.
155 |
156 |
157 | Exiting because {0}
158 | String written to App event log. May not be localized.
159 |
160 |
--------------------------------------------------------------------------------
/Properties/Resources.ru.Designer.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgentMC/power8/ed47d2dd8ec2ba7a5092e910d26a411a95de123b/Properties/Resources.ru.Designer.cs
--------------------------------------------------------------------------------
/Properties/Resources.sv.Designer.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgentMC/power8/ed47d2dd8ec2ba7a5092e910d26a411a95de123b/Properties/Resources.sv.Designer.cs
--------------------------------------------------------------------------------
/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | False
7 |
8 |
9 |
10 |
11 |
12 | False
13 |
14 |
15 | False
16 |
17 |
18 | False
19 |
20 |
21 | True
22 |
23 |
24 | True
25 |
26 |
27 | 2
28 |
29 |
30 | True
31 |
32 |
33 |
34 |
35 |
36 | True
37 |
38 |
39 | True
40 |
41 |
42 | True
43 |
44 |
45 | True
46 |
47 |
48 | True
49 |
50 |
51 | False
52 |
53 |
54 |
55 |
56 |
57 | True
58 |
59 |
60 | True
61 |
62 |
63 | False
64 |
65 |
66 | False
67 |
68 |
69 | True
70 |
71 |
72 | True
73 |
74 |
75 | False
76 |
77 |
78 | False
79 |
80 |
81 | False
82 |
83 |
84 | 2
85 |
86 |
87 | True
88 |
89 |
90 | True
91 |
92 |
93 | False
94 |
95 |
96 | False
97 |
98 |
99 | <?xml version="1.0" encoding="utf-8"?>
100 | <P8SearchProviders>
101 | <Provider key="b">https://www.bing.com/search?q={0}</Provider>
102 | <Provider key="d">https://www.baidu.com/s?wd={0}</Provider>
103 | <Provider key="g">https://google.com/search?q={0}</Provider>
104 | <Provider key="w">https://en.wikipedia.org/w/index.php?search={0}</Provider>
105 | <Provider key="y">https://search.yahoo.com/search?p={0}</Provider>
106 | <Provider key="в">https://ru.wikipedia.org/w/index.php?search={0}</Provider>
107 | </P8SearchProviders>
108 |
109 |
110 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #  Power 8 #
2 |
3 | ## The start menu replacer for Win8, styled and integrated inside taskbar. ##
4 |
5 | Designed for Windows8, works under Windows10, XP SP3 and Se7en SP1 as well.
6 | Please see all the info on [our Wiki](https://github.com/AgentMC/power8/wiki)
7 |
8 | ### ATTENTION! If you see "Unable to check for updates" warning on Power8 button, please manually update to [release 1.6.1.1619](https://github.com/AgentMC/power8/releases/tag/v.1.6.1.1619)!
9 |
--------------------------------------------------------------------------------
/Views/About.xaml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
87 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/Views/About.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 |
4 | namespace Power8.Views
5 | {
6 | ///
7 | /// The About window, inherits DisposableWindow
8 | ///
9 | public partial class About
10 | {
11 | public About()
12 | {
13 | Util.FpReset();
14 | InitializeComponent();
15 | }
16 |
17 | ///
18 | /// Gets the "Copyright" assembly description of currently running application
19 | ///
20 | public string CopyrightContent
21 | {
22 | get
23 | {
24 | return ((AssemblyCopyrightAttribute)
25 | (Assembly.GetEntryAssembly()
26 | .GetCustomAttributes(typeof (AssemblyCopyrightAttribute), true)[0]))
27 | .Copyright;
28 | }
29 | }
30 |
31 | ///
32 | /// Gets the string representation of version of currently running application
33 | ///
34 | public string VersionContent
35 | {
36 | get { return Util.GetAppVersion().ToString(); }
37 | }
38 |
39 | ///
40 | /// If the Localizer url is available in localization, returns instance of
41 | /// corresponding URI. Returns null otherwise.
42 | ///
43 | public Uri UriContent
44 | {
45 | get
46 | {
47 | return (!string.IsNullOrEmpty(Properties.Resources.Str_LocalizerUri))
48 | && Uri.TryCreate(Properties.Resources.Str_LocalizerUri, UriKind.Absolute, out var u)
49 | ? u
50 | : null;
51 | }
52 | }
53 |
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/Views/BtnStck.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
23 |
24 |
25 |
26 |
27 |
30 |
59 |
60 |
68 |
69 |
70 |
71 |
72 |
73 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
157 |
158 |
159 |
160 |
161 |
164 |
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 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
--------------------------------------------------------------------------------
/Views/ComputerList.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
19 |
20 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Views/ComputerList.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Windows;
3 | using System.Windows.Media;
4 |
5 | namespace Power8.Views
6 | {
7 | ///
8 | /// This class works as list and quick search among computers
9 | /// available on network, if the amount is more than ten.
10 | ///
11 | public partial class ComputerList
12 | {
13 | ///
14 | /// Constructor. Initialize and fill data
15 | ///
16 | public ComputerList()
17 | {
18 | Util.FpReset();
19 | InitializeComponent();
20 | DataContext = this;
21 | foreach (var comp in NetManager.ComputersNearby)
22 | listBox1.Items.Add(comp);
23 | }
24 | ///
25 | /// Bindable ImageSource for Window icon.
26 | /// Returns already extracted "Workgroup" icon
27 | ///
28 | public ImageSource IconEx
29 | {
30 | get { return PowerItemTree.NetworkRoot.Items[0]/*workgroup*/.Icon.SmallBitmap; }
31 | }
32 | ///
33 | /// Clear button handler. Clears text in search box.
34 | ///
35 | private void CleanerBtnClick(object sender, RoutedEventArgs e)
36 | {
37 | CLTextbox.Text = string.Empty;
38 | }
39 | ///
40 | /// Search box text changed handler. Filters the results to items that contain entered text.
41 | /// Case insensitive, and fast since all computers are stored UPPERCASE.
42 | ///
43 | private void Textbox1TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
44 | {
45 | var txt = CLTextbox.Text.ToUpper();
46 | listBox1.Items.Clear();
47 | foreach (var comp in NetManager.ComputersNearby.Where(comp => comp.Contains(txt)))
48 | listBox1.Items.Add(comp);
49 | }
50 | ///
51 | /// Currently open the computer - is the only one available action.
52 | /// By doubleclick.
53 | ///
54 | private void ListBox1MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
55 | {
56 | Util.StartExplorer("\\\\" + listBox1.SelectedItem);
57 | }
58 |
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/Views/ConfirmActionWindow.xaml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
33 |
34 |
35 |
38 |
39 |
47 |
48 |
54 |
55 |
61 |
62 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/Views/ConfirmActionWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Windows;
4 | using Power8.Properties;
5 |
6 | namespace Power8.Views
7 | {
8 | ///
9 | /// Window to get user confirmation of PowerAction.
10 | ///
11 | public partial class ConfirmActionWindow
12 | {
13 | public ConfirmActionWindow(object action)
14 | {
15 | InitializeComponent();
16 |
17 | QuestionIcon.Source =
18 | ImageManager.GetImageContainerForIconSync("Question", SystemIcons.Question.Handle).LargeBitmap;
19 | Title = NoLoc.Stg_AppShortName;
20 | CawConfirmButton.Content = action;
21 | }
22 |
23 |
24 | public ConfirmActionWindow(string confirmMessage, string confirmButtonText, string cancelButtonText)
25 | : this(confirmButtonText)
26 | {
27 | CawCancelButton.Content = cancelButtonText;
28 | CawMessageTextBlock.Text = confirmMessage;
29 | }
30 |
31 | private void ConfirmButtonClick(object sender, RoutedEventArgs e)
32 | {
33 | DialogResult = true;
34 | Close();
35 | }
36 |
37 | private void CancelButtonClick(object sender, RoutedEventArgs e)
38 | {
39 | DialogResult = false;
40 | Close();
41 | }
42 |
43 | private void ConfirmWindow_Loaded(object sender, RoutedEventArgs e)
44 | {
45 | var ceil = Math.Ceiling(LayoutRoot.RowDefinitions[0].ActualHeight);
46 | ceil += ceil%2; //getting first even number more than ActualHeight of Row
47 | LayoutRoot.RowDefinitions[0].MinHeight = ceil;
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/Views/DisposableLinkWindow.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows;
3 | using System.Windows.Documents;
4 |
5 | namespace Power8.Views
6 | {
7 | public class DisposableLinkWindow: DisposableWindow
8 | {
9 | public DisposableLinkWindow()
10 | {
11 | WindowStartupLocation = WindowStartupLocation.CenterScreen;
12 | }
13 |
14 | ///
15 | /// Handles clicks on the Hyperlinks in this window
16 | ///
17 | protected void Navigate(object sender, RoutedEventArgs e)
18 | {
19 | Util.CreateProcess(((Hyperlink)sender).NavigateUri.AbsoluteUri);
20 | }
21 |
22 | private static readonly string[] Names = //different P8 images
23 | {"", "Blue_", "Green_", "marine_", "Red_", "violet_", "yellow_"};
24 | private static readonly Random Rnd = new Random(); //used to get random image
25 |
26 | ///
27 | /// Returns string that can be used as ImageSource, and containing
28 | /// the random Power8 image.
29 | ///
30 | public string Logo
31 | {
32 | get
33 | {
34 | return "/Power8;component/Images/logo_alfa/Power8Logo7_" +
35 | Names[Rnd.Next(Names.Length)] +
36 | "alfa.png";
37 | }
38 | }
39 |
40 | ///
41 | /// Handles OK button click
42 | ///
43 | protected void SimpleClose(object sender, RoutedEventArgs e)
44 | {
45 | Close();
46 | }
47 |
48 | ///
49 | /// Returns Uri to Rower8 online repo, taking it from NoLoc resource.
50 | ///
51 | public Uri RepoUri
52 | {
53 | get
54 | {
55 | return new Uri(Properties.NoLoc.Stg_Power8URI);
56 | }
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/Views/DisposableWindow.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Windows;
4 | using Power8.Helpers;
5 |
6 | namespace Power8.Views
7 | {
8 | ///
9 | /// Use this class to create a singleton window to be used with
10 | /// Util.InstantiateClass()
. Except inheritance, you need explicit
11 | /// parameterless constructor with call to InitializeComponent()
12 | /// to be used by VS designer.
13 | ///
14 | public class DisposableWindow : Window, IComponent
15 | {
16 | ///
17 | /// The destructor will fire the disposition event, and thus will remove
18 | /// unusable this
from the type cache of
19 | /// InstantiateClass()
20 | ///
21 | ~DisposableWindow()
22 | {
23 | Dispose();
24 | }
25 |
26 | private bool _disposing;
27 | ///
28 | /// Call this to close the DisposableWindow and stop usage of it.
29 | ///
30 | public void Dispose()
31 | {
32 | Log.Raw("called", GetType().FullName);
33 | lock (this)
34 | {
35 | if (_disposing)
36 | return;
37 | _disposing = true;
38 | }
39 | Util.Send(() => //The Dispose() might be called from background
40 | {
41 | if(IsVisible)
42 | Close();
43 | var handler = Disposed;
44 | if (handler != null)
45 | handler(this, null);
46 | });
47 | }
48 | ///
49 | /// Occurs when the DisposableWindow is closed or in other way finalized
50 | ///
51 | public event EventHandler Disposed;
52 |
53 | ///
54 | /// Do not use.
55 | ///
56 | public ISite Site { get; set; }
57 |
58 | ///
59 | /// When override, always use base call. The disposable window
60 | /// always disposes itself on closing.
61 | ///
62 | /// EventArgs instance of any kind
63 | protected override void OnClosed(EventArgs e)
64 | {
65 | base.OnClosed(e);
66 | Dispose();
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Views/Donate.xaml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | PayPal:
45 |
52 | (USD, EUR)
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
66 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/Views/Donate.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Power8.Properties;
3 |
4 | namespace Power8.Views
5 | {
6 | ///
7 | /// The Donate window, inherits DisposableLinkWindow.
8 | ///
9 | public partial class Donate
10 | {
11 | public Donate()
12 | {
13 | Util.FpReset();
14 | InitializeComponent();
15 | }
16 |
17 | public Uri DonateUri
18 | {
19 | get { return new Uri(RepoUri, NoLoc.Stg_DonateUri); }
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Views/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
17 |
18 |
19 |
20 |
68 |
69 |
--------------------------------------------------------------------------------
/Views/MenuedButton.xaml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
--------------------------------------------------------------------------------
/Views/MenuedButton.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using System.Windows.Controls;
3 |
4 | namespace Power8
5 | {
6 | ///
7 | /// MenuedButton the button with image-dropdown. Represents PowerItem.
8 | ///
9 | public partial class MenuedButton:INotifyPropertyChanged
10 | {
11 | public MenuedButton()
12 | {
13 | InitializeComponent();
14 | }
15 |
16 | private PowerItem _item;
17 | ///
18 | /// The PowerItem represented by this menued button.
19 | /// This is not implemented as DependencyProperty since a lot of work
20 | /// is done automatically in case of DP, so the designer can crash
21 | /// from time to time. This doesn't happen with regular property.
22 | ///
23 | public PowerItem Item
24 | {
25 | get { return _item; }
26 | set
27 | {
28 | if (_item == value)
29 | return;
30 | _item = value;
31 | var handler = PropertyChanged;
32 | if (handler != null)
33 | handler(this, new PropertyChangedEventArgs("Item"));
34 | }
35 | }
36 |
37 | ///
38 | /// The context menu is over the drop-down PowerItems.
39 | /// So what we are doing is setting the data context for that menu
40 | /// to the PowerItem clicked.
41 | ///
42 | private void ContextMenuContextMenuOpening(object sender, ContextMenuEventArgs e)
43 | {
44 | App.Current.MenuDataContext = Util.ExtractRelatedPowerItem(e);
45 | }
46 |
47 | public event PropertyChangedEventHandler PropertyChanged;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Views/RestartExplorer.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Power8.Views
2 | {
3 | partial class RestartExplorer
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.label1 = new System.Windows.Forms.Label();
32 | this.button1 = new System.Windows.Forms.Button();
33 | this.button2 = new System.Windows.Forms.Button();
34 | this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
35 | this.tableLayoutPanel1.SuspendLayout();
36 | this.SuspendLayout();
37 | //
38 | // label1
39 | //
40 | this.label1.AutoSize = true;
41 | this.label1.Font = new System.Drawing.Font("Segoe UI", 14.25F);
42 | this.label1.Location = new System.Drawing.Point(3, 0);
43 | this.label1.Name = "label1";
44 | this.label1.Size = new System.Drawing.Size(535, 100);
45 | this.label1.TabIndex = 0;
46 | this.label1.Text = "It seems that Windows Explorer process is unavailable.\r\nPower8 can help you handl" +
47 | "ing this.\r\n \r\nDo you want to restore Windows Explorer and restart Power8?";
48 | //
49 | // button1
50 | //
51 | this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
52 | | System.Windows.Forms.AnchorStyles.Right)));
53 | this.button1.AutoSize = true;
54 | this.button1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
55 | this.button1.DialogResult = System.Windows.Forms.DialogResult.OK;
56 | this.button1.Font = new System.Drawing.Font("Segoe UI", 14.25F, System.Drawing.FontStyle.Bold);
57 | this.button1.Location = new System.Drawing.Point(3, 122);
58 | this.button1.Name = "button1";
59 | this.button1.Size = new System.Drawing.Size(539, 60);
60 | this.button1.TabIndex = 1;
61 | this.button1.Text = "Yes!\r\nPlease launch Explorer for me and restart Power8 process.";
62 | this.button1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
63 | this.button1.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
64 | this.button1.UseVisualStyleBackColor = true;
65 | //
66 | // button2
67 | //
68 | this.button2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
69 | | System.Windows.Forms.AnchorStyles.Right)));
70 | this.button2.AutoSize = true;
71 | this.button2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
72 | this.button2.DialogResult = System.Windows.Forms.DialogResult.Cancel;
73 | this.button2.Font = new System.Drawing.Font("Segoe UI", 14.25F);
74 | this.button2.Location = new System.Drawing.Point(3, 188);
75 | this.button2.Name = "button2";
76 | this.button2.Size = new System.Drawing.Size(539, 60);
77 | this.button2.TabIndex = 2;
78 | this.button2.Text = "No, thanks.\r\nI know what\'s happening and will handle the problem myself.";
79 | this.button2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
80 | this.button2.UseVisualStyleBackColor = true;
81 | //
82 | // tableLayoutPanel1
83 | //
84 | this.tableLayoutPanel1.AutoSize = true;
85 | this.tableLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
86 | this.tableLayoutPanel1.ColumnCount = 1;
87 | this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
88 | this.tableLayoutPanel1.Controls.Add(this.label1, 0, 0);
89 | this.tableLayoutPanel1.Controls.Add(this.button2, 0, 2);
90 | this.tableLayoutPanel1.Controls.Add(this.button1, 0, 1);
91 | this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
92 | this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
93 | this.tableLayoutPanel1.Name = "tableLayoutPanel1";
94 | this.tableLayoutPanel1.RowCount = 3;
95 | this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
96 | this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
97 | this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
98 | this.tableLayoutPanel1.Size = new System.Drawing.Size(545, 251);
99 | this.tableLayoutPanel1.TabIndex = 3;
100 | //
101 | // RestartExplorer
102 | //
103 | this.AcceptButton = this.button1;
104 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
105 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
106 | this.AutoSize = true;
107 | this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
108 | this.CancelButton = this.button2;
109 | this.ClientSize = new System.Drawing.Size(545, 251);
110 | this.ControlBox = false;
111 | this.Controls.Add(this.tableLayoutPanel1);
112 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
113 | this.Name = "RestartExplorer";
114 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
115 | this.Text = "Power8 — Windows Explorer is dead";
116 | this.TopMost = true;
117 | this.tableLayoutPanel1.ResumeLayout(false);
118 | this.tableLayoutPanel1.PerformLayout();
119 | this.ResumeLayout(false);
120 | this.PerformLayout();
121 |
122 | }
123 |
124 | #endregion
125 |
126 | private System.Windows.Forms.Label label1;
127 | private System.Windows.Forms.Button button1;
128 | private System.Windows.Forms.Button button2;
129 | private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
130 | }
131 | }
--------------------------------------------------------------------------------
/Views/RestartExplorer.cs:
--------------------------------------------------------------------------------
1 | using System.Windows.Forms;
2 | using Power8.Converters;
3 |
4 | namespace Power8.Views
5 | {
6 | ///
7 | /// The win32 window that is shown in case Explorer is dead
8 | /// and we got to do something. Contains no logic except the localization.
9 | /// The only function of this is the question to user:
10 | /// Do you know what's happening or not? Because we don't like it!
11 | /// So the only thing whis window does is to return Yes or No :)
12 | ///
13 | public partial class RestartExplorer : Form
14 | {
15 | ///
16 | /// Constructor. Performs form init and loads the
17 | /// localized strings for current UI culture.
18 | ///
19 | public RestartExplorer()
20 | {
21 | InitializeComponent();
22 | var c = NameToResourceConverter.Instance;
23 | base.Text = c.Convert("RE_Title");
24 | label1.Text = c.Convert("RE_TopLabel");
25 | button1.Text = c.Convert("RE_YesButton");
26 | button2.Text = c.Convert("RE_NoButton");
27 | }
28 | ///
29 | /// ShowDialog() is overriden to guarantee the window will be
30 | /// displayed foreground on all OS in the same way.
31 | ///
32 | new public void ShowDialog()
33 | {
34 | Show();
35 | BringToFront();
36 | Hide();
37 | base.ShowDialog();
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Views/SettingsWnd.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
15 |
19 |
22 |
33 |
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 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 | 1:1
100 | 4:3
101 | 16:9
102 | 16:10
103 |
104 |
105 |
106 |
107 |
108 |
110 |
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 |
137 |
138 |
139 |
140 |
141 | Computer
142 | Documents/Libraries
143 | Control Panel
144 |
146 |
147 |
149 |
156 |
157 | Administrative tools
158 | Network
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
--------------------------------------------------------------------------------
/Views/SettingsWnd.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows;
3 | using Power8.Converters;
4 | using Power8.Helpers;
5 |
6 | namespace Power8.Views
7 | {
8 | ///
9 | /// Interaction logic for Settings window.
10 | /// Guess it's the first window in project where only
11 | /// interaction logic is placed in codebehind :)
12 | ///
13 | public partial class SettingsWnd
14 | {
15 | ///
16 | /// Constructor. Sets window's data context to Settings Manager's current instance
17 | /// and hides BlockMetro box if not Win8. Localizes UI partially.
18 | ///
19 | public SettingsWnd()
20 | {
21 | Util.FpReset();
22 | InitializeComponent();
23 | DataContext = SettingsManager.Instance;
24 | if(!Util.OsIs.EightFamily)
25 | MWBlockMetro.Visibility = Visibility.Collapsed;
26 | if (!Util.OsIs.SevenOrMore)
27 | StgCbCtrl.IsEnabled = false; //No Category view for CPL for XP; overrides binding.
28 | //The following is needed to protect users migrating 8==>10. They won't be able to change
29 | //the setting, and in case we don't clear it - the button will be malformed.
30 | if (Util.OsIs.TenOrMore) SettingsManager.Instance.SquareStartButton = false;
31 | //System-wide localization
32 | StgCbAdmT.Content = PowerItemTree.AdminToolsRoot.FriendlyName;
33 | StgCbComp.Content = PowerItemTree.MyComputerRoot.FriendlyName;
34 | StgCbCpnl.Content = PowerItemTree.ControlPanelRoot.FriendlyName;
35 | StgCbDocs.Content = PowerItemTree.LibrariesRoot.FriendlyName;
36 | StgCbNtwk.Content = PowerItemTree.NetworkRoot.FriendlyName;
37 | //localization for headers (columns don't have names)
38 | StgWseColKey.Header = NameToResourceConverter.Instance.Convert("StgWseColKey", null, null, null);
39 | StgWseColVal.Header = NameToResourceConverter.Instance.Convert("StgWseColVal", null, null, null);
40 | StgMfuColExcl.Header = NameToResourceConverter.Instance.Convert("StgMfuColExcl", null, null, null);
41 | }
42 |
43 | ///
44 | /// Handles closing of the window. Initiates the SearchProviders saving
45 | ///
46 | private void WindowClosed(object sender, System.EventArgs e)
47 | {
48 | SettingsManager.SaveActiveSearchProviders();
49 | }
50 |
51 | ///
52 | /// Displays the OpenFileDialog with Title and Filter set.
53 | /// Filter allows images. If OFD is closed by OK, the returned
54 | /// filename is being put into textbox.
55 | ///
56 | private void Browse(object sender, RoutedEventArgs e)
57 | {
58 | var ofd = new System.Windows.Forms.OpenFileDialog
59 | {
60 | Filter = Properties.Resources.Str_PicDialogFilter + @"|*.png;*.gif;*.jpg;*.jpe*;*.tif*",
61 | Title = Properties.NoLoc.Stg_AppShortName + Properties.Resources.Str_PicDialogDescription
62 | };
63 | if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
64 | pictureBox.Text = ofd.FileName;
65 | }
66 |
67 | ///
68 | /// Handles text box doubleclick. Clears the box.
69 | ///
70 | private void Clear(object sender, System.Windows.Input.MouseButtonEventArgs e)
71 | {
72 | pictureBox.Text = string.Empty;
73 | }
74 |
75 | ///
76 | /// Bindable propertyto disable the "Configure start button" checkbox.
77 | /// It is disabled on XP or below + on W10 for now.
78 | ///
79 | public static bool NotXp
80 | {
81 | get { return Util.OsIs.SevenOrMore && !Util.OsIs.TenOrMore; }
82 | }
83 |
84 | ///
85 | /// Returns special uri to navigate to Duplicated Icons hack page
86 | ///
87 | public Uri IconsHackUri
88 | {
89 | get { return new Uri(RepoUri, Properties.NoLoc.Stg_DuplicatedIconsHackUri); }
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/Views/UpdateNotifier.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
12 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/Views/UpdateNotifier.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.IO;
4 | using System.Net;
5 | using System.Windows;
6 | using Microsoft.Win32;
7 | using Power8.Properties;
8 |
9 | namespace Power8.Views
10 | {
11 | ///
12 | /// Window that is automatically shown when the update is available
13 | /// Inherits DisposabeWindow, so is implemented as lazy resource-friendly
14 | /// singleton.
15 | ///
16 | public partial class UpdateNotifier:INotifyPropertyChanged
17 | {
18 | private readonly string _curVer, _newVer, _uri7Z, _uriMsi;
19 | public event PropertyChangedEventHandler PropertyChanged;
20 | //Constructor-----------------------------
21 | ///
22 | /// Needed for Designer
23 | ///
24 | public UpdateNotifier()
25 | {
26 | Util.FpReset();
27 | InitializeComponent();
28 | }
29 | ///
30 | /// Main constructor of a form
31 | ///
32 | /// String representation of curent application version
33 | /// String representation of a version available for download
34 | /// http:// URL (string) to z7 package
35 | /// http:// URL (string) to msi package
36 | internal UpdateNotifier(string currentVer, string newVer, string uri7Z, string uriMsi) : this()
37 | {
38 | _curVer = currentVer;
39 | _newVer = newVer;
40 | _uri7Z = uri7Z;
41 | _uriMsi = uriMsi;
42 | Title = NoLoc.Stg_AppShortName + Properties.Resources.Str_UpdateAvailable;
43 | PropertyChanged(this, new PropertyChangedEventArgs("CurrentVersion"));
44 | PropertyChanged(this, new PropertyChangedEventArgs("NewVersion"));
45 | }
46 | //Bindable properties---------------------
47 | ///
48 | /// Gets the current version passed to constructor
49 | ///
50 | public string CurrentVersion
51 | {
52 | get { return _curVer; }
53 | }
54 | ///
55 | /// Gets the available version passed to constructor
56 | ///
57 | public string NewVersion
58 | {
59 | get { return _newVer; }
60 | }
61 | //Handlers--------------------------------
62 | ///
63 | /// Closes the window
64 | ///
65 | private void CloseClick(object sender, RoutedEventArgs e)
66 | {
67 | Close();
68 | }
69 | ///
70 | /// Handles Ignore this version button.
71 | /// Saves current version as ignorable, saves settings, and closes.
72 | ///
73 | private void IgnoreClick(object sender, RoutedEventArgs e)
74 | {
75 | Settings.Default.IgnoreVer = NewVersion;
76 | Settings.Default.Save();
77 | Close();
78 | }
79 | ///
80 | /// Handles both "Download 7z" and "Download MSI".
81 | /// Shows Save dialog, and if there's OK clicked there,
82 | /// starts async download. After it is completed, the file
83 | /// will be shown selected by Explorer.
84 | ///
85 | private void DownloadFileClick(object sender, RoutedEventArgs e)
86 | {
87 | var obj = (sender == UNdownMsi ? _uriMsi : _uri7Z);
88 | var ofd = new SaveFileDialog
89 | {
90 | AddExtension = true,
91 | DefaultExt = Path.GetExtension(obj),
92 | FileName = "",
93 | Title = NoLoc.Stg_AppShortName + Properties.Resources.Str_SaveDialogDescription,
94 | Filter = NoLoc.Stg_AppShortName
95 | + Properties.Resources.Str_SaveDialogFilter + Path.GetExtension(obj),
96 | };
97 | if (ofd.ShowDialog().Value)
98 | InitDownload(obj, ofd.FileName, () => Util.StartExplorerSelect(ofd.FileName));
99 | }
100 | ///
101 | /// The big and bold button handler. Downloads MSI to temporary location,
102 | /// then launches it passing current startup location as APPDIR var.
103 | /// Power8 will automatically exit when the installation is launched.
104 | ///
105 | private void DownAndUpClick(object sender, RoutedEventArgs e)
106 | {
107 | var file = Environment.ExpandEnvironmentVariables("%temp%\\" + Path.GetFileName(_uriMsi));
108 | InitDownload(_uriMsi, file, () =>
109 | {
110 | var startupFolder = System.Windows.Forms.Application.StartupPath.Trim('"');
111 | Util.CreateProcess("msiexec.exe", string.Format("/i \"{0}\" APPDIR=\"{1}\"", file, startupFolder));
112 | Environment.Exit(0);
113 | });
114 | }
115 | ///
116 | /// Opens project website. Then closes the window.
117 | ///
118 | private void GoWebClick(object sender, RoutedEventArgs e)
119 | {
120 | Util.OpenPower8WebSite();
121 | Close();
122 | }
123 | //Download helpers------------------------
124 | ///
125 | /// Handles the event when download is completed or stopped in any other way.
126 | ///
127 | void WcDownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
128 | {
129 | Util.Send(() => IsEnabled = true); //Enable the UI. Since we're in some non-main thread, do this from main one.
130 | if (e.Cancelled || e.Error != null) //i.e. the download wasn't successful:
131 | {
132 | MessageBox.Show(
133 | Properties.Resources.Err_DownloadCancelled + (e.Error != null ? "\r\n" + e.Error.Message : ""),
134 | NoLoc.Stg_AppShortName,
135 | MessageBoxButton.OK,
136 | MessageBoxImage.Error);
137 | }
138 | else //the download succeeded
139 | {
140 | ((Action) e.UserState)(); //Invoke the passed action
141 | Util.Send(Close); //Close the window from main thread
142 | }
143 | }
144 | ///
145 | /// Initializes the download process
146 | ///
147 | /// String URL what to download
148 | /// String path where to download
149 | /// Action lambda what to do after the
150 | /// download is done. This it stored as "user token" in the async download
151 | /// thread, so can be extracted later and executed by the completion
152 | /// event handler. Be careful NOT to pass here any line working with the UI,
153 | /// since the handler will be called in background thread. Also keep in mind
154 | /// that UI will be disabled during the download and will become enabled
155 | /// automatically when this is done, so you shouldn't bother about this.
156 | private void InitDownload(string url, string where, Action successAction)
157 | {
158 | var wc = new WebClient();
159 | //Subscribe to two events. Both handler and event (method/lambda and webClient)
160 | //are owned by the window, so after it is disposed on close they can be garbaged out.
161 | wc.DownloadFileCompleted += WcDownloadFileCompleted;
162 | wc.DownloadProgressChanged += (sender, args) => Util.Send(() => progress.Value = args.ProgressPercentage);
163 | wc.DownloadFileAsync(new Uri(url), where, successAction); //passing action as token
164 | progress.Visibility = Visibility.Visible;
165 | IsEnabled = false; //this is called from UI (Click starts it)
166 | }
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/Views/WelcomeArrow.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/Views/WelcomeArrow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | namespace Power8.Views
4 | {
5 | ///
6 | /// Shows bouncing arrow pointed to Power8 button
7 | ///
8 | public partial class WelcomeArrow : INotifyPropertyChanged
9 | {
10 | ///
11 | /// .ctor
12 | ///
13 | public WelcomeArrow()
14 | {
15 | Util.FpReset();
16 | InitializeComponent();
17 | }
18 |
19 | private double _rotation;
20 | ///
21 | /// Gets or sets the angle the arrow is rotated, and thus the bouncing direction.
22 | ///
23 | public double Rotation
24 | {
25 | get { return _rotation; }
26 | set
27 | {
28 | _rotation = value;
29 | var h = PropertyChanged;
30 | if (h != null)
31 | h(this, new PropertyChangedEventArgs("Rotation"));
32 | }
33 | }
34 |
35 | public event PropertyChangedEventHandler PropertyChanged;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | False
12 |
13 |
14 |
15 |
16 |
17 | False
18 |
19 |
20 | False
21 |
22 |
23 | False
24 |
25 |
26 | True
27 |
28 |
29 | True
30 |
31 |
32 | 2
33 |
34 |
35 | True
36 |
37 |
38 |
39 |
40 |
41 | True
42 |
43 |
44 | True
45 |
46 |
47 | True
48 |
49 |
50 | True
51 |
52 |
53 | True
54 |
55 |
56 | False
57 |
58 |
59 |
60 |
61 |
62 | True
63 |
64 |
65 | True
66 |
67 |
68 | False
69 |
70 |
71 | False
72 |
73 |
74 | True
75 |
76 |
77 | True
78 |
79 |
80 | False
81 |
82 |
83 | False
84 |
85 |
86 | False
87 |
88 |
89 | 2
90 |
91 |
92 | True
93 |
94 |
95 | True
96 |
97 |
98 | False
99 |
100 |
101 | False
102 |
103 |
104 | <?xml version="1.0" encoding="utf-8"?>
105 | <P8SearchProviders>
106 | <Provider key="b">https://www.bing.com/search?q={0}</Provider>
107 | <Provider key="d">https://www.baidu.com/s?wd={0}</Provider>
108 | <Provider key="g">https://google.com/search?q={0}</Provider>
109 | <Provider key="w">https://en.wikipedia.org/w/index.php?search={0}</Provider>
110 | <Provider key="y">https://search.yahoo.com/search?p={0}</Provider>
111 | <Provider key="в">https://ru.wikipedia.org/w/index.php?search={0}</Provider>
112 | </P8SearchProviders>
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
--------------------------------------------------------------------------------