ProjectArcade

Форк
0
339 строк · 12.3 Кб
1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Text;
5
using System.Diagnostics;
6
using System.IO;
7
using System.Management;
8
using System.Runtime.InteropServices;
9
using System.IO.Compression;
10
using System.Security.Cryptography;
11

12
namespace EmulatorLauncher.Common
13
{
14
    public static class FileTools
15
    {
16
        /// <summary>
17
        /// Get MD5 hash
18
        /// </summary>
19
        /// <param name="file"></param>
20
        public static string GetMD5(string file)
21
        {
22
            if (!File.Exists(file))
23
                return null;
24

25
            using (var md5 = MD5.Create())
26
                using (var stream = File.OpenRead(file))
27
                    return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", string.Empty).ToLower();
28
        }
29

30
        /// <summary>
31
        /// Get SHA-1 hash
32
        /// </summary>
33
        /// <param name="file"></param>
34
        public static string GetSHA1(string file)
35
        {
36
            if (!File.Exists(file))
37
                return null;
38

39
            using (FileStream fs = File.OpenRead(file))
40
            {
41
                SHA1 sha = new SHA1Managed();
42
                return BitConverter.ToString(sha.ComputeHash(fs)).Replace("-", string.Empty).ToLower();
43
            }
44
        }
45

46
        /// <summary>
47
        /// Get File size
48
        /// </summary>
49
        /// <param name="file"></param>
50
        public static long GetFileSize(string file)
51
        {
52
            if (!File.Exists(file))
53
                return 0;
54

55
            return new FileInfo(file).Length;            
56
        }
57

58
        public static bool ExtractGZipBytes(byte[] bytes, string fileName)
59
        {
60
            try
61
            {
62
                using (var reader = new MemoryStream(bytes))
63
                {
64
                    using (var decompressedStream = new FileStream(fileName, FileMode.Create, FileAccess.Write))
65
                    {
66
                        using (GZipStream decompressionStream = new GZipStream(reader, CompressionMode.Decompress))
67
                        {
68
                            decompressionStream.CopyTo(decompressedStream);
69
                            return true;
70
                        }
71
                    }
72
                }
73
            }
74
            catch (Exception ex)
75
            {
76
                SimpleLogger.Instance.Error("[ReadGZipStream] Failed " + ex.Message, ex);
77
            }
78

79
            return false;
80
        }
81

82
        public static string GetRelativePath(string basePath, string targetPath)
83
        {
84
            Uri baseUri = new Uri(basePath);
85
            Uri targetUri = new Uri(targetPath);
86

87
            Uri relativeUri = baseUri.MakeRelativeUri(targetUri);
88
            string relativePath = Uri.UnescapeDataString(relativeUri.ToString());
89

90
            return relativePath.Replace('/', '\\');
91
        }
92

93
        public static string FindFreeDriveLetter()
94
        {
95
            var drives = DriveInfo.GetDrives();
96

97
            for (char letter = 'Z'; letter >= 'D'; letter--)
98
                if (!drives.Any(d => d.Name == letter + ":\\"))
99
                    return letter + ":\\";
100

101
            return null;
102
        }
103

104
        private static void TryMoveFile(string sourceFileName, string destFileName)
105
        {
106
            if (File.Exists(sourceFileName))
107
            {
108
                if (File.Exists(destFileName))
109
                {
110
                    try { File.Delete(destFileName); }
111
                    catch { }
112
                }
113

114
                try { File.Move(sourceFileName, destFileName); }
115
                catch { }
116
            }
117
        }
118

119
        public static void TryCreateDirectory(string path)
120
        {
121
            if (Directory.Exists(path))
122
                return;
123

124
            try { Directory.CreateDirectory(path); }
125
            catch { }
126
        }
127

128
        public static void TryDeleteFile(string path)
129
        {
130
            if (!File.Exists(path))
131
                return;
132

133
            try { File.Delete(path); }
134
            catch { }
135
        }
136

137
        public static void TryCopyFile(string sourceFileName, string destFileName, bool overwrite = true)
138
        {
139
            if (!File.Exists(sourceFileName))
140
                return;
141

142
            try { File.Copy(sourceFileName, destFileName, overwrite); }
143
            catch { }
144
        }
145

146
        #region Apis
147
        const uint GENERIC_READ = 0x80000000;
148
        const uint GENERIC_WRITE = 0x40000000;
149
        const uint OPEN_EXISTING = 3;
150
        const uint FILE_SHARE_READ = 1;
151
        const uint FILE_SHARE_WRITE = 2;
152

153
        static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
154

155
        [DllImport("kernel32.dll", SetLastError = true)]
156
        static extern IntPtr CreateFile(
157
            string lpFileName,
158
            uint dwDesiredAccess,
159
            uint dwShareMode,
160
            IntPtr lpSecurityAttributes,
161
            uint dwCreationDisposition,
162
            uint dwFlagsAndAttributes,
163
            IntPtr hTemplateFile
164
        );
165

166
        [DllImport("kernel32.dll", SetLastError = true)]
167
        [return: MarshalAs(UnmanagedType.Bool)]
168
        static extern bool CloseHandle(IntPtr hObject);
169
        #endregion
170

171
        public static bool IsFileLocked(string path)
172
        {
173
            if (!File.Exists(path))
174
                return false;
175

176
            IntPtr handle = CreateFile(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
177
            if (handle == INVALID_HANDLE_VALUE)
178
                return true;
179

180
            CloseHandle(handle);
181
            return false;
182
        }
183

184
        public static void CopyDirectory(string sourceDir, string destinationDir, bool recursive)
185
        {
186
            // Get information about the source directory
187
            var dir = new DirectoryInfo(sourceDir);
188

189
            // Check if the source directory exists
190
            if (!dir.Exists)
191
                throw new DirectoryNotFoundException("Source directory not found: " + dir.FullName);
192

193
            // Cache directories before we start copying
194
            DirectoryInfo[] dirs = dir.GetDirectories();
195

196
            // Create the destination directory
197
            Directory.CreateDirectory(destinationDir);
198

199
            // Get the files in the source directory and copy to the destination directory
200
            foreach (FileInfo file in dir.GetFiles())
201
            {
202
                string targetFilePath = Path.Combine(destinationDir, file.Name);
203
                file.CopyTo(targetFilePath);
204
            }
205

206
            // If recursive and copying subdirectories, recursively call this method
207
            if (recursive)
208
            {
209
                foreach (DirectoryInfo subDir in dirs)
210
                {
211
                    string newDestinationDir = Path.Combine(destinationDir, subDir.Name);
212
                    CopyDirectory(subDir.FullName, newDestinationDir, true);
213
                }
214
            }
215
        }
216

217
        public static void CreateSymlink(string destinationLink, string pathToLink, bool directory = true)
218
        {
219
            string workingDirectory = Path.GetDirectoryName(destinationLink);
220
            string directoryName = Path.GetFileName(destinationLink);
221

222
            var psi = new ProcessStartInfo("cmd.exe", directory ?
223
                "/C mklink /J \"" + directoryName + "\" \"" + pathToLink + "\"" :
224
                "/C mklink \"" + directoryName + "\" \"" + pathToLink + "\"");
225
            psi.WorkingDirectory = workingDirectory;
226
            psi.CreateNoWindow = true;
227
            psi.UseShellExecute = false;
228
            Process.Start(psi).WaitForExit();
229
        }
230

231
        public static void CompressDirectory(string _outputFolder)
232
        {
233
            var dir = new DirectoryInfo(_outputFolder);
234

235
            if (!dir.Exists)
236
            {
237
                dir.Create();
238
            }
239

240
            if ((dir.Attributes & FileAttributes.Compressed) == 0)
241
            {
242
                try
243
                {
244
                    // Enable compression for the output folder
245
                    // (this will save a ton of disk space)
246

247
                    string objPath = "Win32_Directory.Name=" + "'" + dir.FullName.Replace("\\", @"\\").TrimEnd('\\') + "'";
248

249
                    using (ManagementObject obj = new ManagementObject(objPath))
250
                    {
251
                        using (obj.InvokeMethod("Compress", null, null))
252
                        {
253
                            // I don't really care about the return value, 
254
                            // if we enabled it great but it can also be done manually
255
                            // if really needed
256
                        }
257
                    }
258
                }
259
                catch (Exception ex)
260
                {
261
                    System.Diagnostics.Trace.WriteLine("Cannot enable compression for folder '" + dir.FullName + "': " + ex.Message, "WMI");
262
                }
263
            }
264
        }
265

266
        [DllImport("shell32.dll")]
267
        public static extern bool SHGetSpecialFolderPath(IntPtr hwndOwner, [Out]StringBuilder lpszPath, int nFolder, bool fCreate);
268

269
        public static string GetSystemDirectory()
270
        {
271
            if (Environment.Is64BitOperatingSystem)
272
            {
273
                StringBuilder path = new StringBuilder(260);
274
                SHGetSpecialFolderPath(IntPtr.Zero, path, 0x0029, false); // CSIDL_SYSTEMX86
275
                return path.ToString();
276
            }
277

278
            return Environment.SystemDirectory;
279
        }
280

281
        public static string GetShortcutTarget(string file)
282
        {
283
            try
284
            {
285
                if (System.IO.Path.GetExtension(file).ToLower() != ".lnk")
286
                {
287
                    throw new Exception("Supplied file must be a .LNK file");
288
                }
289

290
                FileStream fileStream = File.Open(file, FileMode.Open, FileAccess.Read);
291
                using (System.IO.BinaryReader fileReader = new BinaryReader(fileStream))
292
                {
293
                    fileStream.Seek(0x14, SeekOrigin.Begin);     // Seek to flags
294
                    uint flags = fileReader.ReadUInt32();        // Read flags
295
                    if ((flags & 1) == 1)
296
                    {                      // Bit 1 set means we have to
297
                                           // skip the shell item ID list
298
                        fileStream.Seek(0x4c, SeekOrigin.Begin); // Seek to the end of the header
299
                        uint offset = fileReader.ReadUInt16();   // Read the length of the Shell item ID list
300
                        fileStream.Seek(offset, SeekOrigin.Current); // Seek past it (to the file locator info)
301
                    }
302

303
                    long fileInfoStartsAt = fileStream.Position; // Store the offset where the file info
304
                                                                 // structure begins
305
                    uint totalStructLength = fileReader.ReadUInt32(); // read the length of the whole struct
306
                    fileStream.Seek(0xc, SeekOrigin.Current); // seek to offset to base pathname
307
                    uint fileOffset = fileReader.ReadUInt32(); // read offset to base pathname
308
                                                               // the offset is from the beginning of the file info struct (fileInfoStartsAt)
309
                    fileStream.Seek((fileInfoStartsAt + fileOffset), SeekOrigin.Begin); // Seek to beginning of
310
                                                                                        // base pathname (target)
311
                    long pathLength = (totalStructLength + fileInfoStartsAt) - fileStream.Position - 2; // read
312
                                                                                                        // the base pathname. I don't need the 2 terminating nulls.
313
                    char[] linkTarget = fileReader.ReadChars((int)pathLength); // should be unicode safe
314
                    var link = new string(linkTarget);
315

316
                    int begin = link.IndexOf("\0\0");
317
                    if (begin > -1)
318
                    {
319
                        int end = link.IndexOf("\\\\", begin + 2) + 2;
320
                        end = link.IndexOf('\0', end) + 1;
321

322
                        string firstPart = link.Substring(0, begin);
323
                        string secondPart = link.Substring(end);
324

325
                        return firstPart + secondPart;
326
                    }
327
                    else
328
                    {
329
                        return link;
330
                    }
331
                }
332
            }
333
            catch
334
            {
335
                return "";
336
            }
337
        }
338
    }
339
}
340

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.