2

I'm trying to load a .xps document into a DocumentViewer object in my WPF application. Everything works fine, except when I try loading a resourced .xps document. I am able to load the .xps document fine when using an absolute path, but when I try loading a resourced document it throws a "DirectoryNotFoundException"

Here's an example of my code that loads the document.

     using System.Windows.Xps.Packaging;

      private void Window_Loaded(object sender, RoutedEventArgs e)
        {
//Absolute Path works (below)
            //var xpsDocument = new XpsDocument(@"C:\Users\..\Visual Studio 2008\Projects\MyProject\MyProject\Docs\MyDocument.xps", FileAccess.Read); 
//Resource Path doesn't work (below)
var xpsDocument = new XpsDocument(@"\MyProject;component/Docs/Mydocument.xps", FileAccess.Read);
            DocumentViewer.Document = xpsDocument.GetFixedDocumentSequence();
        }

When the DirectoryNotFoundException is thrown, it says "Could not find a part of the path : 'C:\MyProject;component\Docs\MyDocument.xps'

It appears that it is trying to grab the .xps document from that path, as if it were an actual path on the computer, and not trying to grab from the .xps that is stored as a resource within the application.

contactmatt
  • 18,116
  • 40
  • 128
  • 186

2 Answers2

1

XpsDocument ctor accepts either a file path or a Package instance. Here's how you can open a Package to use the latter approach:

var uri = new Uri("pack://application:,,,/Docs/Mydocument.xps");
var stream = Application.GetResourceStream(uri).Stream;
Package package = Package.Open(stream);
PackageStore.AddPackage(uri, package);
var xpsDoc = new XpsDocument(package, CompressionOption.Maximum, uri.AbsoluteUri);
var fixedDocumentSequence = xpsDoc.GetFixedDocumentSequence();
_vw.Document = fixedDocumentSequence; // displaying document in viewer
xpsDoc.Close();
repka
  • 2,909
  • 23
  • 26
  • Even after doing what you listed above, it appears that it is still trying to read whatever string I put into the parameter as an actual path. For example, I put in the @"Docs/Mydocument.xps" in the parameter and it threw an error because it was looking at the C:\docs\mydocument.xps path. – contactmatt Jun 06 '10 at 03:05
  • 1
    I edited my post, after realizing that `XpsDocument` ctor accepts file path, not URI. – repka Jun 07 '10 at 14:40
  • I edited it again adding mangling with packages. Ugly, but it works. – repka Jun 07 '10 at 15:07
  • You were a great help. Thank you! – contactmatt Jun 08 '10 at 00:05
  • Note that the call to `PackageStore.AddPackage()` is unnecessary. From the [Microsoft docs](https://learn.microsoft.com/en-us/dotnet/api/system.io.packaging.packagestore): "XPS packages opened with an XpsDocument constructor are automatically added and removed from the PackageStore when the document is created and disposed. (You do not need to call AddPackage or RemovePackage separately for XPS packages opened with XpsDocument constructors.)" – mark.monteiro Aug 25 '21 at 13:21
0

I couldn't get the XPS document to load using a package, and in any case it seems like an unnecessary workaround to wrap the document in a package to be able to load it.

If it is not a hard requirement to set the build action of the XPS document to Resource, then a much simpler solution is possible by setting the build action of the document to Content (and setting "Copy to Output Directory").

var docPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!, "Docs/MyDocument.xps");
using var document = new XpsDocument(termsPath, FileAccess.Read);
_vw.Document = document.GetFixedDocumentSequence();
document.Close()
mark.monteiro
  • 2,609
  • 2
  • 33
  • 38