public void MountNetworkDrive(Guid cloudId, string mountPoint) { if (mountPoint?.Length != 3 || !mountPoint.EndsWith(@":\", StringComparison.OrdinalIgnoreCase)) { throw new ArgumentException("Mount Point is invalid."); } if (Globals.Volumes.TryGetValue(cloudId, out var thread) && thread != null) { UnmountNetworkDrive(cloudId); } var cloud = Globals.CloudService.PersonalClouds.First(x => new Guid(x.Id) == cloudId); var dokanThread = new AsyncContextThread(); dokanThread.Factory.Run(() => { try { var disk = new DokanFileSystemAdapter(new PersonalCloudRootFileSystem(cloud, Globals.Loggers.CreateLogger <PersonalCloudRootFileSystem>())); disk.Mount(mountPoint, DokanOptions.EnableNotificationAPI, 5, new DokanyLogger()); } catch (Exception exception) { Globals.Loggers.CreateLogger <CloudManagerService>().LogError(exception, "Mount failed."); Globals.Database.SaveSetting(WindowsUserSettings.EnableVolumeMounting, "0"); Task.Run(async() => { await Globals.NotificationCenter.InvokeAsync(x => x.OnVolumeIOError(mountPoint, exception)) .ConfigureAwait(false); await Task.Delay(TimeSpan.FromSeconds(5)).ConfigureAwait(false); Globals.Volumes.TryRemove(cloudId, out _); dokanThread.Dispose(); }); } }); Globals.Database.SaveSetting(WindowsUserSettings.EnableVolumeMounting, "1"); Globals.Database.SaveMountPoint(cloudId, mountPoint); Globals.Volumes[cloudId] = dokanThread; }
public bool Start(HostControl hostControl) { try { Logger.LogInformation("Windows service started."); HostControl = hostControl; Initialize(); Runners = new CancellationTokenSource(); /* * var ipcServiceCollection = new ServiceCollection() * .AddSingleton<CloudManagerService>() * .AddSingleton<StorageService>() * .AddIpc(builder => { * builder.AddNamedPipe() * .AddService<ICloudManager>(services => services.GetRequiredService<CloudManagerService>()) * .AddService<IFileSystemController>(services => services.GetRequiredService<CloudManagerService>()) * .AddService<IPersistentStorage>(services => services.GetRequiredService<StorageService>()); * }); * _ = new IpcServiceHostBuilder(ipcServiceCollection.BuildServiceProvider()) * .AddNamedPipeEndpoint<ICloudManager>("Cloud Manager", Pipes.CloudAdmin, true) * .AddNamedPipeEndpoint<IFileSystemController>("Dokan Controller", Pipes.DiskMounter, true) * .AddNamedPipeEndpoint<IPersistentStorage>("Storage", Pipes.UserSettings, true) * .Build().RunAsync(Runners.Token); */ Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder() .ConfigureServices(services => { services.AddSingleton <ICloudManager, CloudManagerService>(); }) .ConfigureIpcHost(builder => { builder.AddNamedPipeEndpoint <ICloudManager>(Pipes.CloudAdmin); }) .ConfigureLogging(builder => { builder.SetMinimumLevel(LogLevel.Information); }) .Build().RunAsync(); var services = new ServiceCollection().AddNamedPipeIpcClient <ICloudEventHandler>(NotificationClient, Pipes.NotificationCenter) .BuildServiceProvider(); Globals.NotificationCenter = services.GetRequiredService <IIpcClientFactory <ICloudEventHandler> >() .CreateClient(NotificationClient); #region Restore last-known state of File Sharing if (Globals.Database.CheckSetting(UserSettings.EnableSharing, "1")) { var sharedPath = Globals.Database.LoadSetting(UserSettings.SharingRoot); if (string.IsNullOrEmpty(sharedPath) || !Directory.Exists(sharedPath)) { Globals.Database.Delete <KeyValueModel>(UserSettings.SharingRoot); Globals.Database.SaveSetting(UserSettings.EnableSharing, "0"); sharedPath = null; } Globals.SetupFS(sharedPath); } #endregion Restore last-known state of File Sharing var resourcesPath = Path.Combine(Globals.ConfigurationPath, "Static"); Directory.CreateDirectory(resourcesPath); Globals.CloudService = new PCLocalService(Globals.CloudConfig, Globals.Loggers, Globals.CloudFileSystem, resourcesPath); Globals.CloudService.OnError += (o, e) => { if (e.ErrorCode == ErrorCode.NeedUpdate) { Globals.NotificationCenter.InvokeAsync(x => x.ShowAlert("New Version Available", "Upgrade Personal Cloud to connect to some devices in your network.")); } }; if (!Globals.Database.CheckSetting(UserSettings.LastInstalledVersion, Globals.Version)) { Globals.CloudService.InstallApps().Wait(); } Globals.CloudService.StartService(); Globals.NotificationCenter.InvokeAsync(x => x.OnServiceStarted()); #region Restore last-known state of Network Drives if (Globals.Database.CheckSetting(WindowsUserSettings.EnableVolumeMounting, "1")) { foreach (var cloud in Globals.CloudService.PersonalClouds) { if (cloud == null) { continue; } var cloudId = new Guid(cloud.Id); var mountPoint = Globals.Database.GetMountPoint(cloudId); var dokanThread = new AsyncContextThread(); dokanThread.Factory.Run(() => { try { var disk = new DokanFileSystemAdapter(new PersonalCloudRootFileSystem(cloud, Globals.Loggers.CreateLogger <PersonalCloudRootFileSystem>())); disk.Mount(mountPoint, DokanOptions.EnableNotificationAPI, 5, new NullLogger()); } catch (Exception exception) { Logger.LogError(exception, "OnVolumeIOError exception"); Globals.NotificationCenter.InvokeAsync(x => x.OnVolumeIOError(mountPoint, exception)); } }); Globals.Volumes[cloudId] = dokanThread; } } #endregion return(true); } catch (Exception e) { Logger.LogError(e, "Exception in PersonalCloudWindowsService:Start"); throw; } }