示例#1
0
        public void OpenPriFile(string path)
        {
            ClosePriFile();

            try
            {
                PriStream = File.OpenRead(path);

                PriFile = PriFile.Parse(PriStream);
            }
            catch
            {
                ClosePriFile();
                MessageBox.Show("Could not read file.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            if (!PriFile.Sections.OfType <ResourceMapSection>().Any())
            {
                ClosePriFile();
                MessageBox.Show("Incompatible PRI file.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            ResourceRootPath = Path.GetDirectoryName(path);

            GetEntries();

            SetResourceRootPathCommand.RaiseCanExecuteChanged();
        }
        public CandidateViewModel(PriFile priFile, Stream priStream, string resourceRootPath, ResourceMapItem resourceMapItem, Candidate candidate)
        {
            GoToLocationCommand = new RelayCommand(GoToLocationCommand_CanExecute, GoToLocationCommand_Execute);
            SaveAsCommand       = new RelayCommand(SaveAsCommand_CanExecute, SaveAsCommand_Execute);

            this.priFile          = priFile;
            this.priStream        = priStream;
            this.resourceRootPath = resourceRootPath;
            this.resourceMapItem  = resourceMapItem;
            Candidate             = candidate;

            DecisionInfoSection decisionInfoSection =
                priFile.GetSectionByRef(priFile.PriDescriptorSection.DecisionInfoSections.First());

            qualifiers = decisionInfoSection.QualifierSets[candidate.QualifierSet].Qualifiers;

            if (candidate.Type == ResourceValueType.AsciiPath ||
                candidate.Type == ResourceValueType.Utf8Path ||
                candidate.Type == ResourceValueType.Path)
            {
                string path = (string)GetData();

                if (path != null)
                {
                    locationPath = path;
                    Location     = path;

                    if (!File.Exists(FullLocationPath))
                    {
                        LocationNotFound = true;
                    }
                }
                else
                {
                    Location = "";
                }
            }
            else
            {
                Location = "(embedded)";
            }

            if (candidate.SourceFile != null)
            {
                string sourcePath = priFile.GetReferencedFileByRef(candidate.SourceFile.Value).FullName;

                if (File.Exists(sourcePath))
                {
                    Location = sourcePath + ": " + Location;
                }
                else
                {
                    Location       = sourcePath + " (not found)";
                    SourceNotFound = true;
                }
            }
        }
示例#3
0
        public ScopeDetailPage(PriFile priFile, Stream priStream, ResourceMapScope scope)
        {
            InitializeComponent();

            this.priFile   = priFile;
            this.priStream = priStream;

            bool dotAsPathSeparator = scope.FullName.Contains(@"\Resources");

            List <StringResource> stringResources = new List <StringResource>();

            EnumerateStringResources(scope, string.Empty, dotAsPathSeparator, stringResources);

            keyValueListView.ItemsSource = stringResources;
        }
示例#4
0
        private IEnumerable <Candidate> EnumerateCandidates(ResourceMapItem resourceMapItem)
        {
            ResourceMapSection primaryResourceMapSection =
                PriFile.GetSectionByRef(PriFile.PriDescriptorSection.PrimaryResourceMapSection.Value);

            CandidateSet candidateSet;

            if (primaryResourceMapSection.CandidateSets.TryGetValue(resourceMapItem.Index, out candidateSet))
            {
                foreach (Candidate candidate in candidateSet.Candidates)
                {
                    if (candidate != null)
                    {
                        yield return(candidate);
                    }
                }
            }
        }
示例#5
0
        public void SelectedCandidateChanged()
        {
            if (selectedCandidate == null)
            {
                return;
            }

            object data = selectedCandidate.GetData();

            if (data == null)
            {
                PreviewContent = null;
                return;
            }

            byte[] byteData = null;

            object previewContent = null;

            switch (selectedCandidate.Candidate.Type)
            {
            case ResourceValueType.Path:
            case ResourceValueType.AsciiPath:
            case ResourceValueType.Utf8Path:
                string rootPath;

                if (selectedCandidate.Candidate.SourceFile == null)
                {
                    rootPath = ResourceRootPath;
                }
                else
                {
                    rootPath = Path.GetDirectoryName(PriFile.GetReferencedFileByRef(selectedCandidate.Candidate.SourceFile.Value).FullName);
                }

                string externalFilePath = Path.Combine(rootPath, (string)data);

                if (File.Exists(externalFilePath))
                {
                    byteData = File.ReadAllBytes(externalFilePath);
                }
                else
                {
                    previewContent = new PathNotFoundPreviewPage(new PathNotFoundPreviewViewModel(externalFilePath), this);
                }
                break;

            case ResourceValueType.String:
            case ResourceValueType.AsciiString:
            case ResourceValueType.Utf8String:
                previewContent = data;
                break;

            case ResourceValueType.EmbeddedData:
                byteData = (byte[])data;
                break;
            }

            if (previewContent == null)
            {
                string itemName = selectedEntry?.ResourceMapEntry.Name ?? "";

                try
                {
                    if (itemName.EndsWith(".xbf", StringComparison.OrdinalIgnoreCase))
                    {
                        previewContent = new XbfPreviewPage(new XbfPreviewViewModel(byteData));
                    }
                    else if (itemName.EndsWith(".bmp", StringComparison.OrdinalIgnoreCase) ||
                             itemName.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase) ||
                             itemName.EndsWith(".jpeg", StringComparison.OrdinalIgnoreCase) ||
                             itemName.EndsWith(".png", StringComparison.OrdinalIgnoreCase) ||
                             itemName.EndsWith(".gif", StringComparison.OrdinalIgnoreCase) ||
                             itemName.EndsWith(".ico", StringComparison.OrdinalIgnoreCase) ||
                             itemName.EndsWith(".tif", StringComparison.OrdinalIgnoreCase) ||
                             itemName.EndsWith(".tiff", StringComparison.OrdinalIgnoreCase))
                    {
                        previewContent = new ImagePreviewPage(new ImagePreviewViewModel(byteData));
                    }
                    else if ((byteData.Length >= 3 && byteData[0] == 0xEF && byteData[1] == 0xBB && byteData[2] == 0xBF) ||
                             byteData.Length >= 2 && byteData[0] == 0xEF && byteData[1] == 0xFF ||
                             byteData.Length >= 2 && byteData[0] == 0xFF && byteData[1] == 0xEF ||
                             byteData.All(b => b >= 8 && b <= 127))
                    {
                        previewContent = new TextPreviewPage(new TextPreviewViewModel(byteData));
                    }
                    else
                    {
                        previewContent = new BinaryPreviewPage(new BinaryPreviewViewModel(byteData));
                    }
                }
                catch (Exception ex)
                {
                    TextBlock textBlock = new TextBlock();

                    textBlock.Margin = new Thickness(8);
                    textBlock.Text   = ex.ToString();

                    previewContent = textBlock;
                }
            }

            PreviewContent = previewContent;
        }
示例#6
0
        private void GetEntries()
        {
            Entries.Clear();
            Candidates.Clear();

            ResourceMapSection        primaryResourceMapSection = PriFile.GetSectionByRef(PriFile.PriDescriptorSection.PrimaryResourceMapSection.Value);
            HierarchicalSchemaSection schemaSection             = PriFile.GetSectionByRef(primaryResourceMapSection.SchemaSection);

            Dictionary <ResourceMapEntry, EntryViewModel> entriesToViewModels = new Dictionary <ResourceMapEntry, EntryViewModel>();

            bool parentMissing = false;

            do
            {
                foreach (ResourceMapScope scope in schemaSection.Scopes)
                {
                    if (scope.FullName == string.Empty)
                    {
                        continue;
                    }

                    IList <EntryViewModel> targetEntryCollection;

                    if (scope.Parent == null)
                    {
                        targetEntryCollection = Entries;
                    }
                    else
                    {
                        EntryViewModel parentViewModel;

                        if (scope.Parent.FullName == string.Empty)
                        {
                            targetEntryCollection = Entries;
                        }
                        else
                        if (!entriesToViewModels.TryGetValue(scope.Parent, out parentViewModel))
                        {
                            parentMissing = true;
                            continue;
                        }
                        else
                        {
                            targetEntryCollection = parentViewModel.Children;
                        }
                    }

                    EntryViewModel entry = new EntryViewModel(scope);

                    GetEntryType(entry);

                    entriesToViewModels.Add(scope, entry);

                    targetEntryCollection.Add(entry);
                }
            } while (parentMissing);

            foreach (ResourceMapItem item in schemaSection.Items)
            {
                EntryViewModel parentViewModel;

                if (!entriesToViewModels.TryGetValue(item.Parent, out parentViewModel))
                {
                    continue;
                }

                parentViewModel.Children.Add(new EntryViewModel(item));

                GetEntryType(parentViewModel.Children.Last());
            }

            CollapseStringResources();
        }
示例#7
0
        public static string Localize(string priFile, string appId, string packageFullName, string resourceId)
        {
            if (resourceId == null || !resourceId.StartsWith("ms-resource:"))
            {
                return(resourceId);
            }

            if (!File.Exists(priFile))
            {
                return(resourceId);
            }

            var outBuff = new StringBuilder(1024);


            resourceId = resourceId.Remove(0, "ms-resource:".Length);
            if (string.IsNullOrEmpty(resourceId))
            {
                return(resourceId);
            }

            string fullString;

            if (resourceId.StartsWith("//"))
            {
                fullString = "@{" + priFile + "?ms-resource:" + resourceId.TrimEnd('/') + "}";
                if (SHLoadIndirectString(fullString, outBuff, outBuff.Capacity, IntPtr.Zero) == 0)
                {
                    return(outBuff.ToString());
                }
            }

            string msResource;

            if (resourceId[0] == '/')
            {
                var split         = resourceId.Split('/');
                var newResourceId = string.Join('/', split.Take(2)) + "/" + string.Join('.', split.Skip(2));
                msResource = "ms-resource://" + appId + newResourceId.TrimEnd('/');
            }
            else if (resourceId.IndexOf('/') != -1)
            {
                var split         = resourceId.Split('/');
                var newResourceId = string.Join('/', split.Take(1)) + "/" + string.Join('.', split.Skip(1));
                msResource = "ms-resource://" + appId + "/" + newResourceId.TrimEnd('/');
            }
            else
            {
                var split         = resourceId.Split('/');
                var newResourceId = string.Join('/', split.Take(1)) + "/" + string.Join('.', split.Skip(1));
                msResource = "ms-resource://" + appId + "/resources/" + newResourceId.TrimEnd('/');
            }

            fullString = "@{" + priFile + "?" + msResource + "}";

            if (SHLoadIndirectString(fullString, outBuff, outBuff.Capacity, IntPtr.Zero) == 0)
            {
                return(outBuff.ToString());
            }

            fullString = "@{" + packageFullName + "?" + msResource + "}";
            if (SHLoadIndirectString(fullString, outBuff, outBuff.Capacity, IntPtr.Zero) == 0)
            {
                return(outBuff.ToString());
            }

            using (var s = File.OpenRead(priFile))
            {
                var pri  = PriFile.Parse(s);
                var name = pri.Sections.OfType <HierarchicalSchemaSection>().FirstOrDefault(s => s.UniqueName != null);
                if (name != null)
                {
                    msResource = "ms-resource://" + name.UniqueName.Substring(name.UniqueName.IndexOf("://", StringComparison.OrdinalIgnoreCase) + 3) + "Resources/" + resourceId.TrimEnd('/');
                    fullString = "@{" + priFile + "?" + msResource + "}";

                    if (SHLoadIndirectString(fullString, outBuff, outBuff.Capacity, IntPtr.Zero) == 0)
                    {
                        return(outBuff.ToString());
                    }

                    msResource = "ms-resource://" + name.UniqueName.Substring(name.UniqueName.IndexOf("://", StringComparison.OrdinalIgnoreCase) + 3) + resourceId.TrimEnd('/');
                    fullString = "@{" + priFile + "?" + msResource + "}";

                    if (SHLoadIndirectString(fullString, outBuff, outBuff.Capacity, IntPtr.Zero) == 0)
                    {
                        return(outBuff.ToString());
                    }
                }
            }

            return(resourceId);
        }
示例#8
0
        static void Main(string[] args)
        {
            if (args.Length != 1)
            {
                Console.WriteLine("Usage: PriInfo <path to PRI file>");
                return;
            }

            using (FileStream stream = File.OpenRead(args[0]))
            {
                PriFile priFile = PriFile.Parse(stream);

                Console.WriteLine("Sections:");

                foreach (Section section in priFile.Sections)
                {
                    Console.WriteLine("  {0}", section);
                }

                Console.WriteLine();
                Console.WriteLine("Candidates:");

                foreach (var resourceMapSectionRef in priFile.PriDescriptorSection.ResourceMapSections)
                {
                    ResourceMapSection resourceMapSection = priFile.GetSectionByRef(resourceMapSectionRef);

                    if (resourceMapSection.HierarchicalSchemaReference != null)
                    {
                        continue;
                    }

                    DecisionInfoSection decisionInfoSection = priFile.GetSectionByRef(resourceMapSection.DecisionInfoSection);

                    foreach (var candidateSet in resourceMapSection.CandidateSets.Values)
                    {
                        ResourceMapItem item = priFile.GetResourceMapItemByRef(candidateSet.ResourceMapItem);

                        Console.WriteLine("  {0}:", item.FullName);

                        foreach (var candidate in candidateSet.Candidates)
                        {
                            string value = null;

                            if (candidate.SourceFile != null)
                            {
                                value = string.Format("<external in {0}>", priFile.GetReferencedFileByRef(candidate.SourceFile.Value).FullName);
                            }
                            else
                            {
                                ByteSpan byteSpan;

                                if (candidate.DataItem != null)
                                {
                                    byteSpan = priFile.GetDataItemByRef(candidate.DataItem.Value);
                                }
                                else
                                {
                                    byteSpan = candidate.Data.Value;
                                }

                                stream.Seek(byteSpan.Offset, SeekOrigin.Begin);

                                byte[] data;

                                using (BinaryReader binaryReader = new BinaryReader(stream, Encoding.Default, true))
                                    data = binaryReader.ReadBytes((int)byteSpan.Length);

                                switch (candidate.Type)
                                {
                                case ResourceValueType.AsciiPath:
                                case ResourceValueType.AsciiString:
                                    value = Encoding.ASCII.GetString(data).TrimEnd('\0');
                                    break;

                                case ResourceValueType.Utf8Path:
                                case ResourceValueType.Utf8String:
                                    value = Encoding.UTF8.GetString(data).TrimEnd('\0');
                                    break;

                                case ResourceValueType.Path:
                                case ResourceValueType.String:
                                    value = Encoding.Unicode.GetString(data).TrimEnd('\0');
                                    break;

                                case ResourceValueType.EmbeddedData:
                                    value = string.Format("<{0} bytes>", data.Length);
                                    break;
                                }
                            }

                            QualifierSet qualifierSet = decisionInfoSection.QualifierSets[candidate.QualifierSet];

                            string qualifiers = string.Join(", ", qualifierSet.Qualifiers.Select(q => string.Format("{0}={1}", q.Type, q.Value)));

                            Console.WriteLine("    Candidate {0}: {1}", qualifiers, value);
                        }
                    }
                }
            }
        }
示例#9
0
        static void Main(string[] args)
        {
            if (args.Length != 1)
            {
                Console.WriteLine("Usage: PriInfo <path to PRI file>");
                return;
            }

            var languages = new Dictionary <string, JObject>();

            using (FileStream stream = File.OpenRead(args[0]))
            {
                PriFile priFile = PriFile.Parse(stream);

                foreach (var resourceMapSectionRef in priFile.PriDescriptorSection.ResourceMapSections)
                {
                    ResourceMapSection resourceMapSection = priFile.GetSectionByRef(resourceMapSectionRef);

                    if (resourceMapSection.HierarchicalSchemaReference != null)
                    {
                        continue;
                    }

                    DecisionInfoSection decisionInfoSection = priFile.GetSectionByRef(resourceMapSection.DecisionInfoSection);

                    foreach (var candidateSet in resourceMapSection.CandidateSets.Values)
                    {
                        ResourceMapItem item = priFile.GetResourceMapItemByRef(candidateSet.ResourceMapItem);

                        Console.WriteLine("  {0}:", item.FullName);

                        foreach (var candidate in candidateSet.Candidates)
                        {
                            if (candidate.SourceFile != null)
                            {
                                continue;
                            }

                            string value = null;

                            var qualifierSet = decisionInfoSection.QualifierSets[candidate.QualifierSet];
                            //var language = qualifierSet.Qualifiers.FirstOrDefault(l => l.Type == QualifierType.Language)?.Value ?? qualifierSet.Qualifiers.FirstOrDefault(l => l.Type == QualifierType.Scale)?.Value ?? "generic";
                            //language = language.ToLowerInvariant();

                            var set      = "generic";
                            var language = qualifierSet.Qualifiers.FirstOrDefault(l => l.Type == QualifierType.Language);
                            if (language != null)
                            {
                                set = language.Value.ToLowerInvariant();
                            }
                            else
                            {
                                var scale = qualifierSet.Qualifiers.FirstOrDefault(l => l.Type == QualifierType.Scale);
                                if (scale != null)
                                {
                                    set = $"scale-{scale.Value}";
                                }
                            }

                            var json      = languages.TryGetValue(set, out var la) ? la : languages[set] = new JObject();
                            var keysArray = item.FullName.Split(new[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);
                            var keys      = keysArray.Take(keysArray.Length - 1);
                            if (!keys.Any())
                            {
                                keys = new[] { "generic" }
                            }
                            ;

                            foreach (var key in keys)
                            {
                                json = json.TryGetValue(key, out var j) ? (JObject)j : (JObject)(json[key] = new JObject());
                            }

                            ByteSpan byteSpan;

                            if (candidate.DataItem != null)
                            {
                                byteSpan = priFile.GetDataItemByRef(candidate.DataItem.Value);
                            }
                            else
                            {
                                byteSpan = candidate.Data.Value;
                            }

                            stream.Seek(byteSpan.Offset, SeekOrigin.Begin);
                            byte[] data = new byte[byteSpan.Length];
                            stream.Read(data, 0, (int)byteSpan.Length);

                            switch (candidate.Type)
                            {
                            case ResourceValueType.AsciiPath:
                            case ResourceValueType.AsciiString:
                                value = Encoding.ASCII.GetString(data).TrimEnd('\0');
                                break;

                            case ResourceValueType.Utf8Path:
                            case ResourceValueType.Utf8String:
                                value = Encoding.UTF8.GetString(data).TrimEnd('\0');
                                break;

                            case ResourceValueType.Path:
                            case ResourceValueType.String:
                                value = Encoding.Unicode.GetString(data).TrimEnd('\0');
                                break;

                            case ResourceValueType.EmbeddedData:
                                continue;
                            }

                            var name = item.Name;
                            //if (scale != null && scale.Value != "100")
                            //{
                            //    name = Path.ChangeExtension(name, $".scale-{scale.Value}" + Path.GetExtension(name));
                            //}

                            json[item.Name] = value;
                            //var name = item.FullName.Substring(11).Replace('\\', '.');
                            //json.WriteLine($"<data name=\"{name}\" xml:space=\"preserve\">");
                            //json.WriteLine($"  <value><![CDATA[{value}]]></value>");
                            //json.WriteLine($"</data>");

                            Console.WriteLine("    Candidate {0}: {1}", language, value);
                        }
                    }
                }
            }

            foreach (var lang in languages)
            {
                File.WriteAllText($"{lang.Key}.json", lang.Value.ToString());
                //lang.Value.Flush();
            }
        }
    }
示例#10
0
        public object GetData()
        {
            byte[] data;

            if (Candidate.SourceFile == null)
            {
                ByteSpan byteSpan;

                if (Candidate.DataItem != null)
                {
                    byteSpan = priFile.GetDataItemByRef(Candidate.DataItem.Value);
                }
                else
                {
                    byteSpan = Candidate.Data.Value;
                }

                priStream.Seek(byteSpan.Offset, SeekOrigin.Begin);

                using (BinaryReader binaryReader = new BinaryReader(priStream, Encoding.Default, true))
                    data = binaryReader.ReadBytes((int)byteSpan.Length);
            }
            else
            {
                string sourcePath = priFile.GetReferencedFileByRef(Candidate.SourceFile.Value).FullName;

                if (!File.Exists(sourcePath))
                {
                    return(null);
                }

                using (FileStream fileStream = File.OpenRead(sourcePath))
                {
                    PriFile  sourcePriFile = PriFile.Parse(fileStream);
                    ByteSpan byteSpan      = sourcePriFile.GetDataItemByRef(Candidate.DataItem.Value);

                    fileStream.Seek(byteSpan.Offset, SeekOrigin.Begin);

                    using (BinaryReader binaryReader = new BinaryReader(fileStream, Encoding.Default, true))
                        data = binaryReader.ReadBytes((int)byteSpan.Length);
                }
            }

            switch (Candidate.Type)
            {
            case ResourceValueType.AsciiPath:
            case ResourceValueType.AsciiString:
                return(Encoding.ASCII.GetString(data).TrimEnd('\0'));

            case ResourceValueType.Utf8Path:
            case ResourceValueType.Utf8String:
                return(Encoding.UTF8.GetString(data).TrimEnd('\0'));

            case ResourceValueType.Path:
            case ResourceValueType.String:
                return(Encoding.Unicode.GetString(data).TrimEnd('\0'));

            case ResourceValueType.EmbeddedData:
                return(data);

            default:
                throw new Exception();
            }
        }