Exemple #1
0
        private async Task <IList <Log> > GetLogsFromProvider(
            PSObject provider,
            int maxCount = 0,
            CancellationToken cancellationToken = default, IProgress <ProgressData> itemProgress = null)
        {
            var factory = new LogFactory();

            cancellationToken.ThrowIfCancellationRequested();
            var logName = (string)provider.BaseObject;

            itemProgress?.Report(new ProgressData(0, "Reading " + logName + "..."));

            cancellationToken.ThrowIfCancellationRequested();

            using var psLocal = await PowerShellSession.CreateForModule().ConfigureAwait(false);

            var scriptContent = "Get-WinEvent -ProviderName " + logName + " -ErrorAction SilentlyContinue";

            if (maxCount > 0)
            {
                scriptContent += " -MaxEvents " + maxCount;
            }

            using var scriptLocal = psLocal.AddScript(scriptContent);

            itemProgress?.Report(new ProgressData(10, "Getting events, please wait..."));
            using var logItems = await psLocal.InvokeAsync(itemProgress).ConfigureAwait(false);

            itemProgress?.Report(new ProgressData(70, "Getting events, please wait..."));
            return(logItems.Select(log => factory.CreateFromPowerShellObject(log, logName)).ToList());
        }
        public async Task <string> CreateSelfSignedCertificate(
            DirectoryInfo outputDirectory,
            string publisherName,
            string publisherDisplayName,
            string password,
            DateTime?validUntil,
            CancellationToken cancellationToken = default,
            IProgress <ProgressData> progress   = null)
        {
            // ReSharper disable once AssignNullToNotNullAttribute
            var scriptPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "scripts", "create-certificate.ps1");

            using var ps = await PowerShellSession.CreateForModule("PKI", true).ConfigureAwait(false);

            using var cmd = ps.AddCommand(scriptPath);
            using var paramPublisherFriendlyName = cmd.AddParameter("PublisherFriendlyName", publisherDisplayName);
            using var paramPublisherName         = cmd.AddParameter("PublisherName", publisherName);
            using var paramPassword           = cmd.AddParameter("Password", password);
            using var paramOutputDirectory    = cmd.AddParameter("OutputDirectory", outputDirectory.FullName);
            using var paramCreatePasswordFile = cmd.AddParameter("CreatePasswordFile");
            using var paramNotAfter           = cmd.AddParameter("NotAfter", validUntil ?? DateTime.Now.AddDays(365));

            using var result = await ps.InvokeAsync(progress).ConfigureAwait(false);

            return(Path.Combine(outputDirectory.FullName, publisherDisplayName + ".pfx"));
        }
        public async Task InstallCertificate(string certificateFile, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = null)
        {
            try
            {
                // ReSharper disable once AssignNullToNotNullAttribute
                var scriptPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "scripts", "install-certificate.ps1");

                using var ps = await PowerShellSession.CreateForModule("PKI", true).ConfigureAwait(false);

                using var cmd = ps.AddCommand(scriptPath);
                using var paramCerOutputFileName = cmd.AddParameter("CerFileName", certificateFile);
                using var result = await ps.InvokeAsync(progress).ConfigureAwait(false);
            }
            catch (COMException e)
            {
                Console.WriteLine("COM Exception " + e.HResult);
                if (e.HResult == -2146885623)
                {
                    // This is to catch COMException 0x80092009 file not found which may be thrown for invalid or missing cert files.
                    throw new Exception("Could not install certificate " + certificateFile + ". The file may be invalid, corrupted or missing. System error code: 0x" + e.HResult.ToString("X2"), e);
                }

                throw;
            }
        }
Exemple #4
0
        public async Task Dismount(AppxVolume volume, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = default)
        {
            using var session = await PowerShellSession.CreateForAppxModule().ConfigureAwait(false);

            using var command = session.AddCommand("Dismount-AppxVolume");
            command.AddParameter("Volume", volume.Name);
            await session.InvokeAsync(progress).ConfigureAwait(false);
        }
Exemple #5
0
        public async Task <AppxVolume> GetVolumeForPath(string path, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = default)
        {
            var di = new DirectoryInfo(path);

            if (!di.Exists)
            {
                throw new DirectoryNotFoundException("Directory was not found.");
            }

            if (di.Attributes.HasFlag(FileAttributes.ReparsePoint))
            {
                var target = GetSymbolicLinkTarget(di);
                path = target;
            }

            using var session = await PowerShellSession.CreateForAppxModule().ConfigureAwait(false);

            using var command = session.AddCommand("Get-AppPackageVolume");
            command.AddParameter("Path", path);

            var result = await session.InvokeAsync(progress).ConfigureAwait(false);

            var item = result.FirstOrDefault();

            if (item == null)
            {
                return(null);
            }

            var name             = (string)item.Properties.FirstOrDefault(p => p.Name == "Name")?.Value;
            var packageStorePath = (string)item.Properties.FirstOrDefault(p => p.Name == "PackageStorePath")?.Value;

            var letter = packageStorePath != null && packageStorePath.Length > 2 && packageStorePath[1] == ':' ? packageStorePath.Substring(0, 1) + ":\\" : null;

            var appxVolume = new AppxVolume {
                Name = name, PackageStorePath = packageStorePath
            };

            if (letter == null)
            {
                return(appxVolume);
            }

            var drive = DriveInfo.GetDrives().FirstOrDefault(d => d.RootDirectory.FullName.StartsWith(letter, StringComparison.OrdinalIgnoreCase));

            if (drive == null)
            {
                return(appxVolume);
            }

            appxVolume.IsDriveReady       = drive.IsReady;
            appxVolume.DiskLabel          = drive.VolumeLabel;
            appxVolume.Capacity           = drive.TotalSize;
            appxVolume.AvailableFreeSpace = drive.AvailableFreeSpace;

            return(appxVolume);
        }
Exemple #6
0
        public async Task MovePackageToVolume(string volumePackagePath, string packageFullName, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = default)
        {
            using var session = await PowerShellSession.CreateForAppxModule().ConfigureAwait(false);

            using var command = session.AddCommand("Move-AppxPackage");
            command.AddParameter("Package", packageFullName);
            command.AddParameter("Volume", volumePackagePath);

            Logger.Debug($"Executing Move-AppxPackage -Package \"{packageFullName}\" -Volume \"{volumePackagePath}\"...");
            await session.InvokeAsync(progress).ConfigureAwait(false);
        }
Exemple #7
0
        public async Task RunToolInContext(string packageFamilyName, string appId, string toolPath, string arguments = null, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = default)
        {
            if (SideloadingChecker.GetStatus() != SideloadingStatus.DeveloperMode)
            {
                throw new DeveloperModeException("Developer mode must be enabled to use this feature.");
            }

            Logger.Info("Running tool '{0}' with arguments '{1}' in package '{2}' (AppId = '{3}')...", toolPath, arguments, packageFamilyName, appId);
            if (packageFamilyName == null)
            {
                throw new ArgumentNullException(nameof(packageFamilyName));
            }

            if (toolPath == null)
            {
                throw new ArgumentNullException(nameof(toolPath));
            }

            using var ps = await PowerShellSession.CreateForAppxModule().ConfigureAwait(false);

            using var cmd = ps.AddCommand("Invoke-CommandInDesktopPackage");
            cmd.AddParameter("Command", toolPath);
            cmd.AddParameter("PackageFamilyName", packageFamilyName);
            cmd.AddParameter("AppId", appId);
            cmd.AddParameter("PreventBreakaway");

            if (!string.IsNullOrEmpty(arguments))
            {
                cmd.AddParameter("Args", arguments);
            }

            Logger.Debug("Executing Invoke-CommandInDesktopPackage");
            try
            {
                // ReSharper disable once UnusedVariable
                using var result = await ps.InvokeAsync().ConfigureAwait(false);
            }
            catch (Exception e)
            {
                if (e.HResult == -2147024891 /* 0x80070005 E_ACCESSDENIED */)
                {
                    throw new DeveloperModeException("Developer mode must be enabled to use this feature.", e);
                }

                if (e.HResult == -2146233087)
                {
                    throw new AdminRightsRequiredException("This tool requires admin rights.", e);
                }

                throw;
            }
        }
Exemple #8
0
        public async Task <List <AppxVolume> > GetAll(CancellationToken cancellationToken = default, IProgress <ProgressData> progress = default)
        {
            using var session = await PowerShellSession.CreateForAppxModule().ConfigureAwait(false);

            using var command = session.AddCommand("Get-AppxVolume");

            var results = await session.InvokeAsync(progress).ConfigureAwait(false);

            if (!results.Any())
            {
                return(new List <AppxVolume>());
            }

            var list = new List <AppxVolume>();

            foreach (var item in results)
            {
                var packageStorePath = (string)item.Properties.FirstOrDefault(p => p.Name == "PackageStorePath")?.Value;
                if (string.IsNullOrEmpty(packageStorePath))
                {
                    Logger.Warn("Empty path for " + item);
                    continue;
                }

                var isOffline      = true == (bool?)item.Properties.FirstOrDefault(p => p.Name == "IsOffline")?.Value;
                var name           = (string)item.Properties.FirstOrDefault(p => p.Name == "Name")?.Value;
                var isSystemVolume = true == (bool?)item.Properties.FirstOrDefault(p => p.Name == "IsSystemVolume")?.Value;

                list.Add(new AppxVolume {
                    Name = name, PackageStorePath = packageStorePath, IsOffline = isOffline, IsSystem = isSystemVolume
                });
            }

            var drives = DriveInfo.GetDrives();

            foreach (var drive in list.Where(c => c.PackageStorePath.IndexOf(":\\", StringComparison.Ordinal) == 1))
            {
                var letter        = drive.PackageStorePath.Substring(0, 3);
                var matchingDrive = drives.FirstOrDefault(d => string.Equals(d.RootDirectory.FullName, letter, StringComparison.OrdinalIgnoreCase));
                if (matchingDrive?.IsReady == true)
                {
                    drive.Capacity           = matchingDrive.TotalSize;
                    drive.AvailableFreeSpace = matchingDrive.AvailableFreeSpace;
                    drive.DiskLabel          = matchingDrive.VolumeLabel;
                    drive.IsDriveReady       = true;
                }
            }

            return(list.OrderBy(l => l.PackageStorePath).ToList());
        }
Exemple #9
0
        public async Task <List <Log> > GetLogs(int maxCount, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = default)
        {
            Logger.Info("Getting last {0} log files...", maxCount);

            var allLogs = new List <Log>();

            using var ps = await PowerShellSession.CreateForModule().ConfigureAwait(false);

            using var script = ps.AddScript("(Get-WinEvent -ListLog *Microsoft-Windows-*Appx* -ErrorAction SilentlyContinue).ProviderNames");
            using var logs   = await ps.InvokeAsync().ConfigureAwait(false);

            var logNames = logs.ToArray();

            var progresses = new IProgress <ProgressData> [logNames.Length];

            using (var wrapperProgress = new WrappedProgress(progress ?? new Progress <ProgressData>()))
            {
                for (var index = 0; index < logNames.Length; index++)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    progresses[index] = wrapperProgress.GetChildProgress();
                }

                var allTasks = new List <Task <IList <Log> > >();
                for (var index = 0; index < logNames.Length; index++)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    var item         = logNames[index];
                    var itemProgress = progresses[index];

                    allTasks.Add(this.GetLogsFromProvider(item, maxCount, cancellationToken, itemProgress));
                }

                await Task.WhenAll(allTasks).ConfigureAwait(false);

                foreach (var item in allTasks)
                {
                    allLogs.AddRange(await item.ConfigureAwait(false));
                }
            }

            if (maxCount > 0)
            {
                return(allLogs.OrderByDescending(l => l.DateTime).Take(maxCount).ToList());
            }

            return(allLogs);
        }
        private async Task <bool> ExtractCertificateFromMsix(
            string msixFile,
            bool importToStore = false,
            string outputFile  = null,
            IProgress <ProgressData> progress = null)
        {
            // ReSharper disable once AssignNullToNotNullAttribute
            var scriptPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "scripts", "extract-certificate-from-msix.ps1");

            using var ps = await PowerShellSession.CreateForModule("PKI", true).ConfigureAwait(false);

            using var cmd = ps.AddCommand(scriptPath);
            using var paramSourceMsixFile = cmd.AddParameter("SourceMsixFile", msixFile);

            if (outputFile != null)
            {
                cmd.AddParameter("CerOutputFileName", outputFile);
            }

            if (importToStore)
            {
                cmd.AddParameter("ImportToStore");
            }

            try
            {
                using var result = await ps.InvokeAsync(progress).ConfigureAwait(false);

                return(true);
            }
            catch (UnauthorizedAccessException e)
            {
                if (importToStore)
                {
                    if (e.InnerException != null)
                    {
                        throw new UnauthorizedAccessException(e.Message + ". Did you start MSIX Hero as administrator?", e.InnerException);
                    }

                    throw new UnauthorizedAccessException(e.Message + ". Did you start MSIX Hero as administrator?");
                }

                throw;
            }
        }
Exemple #11
0
        public async Task <AppxVolume> GetDefault(CancellationToken cancellationToken = default, IProgress <ProgressData> progress = default)
        {
            using var session = await PowerShellSession.CreateForAppxModule().ConfigureAwait(false);

            using var command = session.AddCommand("Get-AppxDefaultVolume");

            var result = await session.InvokeAsync(progress).ConfigureAwait(false);

            var item = result.FirstOrDefault();

            if (item == null)
            {
                return(null);
            }

            var baseType         = item.BaseObject.GetType();
            var name             = (string)baseType.GetProperty("Name")?.GetValue(item.BaseObject);
            var packageStorePath = (string)baseType.GetProperty("PackageStorePath")?.GetValue(item.BaseObject);

            var letter = packageStorePath != null && packageStorePath.Length > 2 && packageStorePath[1] == ':' ? packageStorePath.Substring(0, 1) + ":\\" : null;

            var appxVolume = new AppxVolume {
                Name = name, PackageStorePath = packageStorePath
            };

            if (letter != null)
            {
                var drive = DriveInfo.GetDrives().First(d => d.RootDirectory.FullName.StartsWith(letter, StringComparison.OrdinalIgnoreCase));
                if (drive != null)
                {
                    appxVolume.IsDriveReady       = drive.IsReady;
                    appxVolume.DiskLabel          = drive.VolumeLabel;
                    appxVolume.Capacity           = drive.TotalSize;
                    appxVolume.AvailableFreeSpace = drive.AvailableFreeSpace;
                }
            }

            return(appxVolume);
        }
Exemple #12
0
        public async Task <AppxVolume> Add(string drivePath, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = default)
        {
            using var session = await PowerShellSession.CreateForAppxModule().ConfigureAwait(false);

            using var command = session.AddCommand("Add-AppxVolume");
            command.AddParameter("Path", drivePath);

            var results = await session.InvokeAsync(progress).ConfigureAwait(false);

            var obj = results.FirstOrDefault();

            if (obj == null)
            {
                throw new InvalidOperationException($"Volume {drivePath} could not be created.");
            }

            var baseType         = obj.BaseObject.GetType();
            var name             = (string)baseType.GetProperty("Name")?.GetValue(obj.BaseObject);
            var packageStorePath = (string)baseType.GetProperty("PackageStorePath")?.GetValue(obj.BaseObject);

            return(new AppxVolume {
                Name = name, PackageStorePath = packageStorePath
            });
        }