Winify – Diff between revs 28 and 30

Subversion Repositories:
Rev:
Show entire fileIgnore whitespace
Rev 28 Rev 30
Line 1... Line 1...
1 using System; 1 using System;
2 using System.Collections.Generic; 2 using System.Collections.Generic;
-   3 using System.Diagnostics;
3 using System.Drawing; 4 using System.Drawing;
4 using System.IO; 5 using System.IO;
5 using System.Reflection; 6 using System.Reflection;
6 using System.Runtime.InteropServices; 7 using System.Threading;
7 using System.Threading.Tasks; 8 using System.Threading.Tasks;
8 using System.Windows.Forms; 9 using System.Windows.Forms;
9 using Microsoft.Win32; 10 using Microsoft.Win32;
Line 10... Line 11...
10   11  
11 namespace Winify.Utilities 12 namespace Winify.Utilities
12 { 13 {
13 public static class Miscellaneous 14 public static class Miscellaneous
14 { 15 {
Line 15... Line 16...
15 #region Public Methods 16 #region Public Methods
16   17  
17 public static TimeSpan GetIdleTime() -  
18 { 18 public static bool LaunchOnBootSet(bool enable)
19 var lastInPut = new Natives.LASTINPUTINFO(); 19 {
Line 20... Line 20...
20 lastInPut.cbSize = (uint)Marshal.SizeOf(lastInPut); 20 using var key = Registry.CurrentUser.OpenSubKey
21 Natives.GetLastInputInfo(ref lastInPut); -  
Line 22... Line 21...
22   21 ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
23 return TimeSpan.FromMilliseconds((uint)Environment.TickCount - lastInPut.dwTime); -  
24 } -  
25   -  
26 public static bool LaunchOnBootSet(bool enable) 22  
27 { -  
28 using (var key = Registry.CurrentUser.OpenSubKey -  
29 ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true)) -  
30 { -  
31 if (key == null) return false; 23 if (key == null) return false;
32   24  
33 switch (enable) 25 switch (enable)
34 { 26 {
35 case true: 27 case true:
36 key.SetValue(Constants.AssemblyName, Assembly.GetEntryAssembly().Location); 28 key.SetValue(Constants.AssemblyName, Assembly.GetEntryAssembly().Location);
37 break; -  
38 default: 29 break;
Line 39... Line 30...
39 key.DeleteValue(Constants.AssemblyName, false); 30 default:
40 break; 31 key.DeleteValue(Constants.AssemblyName, false);
Line 41... Line 32...
41 } 32 break;
42 } 33 }
43   34  
44 return true; 35 return true;
45 } 36 }
46   37  
47 public static bool LaunchOnBootGet() -  
48 { 38 public static bool LaunchOnBootGet()
Line 49... Line 39...
49 using (var key = Registry.CurrentUser.OpenSubKey 39 {
50 ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true)) 40 using var key = Registry.CurrentUser.OpenSubKey
51 { 41 ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
52 return key?.GetValue(Constants.AssemblyName) != null; 42  
53 } 43 return key?.GetValue(Constants.AssemblyName) != null;
54 } 44 }
55   45  
56 /// <summary> 46 /// <summary>
-   47 /// Enable double buffering for an arbitrary control.
57 /// Enable double buffering for an arbitrary control. 48 /// </summary>
58 /// </summary> 49 /// <param name="control">the control to enable double buffering for</param>
59 /// <param name="control">the control to enable double buffering for</param> 50 /// <returns>true on success</returns>
60 /// <returns>true on success</returns> 51 /// <remarks>Do not enable double buffering on RDP: https://devblogs.microsoft.com/oldnewthing/20060103-12/?p=32793</remarks>
61 /// <remarks>Do not enable double buffering on RDP: https://devblogs.microsoft.com/oldnewthing/20060103-12/?p=32793</remarks> 52 public static void SetDoubleBuffered(this Control control)
62 public static bool SetDoubleBuffered(this Control control) -  
63 { -  
64 if (SystemInformation.TerminalServerSession) return false; 53 {
65   -  
66 var dgvType = control.GetType(); 54 // Double buffering can make DGV slow in remote desktop
67 var pi = dgvType.GetProperty("DoubleBuffered", 55 if (!SystemInformation.TerminalServerSession)
Line 68... Line 56...
68 BindingFlags.Instance | BindingFlags.NonPublic); 56 {
69 if (pi == null) return false; 57 var dgvType = control.GetType();
70   58 var pi = dgvType.GetProperty("DoubleBuffered",
71 pi.SetValue(control, true, null); 59 BindingFlags.Instance | BindingFlags.NonPublic);
72   -  
73 return true; 60 pi.SetValue(control, true, null);
74 } 61 }
75   62 }
76 public static async Task<Icon> CreateIconFromResource(string resource) 63  
77 { -  
78 var iconBytes = await LoadResource(resource); 64 public static async Task<Icon> CreateIconFromResource(string resource)
Line 79... Line 65...
79 using (var iconMemoryStream = new MemoryStream(iconBytes)) 65 {
80 { 66 var iconBytes = await LoadResource(resource);
81 var bitmap = (Bitmap)Image.FromStream(iconMemoryStream); 67 using var iconMemoryStream = new MemoryStream(iconBytes);
Line 82... Line 68...
82 var bitmapIntPtr = bitmap.GetHicon(); 68 var bitmap = (Bitmap)Image.FromStream(iconMemoryStream);
83 var icon = Icon.FromHandle(bitmapIntPtr); -  
84 return icon; -  
Line 85... Line 69...
85 } 69 var bitmapIntPtr = bitmap.GetHicon();
Line 86... Line 70...
86 } 70 var icon = Icon.FromHandle(bitmapIntPtr);
Line 87... Line 71...
87   71 return icon;
Line 88... Line 72...
88 public static async Task<byte[]> LoadResource(string resource) 72 }
-   73  
89 { 74 public static async Task<byte[]> LoadResource(string resource)
90 var assembly = Assembly.GetExecutingAssembly(); 75 {
Line 91... Line 76...
91   76 var assembly = Assembly.GetExecutingAssembly();
92 using (var manifestResourceStream = assembly.GetManifestResourceStream(resource)) 77  
93 { 78 using var manifestResourceStream = assembly.GetManifestResourceStream(resource);
Line 112... Line 97...
112 } 97 }
Line 113... Line 98...
113   98  
114 action(control); 99 action(control);
Line -... Line 100...
-   100 }
115 } 101  
116   102 /// <summary>
117 public static T MapValueToRange<T>(this T value, T xMin, T xMax, T yMin, T yMax) 103 /// Attempts to access a file within <see cref="timeout" /> milliseconds by retrying to access the file every
118 where T : struct, IComparable<T>, IConvertible 104 /// <see cref="retry" /> milliseconds.
119 { 105 /// </summary>
120 return (dynamic)yMin + 106 /// <param name="path">the path to the file</param>
121 ((dynamic)yMax - (dynamic)yMin) * ((dynamic)value - (dynamic)xMin) / 107 /// <param name="mode">the file mode used to access the file</param>
122 ((dynamic)xMax - (dynamic)xMin); -  
-   108 /// <param name="access">the file access to use</param>
-   109 /// <param name="share">the file share to use</param>
-   110 /// <param name="cancellationToken">a cancellation token</param>
-   111 /// <param name="retry">the amount of milliseconds to retry between accesses to the file</param>
123 } 112 /// <param name="timeout">the amount of time in milliseconds to attempt and access the file</param>
124   113 /// <returns>a file stream if the file could be accessed within the allotted time</returns>
125 public static IEnumerable<TU> SequenceSubtract<TU, TV>(this IEnumerable<TU> a, 114 public static async Task<FileStream> GetFileStream(string path, FileMode mode, FileAccess access,
126 IEnumerable<TV> b, 115 FileShare share, CancellationToken cancellationToken,
127 Func<TU, TV, bool> cmp) 116 int retry = 1000, int timeout = 60000)
Line 128... Line 117...
128 { 117 {
129 var eb = new List<TV>(b); 118 var time = Stopwatch.StartNew();
130   119  
131 using (var ea = a.GetEnumerator()) 120 while (time.ElapsedMilliseconds < timeout && !cancellationToken.IsCancellationRequested)
132 { -  
133 while (ea.MoveNext()) -  
134 { -  
135 if (ea.Current == null) continue; -  
136   121 {
137 foreach (var ib in eb) -  
138 { -  
139 if (cmp.Invoke(ea.Current, ib)) continue; -  
140   -  
141 yield return ea.Current; -  
142   122 try
-   123 {
-   124 return new FileStream(path, mode, access, share);
-   125 }
-   126 catch (IOException e)
-   127 {
-   128 // access error
-   129 if (e.HResult != -2147024864) throw;
143 break; 130 }
-   131  
-   132 await Task.Delay(retry, cancellationToken);
144 } 133 }
Line 145... Line 134...
145 } 134  
146 } 135 throw new TimeoutException($"Failed to get a access to {path} within {timeout}ms.");
147 } 136 }