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; } } }
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; }
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); } } } }
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; }
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(); }
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); }
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); } } } } }
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(); } } }
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(); } }