ProjectArcade
140 строк · 4.2 Кб
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.Runtime.InteropServices;
6using System.Runtime.InteropServices.ComTypes;
7using System.Management;
8using System.Diagnostics;
9using System.Globalization;
10using System.IO;
11
12namespace EmulatorLauncher.Common.Compression
13{
14public class MountFile : IDisposable
15{
16public static MountFile Mount(string filename, string extractionpath, string overlayPath)
17{
18if (!Zip.IsCompressedFile(filename))
19return null;
20
21string mountPath = Path.Combine(Path.GetDirectoryName(typeof(MountFile).Assembly.Location), "mount.exe");
22if (!File.Exists(mountPath))
23return null;
24
25string dokan = Environment.GetEnvironmentVariable("DokanLibrary2");
26if (!Directory.Exists(dokan))
27return null;
28
29dokan = Path.Combine(dokan, "dokan2.dll");
30if (!File.Exists(dokan))
31return null;
32
33var drive = FileTools.FindFreeDriveLetter();
34if (drive == null)
35return null;
36
37if (!Zip.IsFreeDiskSpaceAvailableForExtraction(filename, extractionpath))
38return null;
39
40if (!Directory.Exists(extractionpath))
41{
42Directory.CreateDirectory(extractionpath);
43FileTools.CompressDirectory(extractionpath);
44}
45
46List<string> args = new List<string>();
47
48if (Debugger.IsAttached)
49args.Add("-debug");
50
51args.Add("-drive");
52args.Add(drive.Substring(0, 2));
53
54if (!string.IsNullOrEmpty(extractionpath))
55{
56// extractionpath = Path.Combine(extractionpath, Path.GetFileName(filename));
57
58args.Add("-extractionpath");
59args.Add("\"" + extractionpath + "\"");
60
61Directory.CreateDirectory(extractionpath);
62}
63
64if (!string.IsNullOrEmpty(overlayPath))
65{
66args.Add("-overlay");
67args.Add("\"" + overlayPath + "\"");
68
69Directory.CreateDirectory(overlayPath);
70}
71
72args.Add("\"" + filename + "\"");
73
74var mountProcess = Process.Start(new ProcessStartInfo()
75{
76FileName = mountPath,
77WorkingDirectory = Path.GetDirectoryName(filename),
78Arguments = string.Join(" ", args.ToArray()),
79UseShellExecute = false,
80CreateNoWindow = !Debugger.IsAttached
81});
82
83int time = Environment.TickCount;
84int elapsed = 0;
85
86while (elapsed < 5000)
87{
88if (mountProcess.WaitForExit(10))
89return null;
90
91if (Directory.Exists(drive))
92{
93Job.Current.AddProcess(mountProcess);
94return new MountFile(mountProcess, filename, drive, extractionpath, overlayPath);
95}
96
97int newTime = Environment.TickCount;
98elapsed = time - newTime;
99time = newTime;
100}
101
102try { mountProcess.Kill(); }
103catch { }
104
105return null;
106}
107
108private MountFile(Process process, string filename, string driveLetter, string extractionpath, string overlayPath)
109{
110Filename = filename;
111DriveLetter = driveLetter;
112ExtractionPath = extractionpath;
113OverlayPath = overlayPath;
114Process = process;
115}
116
117public string Filename { get; private set; }
118public string DriveLetter { get; private set; }
119public string ExtractionPath { get; private set; }
120public string OverlayPath { get; private set; }
121
122public Process Process { get; private set; }
123
124public void UnMount()
125{
126try { Process.Kill(); }
127catch { }
128}
129
130public void Dispose()
131{
132UnMount();
133}
134
135public static void ShowDownloadDokanPage()
136{
137Process.Start("https://github.com/dokan-dev/dokany/releases");
138}
139}
140}
141