Not able to load XPS document on DocumentViewer - wpf

Due to security patch update dated 13 dec 2022 on machine, XPS document is unable display on  DocumentViewer UI control.Although microsoft provided an workaround regarding this. But can any one please help me out is there any other control availabe in WPF that can dispaly the XPS document.
Please let me know
Thanks
your text
I have tried to load XPS document on FlowDocumentScrollViewer, as below
string filePath = #"C:\License.xps"; XpsDocument doc = new XpsDocument(filePath, System.IO.FileAccess.Read); FixedDocumentSequence fds = doc.GetFixedDocumentSequence(); flowDoc.DataContext = fds;
but content of the file don't display on the form.

Related

Could you use Microsoft Print to PDF printer to convert an XPS to a PDF file?

I am trying to use the Microsoft Print to PDF printer to convert an XPS to a PDF.
I Tried converting my XPS Files via commandline with GhostReader and also tried to use PdfSharp.Xps. Both of these were too slow, Taking more then 30 seconds for a 10 page XPS file. Now my question is if it is possible to set an input and output File/Path for printing when i use Microsoft print to PDF
string fileGuid = Guid.NewGuid().ToString();
string xpsFile = System.IO.Path.Combine(System.IO.Path.GetTempPath(), $"{fileGuid}.Print.xps");
string pdfFile = System.IO.Path.Combine(System.IO.Path.GetTempPath(), $"{fileGuid}.Print.pdf");
PrintDocument doc = new PrintDocument()
{
DocumentName = xpsFile,
PrinterSettings = new PrinterSettings()
{
PrinterName = "Microsoft Print to PDF",
PrintToFile = true,
PrintFileName = pdfFile,
}
};
doc.Print();
This is what i have tried. But this creates an empty .PDF file that i can't use
You can check out the LEADTOOLS SDK (disclaimer: I am an employee of this vendor) which actually supports loading and saving XPS files in C# so you do not need to use a printer to do the conversion, you can simply do it directly in your application: https://www.leadtools.com/sdk/formats#document
So you could use the toolkit to simply load an XPS and save it out as a PDF quite easily with the following code and nuget package:
Install-Package Leadtools.Document.Sdk -Version 21.0.0.2
using (DocumentConverter documentConverter = new DocumentConverter())
{
documentConverter.SetDocumentWriterInstance(new DocumentWriter();
foreach (var filename in inputFiles)
{
var jobData = new DocumentConverterJobData();
jobData.InputDocumentFileName = "input.xps";
jobData.DocumentFormat = DocumentFormat.Pdf;
jobData.OutputDocumentFileName = "output.pdf");
var job = documentConverter.Jobs.CreateJob(jobData);
documentConverter.Jobs.RunJobAsync(job);
}
}
Here is a complete tutorial on how to achieve this here: https://test.leadtools.com/help/sdk/v21/tutorials/documents/cross-platform/dotnet-core/convert-files-with-the-document-converter.html
If you would rather use a printer to do the functionality, there is the Virtual Printer Driver that supports the XPS -> PDF conversion as well:
https://www.leadtools.com/help/sdk/v21/tutorials/virtual-printer/windows/dotnet/print-to-file-using-the-virtual-printer-driver.html

Open PDF in a WPF application at specific bookmark

I have an existing PDF which I want to open at specific bookmarks in a WPF application. Below is the snippet of code I'm using:
Dim myProcess As Process = New Process()
myProcess.StartInfo.FileName = "AcroRd32.exe"
myProcess.StartInfo.Arguments = "/n /A ""pagemode=bookmarks&nameddest=Holidays"" ""c:\Classic\Manual\DocumentationManual.pdf"""
myProcess.Start()
The PDF opens in bookmark mode but not at the specified destination
bookmark (Holidays in the example above).
Can anyone help me resolve this issue?

WPF : render report in PDF format

I am working with WPF rdlc , currently I am using windowformhost reportviewer to show my report . If I need to view in PDF form I will export to PDF through the report viewer by clicking the export button .
Is that anyway to show the report directly in a PDF form instead of doing all the steps above ?
I am using VS2013 as development tools
Thank you
Yes it's possible. You want to first use the ReportViewer to render the report, then stream it to file. Once it's written to file, you can open the pdf from the file system.
Export is something along these lines:
byte[] renderedBytes = rptViewer.LocalReport.Render(
"PDF",
"<DeviceInfo><ExpandContent>True</ExpandContent></DeviceInfo>",
out mimeType,
out encoding,
out fileNameExtension,
out streams,
out warnings);
using (FileStream fsExport = new FileStream(#"C:\MyLocation\MyReport.pdf", FileMode.Create))
{
fsExport.Write(wordbytes, 0, wordbytes.Length);
}
Now you simply open up the pdf file:
System.Diagnostics.Process.Start(#"C:\MyLocation\MyReport.pdf")

Creating XPS in WPF - used image files are being locked until my app quits

In my WPF app, I am creating a FlowDocument by building its XAML markup as a string, and then using XamlReader.Parse to turn the string into a FlowDocument object, which I then save to an XPS document file. It works.
I needed to include an image in my document, and so to achieve this, I create and save the image as a temporary file in the temp directory, and then reference it with an absolute path in my FlowDocument's XAML. This works too - during the XPS document creation process, the image actually gets embedded into the XPS document, which is great.
But the problem is, my app retains a file lock on this image until the app quits.
I am cleaning up all resources. There is NO file lock on my generated XPS file - just the image file. If I comment out the part of my code which creates the XPS file, then the image file does not get locked.
My code (I'm on .NET 4 CP):
var xamlBuilder = new StringBuilder();
// many lines of code like this
xamlBuilder.Append(...);
// create and save image file
// THE IMAGE AT THE PATH imageFilePath IS GETTING LOCKED
// AFTER CREATING THE XPS FILE
var fileName = string.Concat(Guid.NewGuid().ToString(), ".png");
var imageFilePath = string.Format("{0}{1}", Path.GetTempPath(), fileName);
using (var stream = new FileStream(imageFilePath, FileMode.Create)) {
var encoder = new PngBitmapEncoder();
using (var ms = new MemoryStream(myBinaryImageData)) {
encoder.Frames.Add(BitmapFrame.Create(ms));
encoder.Save(stream);
}
stream.Close();
}
// add the image to the document by absolute path
xamlBuilder.AppendFormat("<Paragraph><Image Source=\"{0}\" ...", imageFilePath);
// more lines like this
xamlBuilder.Append(...);
// create a FlowDocument from the built string
var document = (FlowDocument) XamlReader.Parse(xamlBuilder.ToString());
// set document settings
document.PageWidth = ...;
...
// save to XPS file
// THE XPS FILE IS NOT LOCKED. IF I LEAVE OUT THIS CODE
// AND DO NOT CREATE THE XPS FILE, THEN THE IMAGE IS NOT LOCKED AT ALL
using (var xpsDocument = new XpsDocument(filePath, FileAccess.ReadWrite)) {
var documentWriter = XpsDocument.CreateXpsDocumentWriter(xpsDocument);
documentWriter.Write(((IDocumentPaginatorSource) document).DocumentPaginator);
xpsDocument.Close();
}
(Actually, the fact that's it's a dynamically generated image in the temp directory is irrelevant - this issue occurs if I hard code in the path of any image file on my machine - it will get locked.)
One would think that there is a bug in the XPS creation code that causes the file lock.
Is there something else I can try? Or a way to remove the file lock via code?
You could change your xaml like this instead:
<Image>
<Image.Source>
<BitmapImage CacheOption="None" UriSource="your path" />
</Image.Source>
</Image>
to be able to play with the CacheOption parameter, to specify how the Xaml Builder should load the image file, as the default value seems to be keeping a lock on it (waiting for the GC to do its work it seems).
Here is some related question here on SO: How do you make sure WPF releases large BitmapSource from Memory?

Converting byte[] of a PDF file original source to MemoryStream for loading into PDF viewer? (component one)

I'm working with a ComponentOne (C1) silverlight PDF viewer control.
It has a "LoadDocument" method that accepts a "Stream".
I'm making an HTTP get call from my client app to get a PDF document.
This document, on the server side, has been streamed in through File.ReadAllBytes(), then converted to a base64 string using Convert.ToBase64String().
This string is sent across the wire back to my silverlight app where it's then reversely converted back into a byte array with Convert.FromBase64String(val).
Then I'm creating a MemoryStream with that byte array and passing "LoadDocument()" that memory stream.
The viewer is rendering nothing. It shows the toolbar and scrollbars, but the contents are blank and the save button is grayed out, suggesting that no document loaded.
I know for certain the file made it across because the byte array size on the client matches teh byte array pre-conversion on the server side.
Here's my code: (in the interest of time/space, i've truncated, removing validation, etc.)
SERVERSIDE
string sendingToClient = Convert.ToBase64String(File.ReadAllBytes(filePath))
CLIENTSIDE
byte[] image = null;
image = Convert.FromBase64String(stringFromServerCall);
MemoryStream stream = new MemoryStream(image);
docViewer.LoadDocument(stream);
edit As a potential workaround, I attempted to save the file into isolated storage with a ".pdf" extension. Then I use the IsolatedStorageFileStream to send to LoadDocument().
I've come to an actual error, it now says "PdfParserException was unhandled by user code: invalid file format (missing pdf header)"
Can anyone shed some light on this PDF header?
Here is an experiment I would conduct.
Add a button to your Xaml and on click use OpenFileDialog to get a FileInfo. From that FileInfo use its Open method to get a stream and pass that to docViewer.LoadDocument.
Now run it, click the button and select the same PDF document you are trying to send from the server.
If that succeeds you need to continue investigating your server streaming strategy. On the other hand if you still have the same problem, well it doesn't get more raw than that. Try other PDF files and start investigating the PDF component. Have you ever actually used it successfully, if so how does this current usage differ.
you should get the stream pointer back to 0 ,so this should do the trick
byte[] image = null;
image = Convert.FromBase64String(stringFromServerCall);
MemoryStream stream = new MemoryStream(image);
stream.Position = 0;
docViewer.LoadDocument(stream);

Resources