2013-11-21 6 views
1

질문 :내가 읽은 XML 파일을 덮어 쓸 수없는 이유는 무엇입니까 (모든 스트림을 닫은 것 같습니다).

아래의 프로그램을 복사 한 후, strPat에 지정된 폴더에있는 모든 XML 보고서 파일 (* .rdl 파일)를 읽고 수정할 내 코드에 따라, 그리고 폴더 <User>/Desktop/AutoModifiedReports/filename.rdl에서 수정 된 XML 파일을 저장한다 수정 된 XML 파일을 strPat의 폴더로 다시 가져옵니다.

내 문제는 카피 백 절차에서 승인되지 않은 액세스 예외가 발생한다는 것입니다. 프로그램은 대상 디렉토리에 파일을 쓰고 덮어 쓸 수 있습니다. 처음에 읽고 수정 한 다음 다시 복사하면 무단 액세스 예외가 발생합니다.

public static void CopyBack(string strFileName) 
     { 
      string strSavePath = GetSavePath(); 
      strSavePath = System.IO.Path.Combine(strSavePath, System.IO.Path.GetFileName(strFileName)); 

      if (System.IO.File.Exists(strSavePath)) 
      { 
       System.IO.File.Copy(strSavePath, strFileName, true); // Exception - Unauthorized access 
      } 

     } // End Sub CopyBack 

에서 나는 열린 스트림을 떠나 어떤 장소 잠긴 파일이 표시되지 않는 발생합니다.
누구나 내가 잘못하고 있다는 것을 정확히 말해 줄 수 있습니까? 어떻게 해결할 수 있습니까?

using System; 
using System.Collections.Generic; 
using System.Windows.Forms; 


namespace ReportModifier 
{ 


    static class MalfunctioningProgram 
    { 

     public static string strLogPath = GetLogFilePath(); 


     public static string GetSavePath() 
     { 
      string strSavePath = System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop); 
      strSavePath = System.IO.Path.Combine(strSavePath, "AutoModifiedReports"); 


      if (!System.IO.Directory.Exists(strSavePath)) 
       System.IO.Directory.CreateDirectory(strSavePath); 

      return strSavePath; 
     } // End Function GetSavePath 


     public static string GetLogFilePath() 
     { 
      string strLogfileLocation = System.IO.Path.Combine(GetSavePath(), "log.txt"); 

      if (System.IO.File.Exists(strLogfileLocation)) 
       System.IO.File.Delete(strLogfileLocation); 

      return strLogfileLocation; 
     } // End Function GetLogFilePath 


     public static void LogMessage(string strMessage) 
     { 
      // Console.WriteLine(strMessage); 
      System.IO.File.AppendAllText(strLogPath, strMessage + Environment.NewLine, System.Text.Encoding.UTF8); 
     } // End Sub LogMessage 


     public static void LogMessage(string str, params object[] args) 
     { 
      LogMessage(string.Format(str, args)); 
     } // End Sub LogMessage 



     public static System.Xml.XmlDocument File2XmlDocument(string strFileName) 
     { 
      // http://blogs.msdn.com/b/tolong/archive/2007/11/15/read-write-xml-in-memory-stream.aspx 
      System.Xml.XmlDocument doc = new System.Xml.XmlDocument(); 
      // doc.Load(memorystream); 
      // doc.Load(FILE_NAME); 

      using (System.Xml.XmlTextReader xtrReader = new System.Xml.XmlTextReader(strFileName)) 
      { 
       doc.Load(xtrReader); 
       xtrReader.Close(); 
      } // End Using xtrReader 

      return doc; 
     } // End Function File2XmlDocument 


     public static System.Xml.XmlNamespaceManager GetReportNamespaceManager(System.Xml.XmlDocument doc) 
     { 
      System.Xml.XmlNamespaceManager nsmgr = new System.Xml.XmlNamespaceManager(doc.NameTable); 
      nsmgr.AddNamespace("dft", "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition"); 

      return nsmgr; 
     } // End Function GetReportNamespaceManager 


     public static void SaveDocument(System.Xml.XmlDocument doc, string strFilename) 
     { 
      SaveDocument(doc, strFilename, false); 
     } // End Sub SaveDocument 


     public static void SaveDocument(System.Xml.XmlDocument doc, string strFilename, bool bDoReplace) 
     { 
      string strSavePath = GetSavePath(); 
      strSavePath = System.IO.Path.Combine(strSavePath, System.IO.Path.GetFileName(strFilename)); 

      if (bDoReplace) 
      { 
       doc.LoadXml(doc.OuterXml.Replace("xmlns=\"\"", "")); 
      } 

      using (System.Xml.XmlTextWriter xtw = new System.Xml.XmlTextWriter(strSavePath, System.Text.Encoding.UTF8)) 
      { 
       xtw.Formatting = System.Xml.Formatting.Indented; // if you want it indented 
       xtw.Indentation = 4; 
       xtw.IndentChar = ' '; 

       doc.Save(xtw); 
       xtw.Flush(); 
       xtw.Close(); 
      } // End Using xtw 

      doc = null; 
     } // End Sub SaveDocument 


     public static void ChangeParameterPrompt(string strFilename, string strReportParameterName, string strReplacementText) 
     { 
      System.Xml.XmlDocument doc = File2XmlDocument(strFilename); 
      System.Xml.XmlNamespaceManager nsmgr = GetReportNamespaceManager(doc); 

      if (!HasParameter(doc, strReportParameterName)) 
       return; 


      System.Xml.XmlNode xnParameterPrompt = GetParameterPrompt(doc, strReportParameterName); 
      string strReportName = System.IO.Path.GetFileNameWithoutExtension(strFilename); 

      if (xnParameterPrompt != null) 
      { 
       string strParameterValue = xnParameterPrompt.FirstChild.Value; 
       xnParameterPrompt.FirstChild.Value = strReplacementText; 
       LogMessage("Old value in {0}:\t{1}", strReportName, strParameterValue); 
      } 
      else 
       LogMessage("{0}\tKein Parameter " + strReportParameterName, strReportName); 

      SaveDocument(doc, strFilename); 
     } // End Sub ChangeParameterPrompt 


     public static void ChangeStichtag(string strFilename) 
     { 
      System.Xml.XmlDocument doc = File2XmlDocument(strFilename); 
      System.Xml.XmlNamespaceManager nsmgr = GetReportNamespaceManager(doc); 

      System.Xml.XmlNode xnStichtag = doc.SelectSingleNode("somequery", nsmgr); 
      string strReportName = System.IO.Path.GetFileNameWithoutExtension(strFilename); 

      if (!HasParameter(doc, "in_stichtag")) 
       return; 


      if (xnStichtag != null) 
      { 
       xnStichtag.FirstChild.Value = "=System.DateTime.Now.ToString(\"dd.MM.yyyy\")"; 
       string strStichTag = xnStichtag.FirstChild.Value; 
       LogMessage("{0}\t{1}", strReportName, strStichTag); 
      } 
      else 
       LogMessage("{0}\tKein Parameter Stichtag", strReportName); 

      SaveDocument(doc, strFilename); 
     } // End Sub ChangeStichtag 



     public static string XmlEscape(string unescaped) 
     { 
      string strReturnValue = null; 

      System.Xml.XmlDocument doc = new System.Xml.XmlDocument(); 
      System.Xml.XmlNode node = doc.CreateElement("root"); 
      node.InnerText = unescaped; 
      strReturnValue = node.InnerXml; 
      node = null; 
      doc = null; 

      return strReturnValue; 
     } // End Function XmlEscape 


     public static string XmlUnescape(string escaped) 
     { 
      string strReturnValue = null; 

      System.Xml.XmlDocument doc = new System.Xml.XmlDocument(); 
      System.Xml.XmlNode node = doc.CreateElement("root"); 
      node.InnerXml = escaped; 
      strReturnValue = node.InnerText; 
      node = null; 
      doc = null; 

      return strReturnValue; 
     } // End Function XmlUnescape 





     public static bool HasParameter(System.Xml.XmlDocument doc, string strParameterName) 
     { 
      strParameterName = XmlEscape(strParameterName); 

      System.Xml.XmlNamespaceManager nsmgr = GetReportNamespaceManager(doc); 
      System.Xml.XmlNode xnProc = doc.SelectSingleNode("somequery", nsmgr); 

      return xnProc != null; 
     } // End Function HasParameter 




     public static System.Xml.XmlNode GetParameter(System.Xml.XmlDocument doc, string strParameterName) 
     { 
      strParameterName = XmlEscape(strParameterName); 

      System.Xml.XmlNamespaceManager nsmgr = GetReportNamespaceManager(doc); 
      System.Xml.XmlNode xnParam = doc.SelectSingleNode("somequery", nsmgr); 

      return xnParam; 
     } // End Function GetParameter 


     public static System.Xml.XmlNode GetParameterPrompt(System.Xml.XmlDocument doc, string strParameterName) 
     { 
      strParameterName = XmlEscape(strParameterName); 

      System.Xml.XmlNamespaceManager nsmgr = GetReportNamespaceManager(doc); 
      System.Xml.XmlNode xnParam = doc.SelectSingleNode("somequery", nsmgr); 

      return xnParam; 
     } // End Function GetParameter 


     public static void AddProc(string strFilename) 
     { 
      System.Xml.XmlDocument doc = File2XmlDocument(strFilename); 

      System.Xml.XmlNamespaceManager nsmgr = GetReportNamespaceManager(doc); 

      if (HasParameter(doc, "proc")) 
       return; 

      System.Xml.XmlNode xnMandant = GetParameter(doc, "in_mandant"); 

      string strReportName = System.IO.Path.GetFileNameWithoutExtension(strFilename); 

      if (xnMandant != null) 
      { 
       LogMessage("{0}\t{1}", strReportName, xnMandant.FirstChild.Value); 

       string frag = @"some xml fragment"; 

       System.Xml.XmlDocumentFragment xmlDocFrag = doc.CreateDocumentFragment(); 
       xmlDocFrag.InnerXml = frag; 

       // System.Xml.XmlNode xn = 
       xnMandant.ParentNode.InsertAfter(xmlDocFrag, xnMandant); 
      } 
      else 
       LogMessage("{0}\tKein Parameter in_mandant", strReportName); 

      SaveDocument(doc, strFilename, true); 
      //SaveDocument(doc, strFilename, "<ReportParameter Name=\"proc\" xmlns=\"\">", "<ReportParameter Name=\"proc\">"); 
     } // End Sub AddProc 


     public static List<string> GetAllReports(string strPath) 
     { 
      List<string> ls = new List<string>(); 
      ls.AddRange(System.IO.Directory.GetFiles(strPath, "*.rdl")); 

      return ls; 
     } // End Function GetAllReports 


     public static void CopyToSaveDirectory(string strFileName) 
     { 
      string strSavePath = GetSavePath(); 
      strSavePath = System.IO.Path.Combine(strSavePath, System.IO.Path.GetFileName(strFileName)); 

      System.IO.File.Copy(strFileName, strSavePath, true); 
     } // End Sub CopyToSaveDirectory 


     public static void CopyBack(string strFileName) 
     { 
      string strSavePath = GetSavePath(); 
      strSavePath = System.IO.Path.Combine(strSavePath, System.IO.Path.GetFileName(strFileName)); 

      if (System.IO.File.Exists(strSavePath)) 
      { 
       System.IO.File.Copy(strSavePath, strFileName, true); // Exception - Unauthorized access 
      } 

     } // End Sub CopyBack 


     public static void AlterReports(string strPath) 
     { 
      List<string> lsReports = GetAllReports(strPath); 

      foreach (string strFileName in lsReports) 
      { 
       ChangeStichtag(strFileName); 
       CopyBack(strFileName); 
       ChangeParameterPrompt(strFileName, "in_standort", "Liegenschaft/Immeuble/Patrimonio immobiliare/Estate"); 
       CopyBack(strFileName); 
       ChangeParameterPrompt(strFileName, "in_gebaeude", "Gebäude/Bâtiment/Edificio/Building"); 
       CopyBack(strFileName); 
       ChangeParameterPrompt(strFileName, "in_geschoss", "Geschoss/Étage/Piano/Floor"); 
       CopyBack(strFileName); 
       ChangeParameterPrompt(strFileName, "in_trakt", "Trakt/Aile/Ala/Wing"); 
       CopyBack(strFileName); 
       ChangeParameterPrompt(strFileName, "in_haus", "Haus/Maison/Casa/House"); 
       CopyBack(strFileName); 
       ChangeParameterPrompt(strFileName, "in_raum", "Raum/Pièce/Stanza/Room"); 
       CopyBack(strFileName); 
       ChangeParameterPrompt(strFileName, "in_stichtag", "Stichtag/Jour de référence/Giorno di riferimento/Reporting date"); 
       CopyBack(strFileName); 
       ChangeParameterPrompt(strFileName, "in_mietertrag", "Mindestertrag Mindestertrag/Rendement minimum/Rendimento minimo/Minimum yield"); 
       CopyBack(strFileName); 
      } // Next strFileName 

     } // End Sub InvestigateStichtag 


     /// <summary> 
     /// Der Haupteinstiegspunkt für die Anwendung. 
     /// </summary> 
     [STAThread] 
     static void Main() 
     { 
      string strPath = @"S:\SomeBody\SomeFolder\Reports"; 

      AlterReports(strPath); 

      Console.WriteLine(Environment.NewLine); 
      Console.WriteLine(" --- Press any key to continue --- "); 
      Console.ReadKey(); 
     } // End Sub Main 


    } // End Class Program 


} // End Namespace ReportModifier 
+4

관련성없는 코드를 삭제하십시오. 관련 코드 만 게시하십시오. –

+0

@Sriram Sakthivel : 이미 해 봤습니다. 어떤 관련없는 비트가 보이나요? –

+0

CopyBack을 연속 9 회 호출하면 각 보고서 뷰어 파일에 대해이 오류가 발생할 때를 지정할 수 있습니까? – JMK

답변

0

.
문제는 파일이 SSRS 보고서였습니다.
보고서 솔루션 폴더 (소스 제어 아래)에서 실험용으로 다른 폴더로 복사했습니다.
그러나 파일의 WriteProtected 플래그가 파일과 함께 복사됩니다.
비주얼 스튜디오에서 편집하고 저장했는지, 내가 쓸 수있는 권한이 있는지 확인하십시오.
문제가 해결 된 쓰기 보호가 제거되었습니다.

그래서 당신은 할 필요가 :

if(FileIsWriteProtected) 
    Unprotect(file); 

System.IO.File.Copy(Source, file.FullPath, true); 

을 Incidentially, 내가 UnauthorizedAccessException있어 그 이유도 설명합니다.

1

이 코드를 보면 :

public static void CopyBack(string strFileName) 
{ 
    string strSavePath = GetSavePath(); 
    strSavePath = System.IO.Path.Combine(strSavePath, System.IO.Path.GetFileName(strFileName)); 

    if (System.IO.File.Exists(strSavePath)) 
    { 
     System.IO.File.Copy(strSavePath, strFileName, true); // Exception - Unauthorized access 
    } 
} 

당신이 GetSavePath()에 의해 지정된 폴더에 strFileName에서 파일을 복사하려는 것으로 보인다.

실제로 이러한 경우라면 File.Copy()에 대한 매개 변수가 잘못된 방법임을 알고 있어야합니다.

그것은 당신의 코드가 있어야한다이 경우에 Copy(String sourceFileName, string destFileName, bool overwrite)

그럼 : 신경 쓰지

System.IO.File.Copy(strFileName, strSavePath, true); 
+0

아니요. 저장 경로는 실제로 소스 경로입니다. 먼저 strFilename에서 XML을로드하고 수정 한 다음 strSavePath에 저장하기 때문입니다. 그런 다음 카피 백에서는 해당 이름을 유지합니다. 즉, 변수 내용이 예상 한 것과 다릅니다. (변수 이름을 수정하지 않고 CopyToSaveDirectory를 복사하여 사본 만들기). 하지만 좋은 점은 모두 로컬 변수이므로 이름을 조정할 것입니다. 그러나 이것은 오류와 아무 관련이 없습니다. –