0

誰かが私を助けてくれることを願っているコードがいくつかあります。私が達成しようとしているのは、埋め込まれた XSLT ファイルを使用して変換を行うことで、Infopaths XML ベースのフォームを Word 2007 ドキュメントに変換することです。

コード:

XPathNavigator nav = MainDataSource.CreateNavigator();
string fieldProject = nav.SelectSingleNode("//my:Project", NamespaceManager).Value;
string fieldQuote = nav.SelectSingleNode("//my:QuoteNumber", NamespaceManager).Value;
string fieldDate = nav.SelectSingleNode("//my:Date", NamespaceManager).Value;


// Define variables for the word template to use and file to create
string wordTemplateFilePath = @"\\2003server\common\OIF Proposals\TemplateFile\Interiors Letter Template.docx";
string wordPrintFilePath = @"\\2003server\common\OIF Proposals\Ben Johnson Ltd Furniture Proposal - " + fieldProject + " - " + fieldQuote + " - " + fieldDate + ".docx";

// Copy the template to create a new docx file
File.Copy(wordTemplateFilePath, wordPrintFilePath, true);

// Crack open the package
Package packWordPrint = Package.Open(wordPrintFilePath, FileMode.Open, FileAccess.ReadWrite);

// Retrieve the document.xml part of the new docx file
PackagePart part = packWordPrint.GetPart(new Uri("/word/document.xml", UriKind.Relative));

// Retrieve the xsl to use to transform the InfoPath form into document.xml
XslCompiledTransform trans = new XslCompiledTransform();
Stream xslTemplate = this.Template.OpenFileFromPackage("transform.xsl");
XmlReader xslTemplateReader = XmlReader.Create(xslTemplate);
trans.Load(xslTemplateReader);

// Create a StreamWriter to be able to write to the stream of the part
using (StreamWriter partStream = new StreamWriter(part.GetStream(FileMode.Open, FileAccess.Write)))
{
    // Transform the InfoPath form and save the XML into the stream for the part
    trans.Transform(this.MainDataSource.CreateNavigator(), null, partStream);

    // Close the stream of the part
    partStream.Close();
}

// Write changes to the package
packWordPrint.Flush();

// Close the package
packWordPrint.Close();

そして、8回に1回、次のエラーが発生します。

System.IO.IOException
The process cannot access the file '\\2003server\common\OIF Proposals\Ben Johnson Ltd Furniture Proposal - ABC123 - 123 - 2010-08-19.docx' because it is being used by another process.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, Boolean useAsync)
   at MS.Internal.IO.Zip.ZipArchive.OpenOnFile(String path, FileMode mode, FileAccess access, FileShare share, Boolean streaming)
   at System.IO.Packaging.ZipPackage..ctor(String path, FileMode mode, FileAccess access, FileShare share, Boolean streaming)
   at System.IO.Packaging.Package.Open(String path, FileMode packageMode, FileAccess packageAccess, FileShare packageShare, Boolean streaming)
   at System.IO.Packaging.Package.Open(String path, FileMode packageMode, FileAccess packageAccess)
   at OIF_Order_Images.FormCode.CTRL31_5_Clicked(Object sender, ClickedEventArgs e)
   at Microsoft.Office.InfoPath.Internal.ButtonEventHost.OnButtonClick(DocActionEvent pEvent)
   at Microsoft.Office.Interop.InfoPath.SemiTrust._ButtonEventSink_SinkHelper.OnClick(DocActionEvent pEvent)

エラーを処理または防止するための賢明な方法が必要です。

どこかでストリームを適切に閉じていないに違いないと思いますか?

コードへのポインタ/変更は大歓迎です。

どうもありがとう

リッチ

4

3 に答える 3

0

Refactoring your code to be a little more efficient and more deterministic on file closures. This should help. note: I re-factored in the SO editor so there could be typos, missing braces etc..

Also, I wasn't sure what else you were using packWordPrint for but does it really need to be opened ReadWrite? It looks like you are just Reading from it so opening it ReadOnly would be smarter and you wouldn't need to call to Flush at the end.

XPathNavigator nav = MainDataSource.CreateNavigator();
string fieldProject = nav.SelectSingleNode("//my:Project", NamespaceManager).Value;
string fieldQuote = nav.SelectSingleNode("//my:QuoteNumber", NamespaceManager).Value;
string fieldDate = nav.SelectSingleNode("//my:Date", NamespaceManager).Value;

// Retrieve the xsl to use to transform the InfoPath form into document.xml
Stream xslTemplate = this.Template.OpenFileFromPackage("transform.xsl");
XmlReader xslTemplateReader = XmlReader.Create(xslTemplate);

XslCompiledTransform trans = new XslCompiledTransform();
trans.Load(xslTemplateReader);

// Define variables for the word template to use and file to create
string wordTemplateFilePath = @"\\2003server\common\OIF Proposals\TemplateFile\Interiors Letter Template.docx";
string wordPrintFilePath = string.Format(@"\\2003server\common\OIF Proposals\Ben Johnson Ltd Furniture Proposal - {0} - {1} - {2}.docx",fieldProject, fieldQuote,fieldDate);

// Copy the template to create a new docx file
File.Copy(wordTemplateFilePath, wordPrintFilePath, true);

// Crack open the package
using (Package packWordPrint = Package.Open(wordPrintFilePath, FileMode.Open, FileAccess.ReadWrite))
{

  // Retrieve the document.xml part of the new docx file
  PackagePart part = packWordPrint.GetPart(new Uri("/word/document.xml", UriKind.Relative));

  // Create a StreamWriter to be able to write to the stream of the part
  using (StreamWriter partStream = new StreamWriter(part.GetStream(FileMode.Open, FileAccess.Write)))
  {
      // Transform the InfoPath form and save the XML into the stream for the part
      trans.Transform(this.MainDataSource.CreateNavigator(), null, partStream);
  }

  // Write changes to the package
  packWordPrint.Flush();

}
于 2010-08-19T17:02:11.200 に答える
0

usingパッケージが閉じていることを確認するために使用するのが最善です。

using (Package packWordPrint = Package.Open(wordPrintFilePath, FileMode.Open, FileAccess.ReadWrite))
{
    ...
}

packWordPrint.Close();と発言を削除。

于 2010-08-19T16:03:24.400 に答える
0

問題は実際にはAVだったと思います。上記のソリューションを使用すると、まだIOExceptionエラーが発生します。どちらも、独自の権利で正しいものとして実装し続けますが、書き込みディレクトリをAVスキャナーの例外リストに入れるとすぐに、エラーが発生しなくなりました.

于 2010-08-20T07:39:02.387 に答える