QuickImage – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System;
2 using System.ComponentModel;
3 using System.Diagnostics;
4 using System.Drawing;
5 using System.IO;
6 using System.Linq;
7 using System.Reflection;
8 using System.Threading;
9 using System.Threading.Tasks;
10 using System.Windows.Forms;
11 using Microsoft.Win32;
12  
13 namespace QuickImage.Utilities
14 {
15 public static class Miscellaneous
16 {
17 #region Public Methods
18  
19 /// <summary>
20 ///
21 /// </summary>
22 /// <param name="sourceFile"></param>
23 /// <param name="destinationFile"></param>
24 /// <param name="cancellationToken"></param>
25 /// <returns></returns>
26 /// <remarks>https://stackoverflow.com/questions/882686/asynchronous-file-copy-move-in-c-sharp</remarks>
27 public static async Task CopyFileAsync(string sourceFile, string destinationFile, CancellationToken cancellationToken = default)
28 {
29 var fileOptions = FileOptions.Asynchronous | FileOptions.SequentialScan;
30 var bufferSize = 4096;
31  
32 using var sourceStream =
33 new FileStream(sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, fileOptions);
34 using var destinationStream =
35 new FileStream(destinationFile, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, bufferSize, fileOptions);
36 await sourceStream.CopyToAsync(destinationStream, bufferSize, cancellationToken)
37 .ConfigureAwait(false);
38 }
39  
40 public static async Task CopyFileAsync(Stream sourceStream, string destinationFile, CancellationToken cancellationToken = default)
41 {
42 var fileOptions = FileOptions.Asynchronous | FileOptions.SequentialScan;
43 var bufferSize = 4096;
44  
45 using var destinationStream =
46 new FileStream(destinationFile, FileMode.CreateNew, FileAccess.Write, FileShare.None, bufferSize, fileOptions);
47 await sourceStream.CopyToAsync(destinationStream, bufferSize, cancellationToken)
48 .ConfigureAwait(false);
49 }
50  
51 public static bool LaunchOnBootSet(bool enable)
52 {
53 using var key = Registry.CurrentUser.OpenSubKey
54 ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
55 if (key == null) return false;
56  
57 switch (enable)
58 {
59 case true:
60 key.SetValue(Constants.AssemblyName, Assembly.GetEntryAssembly().Location);
61 break;
62 default:
63 key.DeleteValue(Constants.AssemblyName, false);
64 break;
65 }
66  
67 return true;
68 }
69  
70 public static bool LaunchOnBootGet()
71 {
72 using var key = Registry.CurrentUser.OpenSubKey
73 ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
74 return key?.GetValue(Constants.AssemblyName) != null;
75 }
76  
77 /// <summary>
78 /// Enable double buffering for an arbitrary control.
79 /// </summary>
80 /// <param name="control">the control to enable double buffering for</param>
81 /// <returns>true on success</returns>
82 /// <remarks>Do not enable double buffering on RDP: https://devblogs.microsoft.com/oldnewthing/20060103-12/?p=32793</remarks>
83 public static void SetDoubleBuffered(this Control control)
84 {
85 // Double buffering can make DGV slow in remote desktop
86 if (!SystemInformation.TerminalServerSession)
87 {
88 var dgvType = control.GetType();
89 var pi = dgvType.GetProperty("DoubleBuffered",
90 BindingFlags.Instance | BindingFlags.NonPublic);
91 pi.SetValue(control, true, null);
92 }
93 }
94  
95 public static async Task<Icon> CreateIconFromResource(string resource)
96 {
97 var iconBytes = await LoadResource(resource);
98 using var iconMemoryStream = new MemoryStream(iconBytes);
99 var bitmap = (Bitmap)Image.FromStream(iconMemoryStream);
100 var bitmapIntPtr = bitmap.GetHicon();
101 var icon = Icon.FromHandle(bitmapIntPtr);
102 return icon;
103 }
104  
105 public static async Task<byte[]> LoadResource(string resource)
106 {
107 var assembly = Assembly.GetExecutingAssembly();
108  
109 using var manifestResourceStream = assembly.GetManifestResourceStream(resource);
110 if (manifestResourceStream == null) return null;
111  
112 var memoryStream = new MemoryStream();
113  
114 await manifestResourceStream.CopyToAsync(memoryStream);
115  
116 memoryStream.Position = 0L;
117  
118 return memoryStream.ToArray();
119 }
120  
121 public static void InvokeIfRequired<T>(this T control, Action<T> action) where T : Control
122 {
123 if (control.InvokeRequired)
124 {
125 control.BeginInvoke((MethodInvoker)delegate { action(control); });
126 return;
127 }
128  
129 action(control);
130 }
131  
132 /// <summary>
133 /// Attempts to access a file within <see cref="timeout" /> milliseconds by retrying to access the file every
134 /// <see cref="retry" /> milliseconds.
135 /// </summary>
136 /// <param name="path">the path to the file</param>
137 /// <param name="mode">the file mode used to access the file</param>
138 /// <param name="access">the file access to use</param>
139 /// <param name="share">the file share to use</param>
140 /// <param name="cancellationToken">a cancellation token</param>
141 /// <param name="retry">the amount of milliseconds to retry between accesses to the file</param>
142 /// <param name="timeout">the amount of time in milliseconds to attempt and access the file</param>
143 /// <returns>a file stream if the file could be accessed within the allotted time</returns>
144 public static async Task<FileStream> GetFileStream(string path, FileMode mode, FileAccess access,
145 FileShare share, CancellationToken cancellationToken,
146 int retry = 1000, int timeout = 60000)
147 {
148 var time = Stopwatch.StartNew();
149  
150 while (time.ElapsedMilliseconds < timeout && !cancellationToken.IsCancellationRequested)
151 {
152 try
153 {
154 return new FileStream(path, mode, access, share);
155 }
156 catch (IOException e)
157 {
158 // access error
159 if (e.HResult != -2147024864) throw;
160 }
161  
162 await Task.Delay(retry, cancellationToken);
163 }
164  
165 throw new TimeoutException($"Failed to get a access to {path} within {timeout}ms.");
166 }
167  
168 ///////////////////////////////////////////////////////////////////////////
169 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
170 ///////////////////////////////////////////////////////////////////////////
171 /// <summary>
172 /// Get the description from an enumeration value.
173 /// </summary>
174 /// <param name="value">an enumeration value</param>
175 /// <returns>the description or the empty string</returns>
176 public static string GetDescriptionFromEnumValue(Enum value)
177 {
178 var attribute = value.GetType()
179 .GetRuntimeField(value.ToString())
180 .GetCustomAttributes(typeof(DescriptionAttribute), false)
181 .SingleOrDefault() as DescriptionAttribute;
182  
183 return attribute?.Description;
184 }
185  
186 ///////////////////////////////////////////////////////////////////////////
187 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
188 ///////////////////////////////////////////////////////////////////////////
189 /// <summary>
190 /// Get enumeration value from its name attribute.
191 /// </summary>
192 /// <typeparam name="T">the enumeration type</typeparam>
193 /// <param name="description">the description of a member</param>
194 /// <param name="comparison">the string comparison to use</param>
195 /// <returns>the value or the default of T if case no name attribute found</returns>
196 public static T GetEnumValueFromDescription<T>(string description,
197 StringComparison comparison = StringComparison.OrdinalIgnoreCase)
198 {
199 var field = typeof(T).GetRuntimeFields()
200 .SelectMany(f => f.GetCustomAttributes(
201 typeof(DescriptionAttribute),
202 false),
203 (
204 f,
205 a) => new { Field = f, Att = a })
206 .SingleOrDefault(a => string.Equals(((DescriptionAttribute)a.Att)
207 .Description,
208 description,
209 comparison));
210  
211 return (T)field?.Field.GetValue(Activator.CreateInstance<T>());
212 }
213  
214 #endregion
215 }
216 }