XpsDocument GetFixedDocumentSequence return 特定计算机生成的文件为空

XpsDocument GetFixedDocumentSequence return null for files generated by a specific computer

Solidworks 生成 "EDRWX" 文件。通常,这些是 opened with Microsoft XPS 查看器。

问题:
应用程序使用 .net XPSDocument 打开它们并在打印前对它们进行一些操作。错误方法是"GetFixedDocumentSequence"。对于从特定计算机生成的文件,它 returns 为空。即使应用程序在特定计算机上 运行ning,它也会这样做。但是它可以很好地处理其他计算机生成的文件。

用XPS文档查看器打开文件时,提示打不开。但是,它会在创建它的特定计算机上打开。如果这台电脑从microsoft word打印一个正常的XPS文件,其他电脑可以用XPS文档查看器正常打开它。此外,"EDRWX" 其他计算机生成的文件可以在每台计算机(包括特定计算机)上使用 XPS 文档查看器轻松打开。

更多规格:
windows下的具体电脑运行 8.1.
windows下的其他电脑运行 7.
使用 .net Framework 4.0 的应用程序 运行。

Here 是由特定计算机生成的 "EDRWX" 虚拟文件。
Here 是由其中一台计算机生成的 "EDRWX" 虚拟文件。

问题的原因是什么,如何解决?

旁注:我已经调查了将近 3 天....所以我对这个问题很生气。可能是你的眼睛能看到我看不到的东西,因为我被吸引了这么多。

在我的挖掘中,我发现了这两个文件之间的差异。

失败的 EDRWX 文件不是 XPS 文件,它们是 Open XPS 文件。这两种格式非常相似,但是正如您所发现的,XPSDocument 不支持 OpenXPS。我不知道有任何直接支持 Open XPS 的 .net API,但是 Microsoft 确实发布了您可以利用的 standalone converter tools

另一种可能有效也可能无效的替代方法是尝试强制 SolidWorks 在故障机器上生成 xps 而不是 oxps。 solidworks 可能正在使用 xps 文档编写器生成这些文件,在这种情况下,按照 here 所述更改输出格式可能会解决问题。

正如 Jon 所指出的,问题在于从 windows8 开始,solidworks 无论如何都使用 OXPS 格式。在组策略中更改默认格式适用于其他应用程序,但 Solidworks 不关心。因此,我最终使用了迄今为止 Microsoft 提供的唯一工具来处理这种情况。这是 windows update package 附带的转换器应用程序。安装后,可以在此处找到转换应用程序: C:\Program Files (x86)\Windows Kits.0\bin

有一个 x86 版本和一个 x64 版本。

这是控制台中的一个用法示例。

因此在我的应用程序旁边添加了转换器应用程序,并在我的应用程序中静默启动转换器。这是一个展示我是如何做到的方法。如有必要,该方法将给定文件转换为 XPS 格式。但转换后的文件必须是另一个文件,因为该工具无法覆盖它正在转换的文件。

private string EnsureFileIsUnderXPSFormat(string fileName)
{
    string retValue = fileName;
    string convertedFileName = System.IO.Path.GetDirectoryName(fileName).TrimEnd(System.IO.Path.DirectorySeparatorChar) + System.IO.Path.DirectorySeparatorChar + System.IO.Path.GetFileNameWithoutExtension(fileName) + "_converted" + System.IO.Path.GetExtension(fileName);
    Version win8version = new Version(6, 2, 9200, 0);
    if (Environment.OSVersion.Platform == PlatformID.Win32NT && Environment.OSVersion.Version >= win8version || true)
    {
        System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
        startInfo.Arguments = "/XPS /InputFile=" + fileName + " /OutputFile=" + convertedFileName;
        string applicationFolderPath = AppDomain.CurrentDomain.BaseDirectory.TrimEnd(System.IO.Path.DirectorySeparatorChar) + System.IO.Path.DirectorySeparatorChar;
        startInfo.FileName = applicationFolderPath + "xpsconverter.exe";
        //if (Environment.Is64BitOperatingSystem)
        //  startInfo.FileName = @"C:\Users\maxiveil\Desktop\testConversion\xpsconverter.exe";
        //else
        //  startInfo.FileName = @"C:\Users\maxiveil\Desktop\testConversion\xpsconverter.exe";
        startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
        startInfo.CreateNoWindow = true;
        using (System.Diagnostics.Process processus = System.Diagnostics.Process.Start(startInfo))
        {
            processus.WaitForExit();
            if (processus.ExitCode != 0)
            {
                throw new Exception("Failed to convert OXPS file(" + fileName + ") to XPS format. Error code : " + processus.ExitCode.ToString());
            }
        }
        retValue = convertedFileName;
    }
    return retValue;
}

N.B:转换器应用程序不关心您是否尝试将 XPS 格式文件转换为 XPS 格式文件。所以 "windows8 if" 是可选的。