Beispiel #1
0
        private void Analyze_Async_Compare(object state)
        {
            AppxPackageComparisonResult resultNoResource   = new AppxPackageComparisonResult();
            AppxPackageComparisonResult resultWithResource = new AppxPackageComparisonResult();

            try
            {
                List <string> packagePaths = state as List <string>;

                List <AppxPackageReader> readerList          = new List <AppxPackageReader>();
                List <AppxPackage>       allMainPackages     = new List <AppxPackage>();
                List <AppxPackage>       allResourcePackages = new List <AppxPackage>();

                foreach (string path in packagePaths)
                {
                    AppxPackageReader r = new AppxPackageReader(path);
                    readerList.Add(r);
                    r.Run(); // async
                }

                foreach (AppxPackageReader r in readerList)
                {
                    r.Wait(); // make sure package reader has completed

                    if (r.ErrorEncountered)
                    {
                        ShowError("Error Reading Package.", r.ErrorText);
                        return;
                    }

                    allMainPackages.AddRange(r.MainPackages);
                    allResourcePackages.AddRange(r.ResourcePackages);
                }

                List <AppxPackage> allPackages = new List <AppxPackage>();
                allPackages.AddRange(allMainPackages);
                allPackages.AddRange(allResourcePackages);

                // Get the result for no resource packages
                resultNoResource = GetInterPackageDupFiles(resultNoResource, allMainPackages);
                resultNoResource = GetCrossPackageDeDupdFiles(resultNoResource, allMainPackages);
                resultNoResource = AnalyzeFileSpaceSavings(resultNoResource, allMainPackages);

                // Get the result with resource packages
                resultWithResource = GetInterPackageDupFiles(resultWithResource, allResourcePackages);
                resultWithResource = GetCrossPackageDeDupdFiles(resultWithResource, allPackages);
                resultWithResource = AnalyzeFileSpaceSavings(resultWithResource, allPackages);
            }
            catch
            {
                // TBD
            }

            // update UI on main thread
            this.Dispatcher.BeginInvoke(new OutputComparisonDataToUIDelegate(OutputComparisonDataToUI), resultNoResource, resultWithResource);
        }
Beispiel #2
0
        private List <AppxPackage> GetContainedPackagesFromBundle(IStream stream)
        {
            List <AppxPackage> containedPackages = new List <AppxPackage>();

            try
            {
                var bundleFactory               = (IAppxBundleFactory) new AppxBundleFactory();
                var bundlePackageReader         = bundleFactory.CreateBundleReader(stream);
                var bundleManifestReader        = bundlePackageReader.GetManifest();
                var bundleManifestInfoItemsEnum = bundleManifestReader.GetPackageInfoItems();

                List <AppxPackageReader> allPackageReadersFromBundle = new List <AppxPackageReader>();
                while (bundleManifestInfoItemsEnum.GetHasCurrent())
                {
                    var bundleManifestPackageInfo = bundleManifestInfoItemsEnum.GetCurrent();

                    // get represented file
                    var appxFile = bundlePackageReader.GetPayloadPackage(bundleManifestPackageInfo.GetFileName());

                    // get the appxpackage
                    AppxPackageReader r = new AppxPackageReader(appxFile.GetStream());
                    allPackageReadersFromBundle.Add(r);
                    r.Run();

                    bundleManifestInfoItemsEnum.MoveNext();

                    Marshal.ReleaseComObject(bundleManifestPackageInfo);
                }

                foreach (AppxPackageReader r in allPackageReadersFromBundle)
                {
                    r.Wait();
                    containedPackages.AddRange(r.MainPackages);
                    containedPackages.AddRange(r.ResourcePackages);
                }

                Marshal.ReleaseComObject(bundleManifestInfoItemsEnum);
                Marshal.ReleaseComObject(bundleManifestReader);
                Marshal.ReleaseComObject(bundlePackageReader);
                Marshal.ReleaseComObject(bundleFactory);
            }
            catch
            {
                // TBD
            }
            return(containedPackages);
        }
Beispiel #3
0
        private void Analyze_Async_Update(object state)
        {
            AppxPackageComparisonResult result = new AppxPackageComparisonResult();

            try
            {
                List <string> packagePaths = state as List <string>;

                // make sure there are only two packages
                if (packagePaths.Count > 2)
                {
                    ShowError("Too many packages", "There can only be 2 packages selected for an update check.");
                    return;
                }
                else if (packagePaths.Count < 2)
                {
                    ShowError("Too few packages", "There must be 2 packages selected for an update check.");
                    return;
                }

                string firstPackagePath  = packagePaths[0];
                string secondPackagePath = packagePaths[1];

                // make sure they're both the same package type
                if (0 != Path.GetExtension(firstPackagePath).ToLower()
                    .CompareTo(
                        Path.GetExtension(secondPackagePath).ToLower()))
                {
                    ShowError("Different Package Types", "The packages must be of the same type (e.g. both .appxbundle or both .appx)");
                    return;
                }

                AppxManifest firstPackageManifest  = AppxPackageReader.GetManifestFromPath(firstPackagePath);
                AppxManifest secondPackageManifest = AppxPackageReader.GetManifestFromPath(secondPackagePath);

                string errorMsg;
                if (!firstPackageManifest.IsUpdate(secondPackageManifest, out errorMsg))
                {
                    ShowError("Identities not suited for update", errorMsg);
                    return;
                }

                AppxPackageReader incommingPackageReader;
                AppxPackageReader outgoingpackageReader;

                // firstPackageManifest is incomming (newer)
                if (firstPackageManifest.ComparePackageVersions(secondPackageManifest) > 0)
                {
                    incommingPackageReader = new AppxPackageReader(firstPackagePath);
                    outgoingpackageReader  = new AppxPackageReader(secondPackagePath);
                }
                // secondPackageManifest is incomming (newer)
                else
                {
                    outgoingpackageReader  = new AppxPackageReader(firstPackagePath);
                    incommingPackageReader = new AppxPackageReader(secondPackagePath);
                }

                // read the packages
                incommingPackageReader.Run();
                outgoingpackageReader.Run();

                // get all the packages
                List <AppxPackage> incommingPackageSet = new List <AppxPackage>();
                List <AppxPackage> outgoingPackageSet  = new List <AppxPackage>();

                incommingPackageReader.Wait();
                incommingPackageSet.AddRange(incommingPackageReader.MainPackages);
                incommingPackageSet.AddRange(incommingPackageReader.ResourcePackages);

                outgoingpackageReader.Wait();
                outgoingPackageSet.AddRange(outgoingpackageReader.MainPackages);
                outgoingPackageSet.AddRange(outgoingpackageReader.ResourcePackages);

                // get the list of block map files
                Dictionary <string, List <AppxBlockMapFile> > incommingPackageFiles = new Dictionary <string, List <AppxBlockMapFile> >();
                foreach (AppxPackage p in incommingPackageSet)
                {
                    incommingPackageFiles = incommingPackageFiles.Concat(p.BlockMap)
                                            .GroupBy(kvp => kvp.Key)
                                            .ToDictionary(g => g.Key, g => g.SelectMany(v => v.Value).ToList());
                }

                Dictionary <string, List <AppxBlockMapFile> > outgoingPackageFiles = new Dictionary <string, List <AppxBlockMapFile> >();
                foreach (AppxPackage p in outgoingPackageSet)
                {
                    outgoingPackageFiles = outgoingPackageFiles.Concat(p.BlockMap)
                                           .GroupBy(kvp => kvp.Key)
                                           .ToDictionary(g => g.Key, g => g.SelectMany(v => v.Value).ToList());
                }


                // Determine the hardlinked files
                List <string> sameFileHashes = new List <string>();
                foreach (string key in incommingPackageFiles.Keys)
                {
                    // if it's the same
                    if (outgoingPackageFiles.ContainsKey(key))
                    {
                        sameFileHashes.Add(key);
                        foreach (AppxBlockMapFile a in incommingPackageFiles[key])
                        {
                            result.BytesHardlinked += a.UncompressedSize;
                        }

                        ChangeResult cr = new ChangeResult()
                        {
                            Package   = incommingPackageFiles[key].First().ParentPackage.Manifest.FullName(),
                            FileName  = incommingPackageFiles[key].First().FileName,
                            BlockHash = incommingPackageFiles[key].First().FinalFileHash,
                            Size      = incommingPackageFiles[key].First().UncompressedSize,
                        };

                        result.FileHardLinkChangeResults.Add(cr.FileName, cr);
                    }
                }

                // remove hardlinked files
                foreach (string key in sameFileHashes)
                {
                    incommingPackageFiles.Remove(key);
                    outgoingPackageFiles.Remove(key);
                }

                //get full list of blocks
                Dictionary <string, List <AppxBlockMapBlock> > incommingPackageBlocks = new Dictionary <string, List <AppxBlockMapBlock> >();
                Dictionary <string, List <AppxBlockMapBlock> > outgoingPackageBlocks  = new Dictionary <string, List <AppxBlockMapBlock> >();

                foreach (List <AppxBlockMapFile> list in incommingPackageFiles.Values)
                {
                    foreach (AppxBlockMapFile file in list)
                    {
                        foreach (AppxBlockMapBlock block in file.Blocks)
                        {
                            if (!incommingPackageBlocks.ContainsKey(block.Hash))
                            {
                                incommingPackageBlocks.Add(block.Hash, new List <AppxBlockMapBlock>());
                            }
                            incommingPackageBlocks[block.Hash].Add(block);
                        }
                    }
                }

                foreach (List <AppxBlockMapFile> list in outgoingPackageFiles.Values)
                {
                    foreach (AppxBlockMapFile file in list)
                    {
                        foreach (AppxBlockMapBlock block in file.Blocks)
                        {
                            if (!outgoingPackageBlocks.ContainsKey(block.Hash))
                            {
                                outgoingPackageBlocks.Add(block.Hash, new List <AppxBlockMapBlock>());
                            }
                            outgoingPackageBlocks[block.Hash].Add(block);
                        }
                    }
                }

                // Determine Copied / Downloaded
                foreach (string hash in incommingPackageBlocks.Keys)
                {
                    // if its going to be copied
                    if (outgoingPackageBlocks.ContainsKey(hash))
                    {
                        result.BlocksCopied += incommingPackageBlocks[hash].First().CompressedSize *(ulong)incommingPackageBlocks[hash].Count;

                        ChangeResult cr = new ChangeResult()
                        {
                            Package   = incommingPackageBlocks[hash].First().ParentFile.ParentPackage.Manifest.FullName(),
                            FileName  = incommingPackageBlocks[hash].First().ParentFile.FileName,
                            BlockHash = incommingPackageBlocks[hash].First().Hash,
                            Size      = incommingPackageBlocks[hash].First().ParentFile.UncompressedSize,
                        };

                        if (!result.BlockCopiedChangeResults.ContainsKey(cr.FileName))
                        {
                            result.BlockCopiedChangeResults.Add(cr.FileName, cr);
                        }
                    }

                    // if its going to be downloaded
                    else if (!outgoingPackageBlocks.ContainsKey(hash))
                    {
                        result.BlocksDownloaded += incommingPackageBlocks[hash].First().CompressedSize *(ulong)incommingPackageBlocks[hash].Count;

                        ChangeResult cr = new ChangeResult()
                        {
                            Package   = incommingPackageBlocks[hash].First().ParentFile.ParentPackage.Manifest.FullName(),
                            FileName  = incommingPackageBlocks[hash].First().ParentFile.FileName,
                            BlockHash = incommingPackageBlocks[hash].First().Hash,
                            Size      = incommingPackageBlocks[hash].First().ParentFile.UncompressedSize,
                        };

                        if (!result.BlockDownloadChangeResults.ContainsKey(cr.FileName))
                        {
                            result.BlockDownloadChangeResults.Add(cr.FileName, cr);
                        }
                    }
                }

                foreach (string hash in outgoingPackageBlocks.Keys)
                {
                    // if its going to be deleted
                    if (!incommingPackageBlocks.ContainsKey(hash))
                    {
                        result.BlocksDeleted += outgoingPackageBlocks[hash].First().CompressedSize *(ulong)outgoingPackageBlocks[hash].Count;

                        ChangeResult cr = new ChangeResult()
                        {
                            Package   = outgoingPackageBlocks[hash].First().ParentFile.ParentPackage.Manifest.FullName(),
                            FileName  = outgoingPackageBlocks[hash].First().ParentFile.FileName,
                            BlockHash = outgoingPackageBlocks[hash].First().Hash,
                            Size      = outgoingPackageBlocks[hash].First().ParentFile.UncompressedSize,
                        };

                        if (!result.BlockDeletedChangeResults.ContainsKey(cr.FileName))
                        {
                            result.BlockDeletedChangeResults.Add(cr.FileName, cr);
                        }
                    }
                }
            }
            catch (Exception ex)
            { }

            this.Dispatcher.BeginInvoke(new OutputUpdateComparisonDataToUIDelegate(OutputUpdateComparisonDataToUI), result);
        }