问题:
下面的程序应该读取 中指定的文件夹中的所有 XML 报告文件(*.rdl 文件),strPat
根据我的代码对其进行修改,并将修改后的 XML 文件保存在文件夹<User>/Desktop/AutoModifiedReports/filename.rdl
中,然后将修改后的 XML 文件复制回 中的文件夹strPat
。
我的问题是我在 CopyBack 过程中获得了未经授权的访问异常。该程序可以写入和覆盖目标目录中的文件。就在它第一次读取、修改然后复制回来时,它会得到一个未经授权的访问异常。
这发生在
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