본문 바로가기

c#

C# 오류 'System.Windows.ResourceDictionary' 형식의 개체를 만들 수 없습니다. 원인 분석

윈도우에서 KB5021233 , KB5020872에 대한 보안 업데이트를 한 뒤로

System.Windows.Markup.XamlParseException: ''System.Windows.ResourceDictionary' 형식의 개체를 만들 수 없습니다. CreateInstance에 실패했으며 이는 'System.Windows.ResourceDictionary'에 대한 공용 기본 생성자가 없기 때문일 수 있습니다.  1 줄 200 위치의 개체 'System.Windows.Documents.FixedPage'에서 오류가 발생했습니다.'

위와 같은 오류가 뜨기 시작 했습니다.

아래는 해당 오류를 분석한 내용입니다. 

 

에러가 나는 로직은 wpf의 flowdocument라는 형식을 xps문서로 변경한뒤 해당 xps문서의 정보값을 가져올 때 발생합니다.

테스트 코드는 아래와 같습니다. 

 public MainWindow()
        {         
           
            Paragraph myParagraph = new Paragraph(new Run("Test"));

            Image img = new Image();

            string uri = "C:\\CIEmrChart\\WORKSPACE\\사진.png";
            BitmapImage bitmap = new BitmapImage();
            bitmap.BeginInit();
            bitmap.UriSource = new Uri(uri,UriKind.Absolute);
            bitmap.EndInit();

            img.Source = bitmap;
          


            FlowDocument flowDocument = new FlowDocument(myParagraph);

            flowDocument.Blocks.Add(new Paragraph(new Run("etsttsetsetsetsetts")));
            flowDocument.Blocks.Add(new BlockUIContainer(img));

            string XpsPathTemp = "C:\\CIEmrChart\\WORKSPACE\\Test.xps";
            string XpsPath = "C:\\CIEmrChart\\WORKSPACE\\Test복사본.xps";

            using (Package container = Package.Open(XpsPathTemp, FileMode.Create))
            {
                //using (XpsDocument xpsDoc = new XpsDocument(container, CompressionOption.SuperFast))     
                using (XpsDocument xpsDoc = new XpsDocument(container, CompressionOption.Normal))
                {
                                        
                    flowDocument.PagePadding = new Thickness(20, 0, 10, 20);

                    DocumentPaginator paginator = ((IDocumentPaginatorSource)flowDocument).DocumentPaginator;

                    XpsDocumentWriter xp = XpsDocument.CreateXpsDocumentWriter(xpsDoc);                  


                    XpsSerializationManager rsm = new XpsSerializationManager(new XpsPackagingPolicy(xpsDoc), false);
                    
                    rsm.SaveAsXaml(paginator);
                    rsm.Commit();
                }
               
            }
            
            using (XpsDocument OriDoc = new System.Windows.Xps.Packaging.XpsDocument(XpsPathTemp, System.IO.FileAccess.Read))
            {
                using (System.Windows.Xps.Packaging.XpsDocument xpsDoc = new System.Windows.Xps.Packaging.XpsDocument(XpsPath, System.IO.FileAccess.ReadWrite))
                {
                	//해당로직 OriDoc.GetFixedDocumentSequence()에서 오류 발생
                    System.Windows.Documents.DocumentPaginator paginator = ((System.Windows.Documents.IDocumentPaginatorSource)OriDoc.GetFixedDocumentSequence()).DocumentPaginator;

                    System.Windows.Xps.Serialization.XpsSerializationManager rsm = new System.Windows.Xps.Serialization.XpsSerializationManager(new System.Windows.Xps.Serialization.XpsPackagingPolicy(xpsDoc), false);
                    rsm.SaveAsXaml(paginator);
                    rsm.Commit();

                    
                }
            }

          

        }

 

현재 문제가 되는 코드는 아래의 GetFixedDocumentSequence()라는 메서드에서 에러가 나는 것을 확인 하였습니다.

(System.Windows.Documents.IDocumentPaginatorSource)OriDoc.GetFixedDocumentSequence()

위의 메서드를 설명하자면

1.먼저 xps문서를 확인하고

2.xps문서 확장자를 zip으로 변경하고 압축을 해제하게되면 아래와 같이 파일들이 생성됩니다.

3.그 중 GetFixedDocumentSequence()는 fdseq파일 안의 uri 값을 가져오게 되는데 현재 저 uri를 가져오지 못하는 상황입니다.

 

그런데 이상하게 어쩔 때는 문제없이 되고 어쩔때는 문제가 생기는 이상한 케이스가 생겨 확인을 해봤습니다.

 

case1. flowdocument객체에 글과 이미지를 넣게 된다면?

// 넣을 텍스트 생성
Paragraph myParagraph = new Paragraph(new Run("Test"));
 //이미지 객체 생성
Image img = new Image();
 //이미지 uri
string uri = "C:\\CIEmrChart\\WORKSPACE\\사진.png";
BitmapImage bitmap = new BitmapImage();
//비트맵 생성
bitmap.BeginInit();
bitmap.UriSource = new Uri(uri,UriKind.Absolute);
bitmap.EndInit();
 //이미지 생성
img.Source = bitmap;
          
 
 // flowdocument에 이미지와 글씨 입력
FlowDocument flowDocument = new FlowDocument(myParagraph);
 
flowDocument.Blocks.Add(new Paragraph(new Run("etsttsetsetsetsetts")));
flowDocument.Blocks.Add(new BlockUIContainer(img));

역시나 위와 같이 에러가 뜨게 됩니다.

 

case2. flowdocument에 이미지는 넣지말고 글만 넣어주게 된다면?

 

결과는 아래와 같이 문제없이 생성이 되고 실행이 되는것을 볼 수 있습니다.

제대로 실행된다.
xps문서도 제대로 생성된다.

작성한 내용도 빠짐없이 잘 작성된 점을 확인 할 수 있었습니다.

 

결론

1.flowdocument에 이미지 객체를 넣게되고 그 이후 xps문서로 변환한뒤 xps문서의 uri값을 가져오려고 하면 안된다.

2. KB5021233 , KB5020872를 삭제하면 문제없이 실행된다