Generate One XML(LogData.xml) file from Two different Application Without Threading - c#

I want to write XML Log File from two or more Application into LogData.xml file. while running the one application it creats the LogData.xml file correctly but at the same time both the allpication are run simulteniously and try to write the LogData.xml file it gives me an error message such as The process cannot access the file Log_Data.xml' because it is being used by another process.
I use this code
public void WriteXmlLog(string logType, string logFlag, string logModule, string logLocation, string logText, string logStackTrace)
{
if (!File.Exists(_logFilePath))
{
//File.WriteAllText(_logFilePath, "<?xml version='1.0' encoding='utf-8' standalone='yes'?>\r\n<AppXmlLogWritter></AppXmlLogWritter>");
XmlTextWriter textWritter = new XmlTextWriter(_logFilePath, null);
textWritter.WriteStartDocument();
textWritter.WriteStartElement("AppXmlLogWritter");
textWritter.WriteEndElement();
textWritter.Close();
}
XmlDocument xmlDoc = new XmlDocument();
using (FileStream fileStream = new FileStream(_logFilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
{
string currentDateTime = DateTime.Now.ToString("yyyyMMddHHmmss");
xmlDoc.Load(fileStream);
XmlElement newelement = xmlDoc.CreateElement("LogData");
XmlElement xmlLogID = xmlDoc.CreateElement("LogID");
XmlElement xmlLogDateTime = xmlDoc.CreateElement("LogDateTime");
XmlElement xmlLogType = xmlDoc.CreateElement("LogType");
XmlElement xmlLogFlag = xmlDoc.CreateElement("LogFlag");
XmlElement xmlLogApplication = xmlDoc.CreateElement("LogApplication");
XmlElement xmlLogModule = xmlDoc.CreateElement("LogModule");
XmlElement xmlLogLocation = xmlDoc.CreateElement("LogLocation");
XmlElement xmlLogText = xmlDoc.CreateElement("LogText");
XmlElement xmlLogStackTrace = xmlDoc.CreateElement("LogStackTrace");
xmlLogID.InnerText = _logIDPrefix + currentDateTime + randomNumber;
xmlLogDateTime.InnerText = currentDateTime;
xmlLogType.InnerText = ((LogTypes)Convert.ToInt32(logType)).ToString();
xmlLogFlag.InnerText = logFlag;
xmlLogApplication.InnerText = _logApplication;
xmlLogModule.InnerText = logModule;
xmlLogLocation.InnerText = logLocation;
xmlLogText.InnerText = logText;
xmlLogStackTrace.InnerText = logStackTrace;
newelement.AppendChild(xmlLogID);
newelement.AppendChild(xmlLogDateTime);
newelement.AppendChild(xmlLogType);
newelement.AppendChild(xmlLogFlag);
newelement.AppendChild(xmlLogApplication);
newelement.AppendChild(xmlLogModule);
newelement.AppendChild(xmlLogLocation);
newelement.AppendChild(xmlLogText);
xmlDoc.DocumentElement.AppendChild(newelement);
//}
//finally
//{
// objMutex.ReleaseMutex();
//}
}
xmlDoc.Save(_logFilePath);
}
I want to achive this without Threading

Perhaps try implementing logging with NLog in both applications and set as the target the same xml.

Related

Cannot change XmlDocument value?

I have a simple function which will simply change and read the value.
void ParseXml(string XmlFile)
{
string totalval = "";
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(new StringReader(XmlFile));
string xmlPathPattern = "//name";
XmlNodeList mynodelist = xmldoc.SelectNodes(xmlPathPattern);
foreach (XmlNode node in mynodelist)
{
XmlNode name = node.FirstChild;
name.Value = "asd";//here I am trying to change value
totalval = totalval + "Name=" + name.OuterXml + "\n";
}
xmldoc.Save(XmlFile);
print(totalval);
}
This is my .xml file.
<name>John</name>
I can successfully read the value but it is not changing the value from .xml file.After running the program it must be like this
<name>asd</name> .
Where is my mistake ?
Obviously, the XMLFile is not a file path, it is xml string. So, you should define a valid path to save it.
xmldoc.Save("samplefile.xml");
or if you want to set the XmlFile variable with modified xml;
XmlFile = xmldoc.OuterXml;
Complete codes look like;
void ParseXml(string XmlFile)
{
string totalval = "";
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(new StringReader(XmlFile));
string xmlPathPattern = "//name";
XmlNodeList mynodelist = xmldoc.SelectNodes(xmlPathPattern);
foreach (XmlNode node in mynodelist)
{
XmlNode name = node.FirstChild;
name.Value = "asd";//here I am trying to change value
totalval = totalval + "Name=" + name.OuterXml + "\n";
}
//XmlFile = xmldoc.OuterXml;
xmldoc.Save("samplefile.xml");
print(totalval);
}
If I'm not wrong - you need to fire disposable to save stream. Easiest way - wrap with using
void ParseXml(string XmlFile)
{
string totalval = "";
using(XmlDocument xmldoc = new XmlDocument())
{
xmldoc.Load(new StringReader(XmlFile));
string xmlPathPattern = "//name";
XmlNodeList mynodelist = xmldoc.SelectNodes(xmlPathPattern);
foreach (XmlNode node in mynodelist)
{
XmlNode name = node.FirstChild;
name.Value = "asd";//here I am trying to change value
totalval = totalval + "Name=" + name.OuterXml + "\n";
}
xmldoc.Save(XmlFile);
print(totalval);
}
}

XML file is overwritten in each run

I am trying to write some data into XML file.
Actually, I can do that, but in each run, the XML file is overwritten while I want it to add another row.
This is what I have done so far:
public static void StoreCustomerIntoXML(string Id)
{
string pth = System.Reflection.Assembly.GetCallingAssembly().CodeBase;
string actualPath = pth.Substring(0, pth.LastIndexOf("bin"));
string projectPath = new Uri(actualPath).LocalPath;
string reportPath = projectPath + "Customers\\CustomersListCreated.xml";
XmlDocument xmlDoc = new XmlDocument();
XmlNode rootNode = xmlDoc.CreateElement("Customers");
xmlDoc.AppendChild(rootNode);
XmlNode userNode = xmlDoc.CreateElement("Id");
userNode.InnerText = Id;
rootNode.AppendChild(userNode);
xmlDoc.Save(reportPath);
}
So calling the method for the first time will include Id = 1234
and the second run will include Id = 6543
The XML file will always include the Id of last run and only this Id.
Try this
public static void StoreCustomerIntoXML(string Id)
{
string pth = System.Reflection.Assembly.GetCallingAssembly().CodeBase;
string actualPath = pth.Substring(0, pth.LastIndexOf("bin"));
string projectPath = new Uri(actualPath).LocalPath;
string reportPath = projectPath + "CustomersListCreated.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(reportPath))
{
xmlDoc.Load(reportPath);
XmlNode rootNode = xmlDoc.DocumentElement;
xmlDoc.AppendChild(rootNode);
XmlElement elem = xmlDoc.CreateElement("Id");
elem.InnerText = Id;
rootNode.AppendChild(elem);
}
else
{
XmlNode rootNode = xmlDoc.CreateElement("Customers");
xmlDoc.AppendChild(rootNode);
XmlNode userNode = xmlDoc.CreateElement("Id");
userNode.InnerText = Id;
rootNode.AppendChild(userNode);
}
xmlDoc.Save(reportPath);
}
You could check if the file exists and load it using the method Load, instead of creating a new one every time you call your method.
public static void StoreCustomerIntoXML(string Id)
{
string pth = System.Reflection.Assembly.GetCallingAssembly().CodeBase;
string actualPath = pth.Substring(0, pth.LastIndexOf("bin"));
string projectPath = new Uri(actualPath).LocalPath;
string reportPath = projectPath + "Customers\\CustomersListCreated.xml";
XmlDocument xmlDoc;
if (File.Exists(reportPath))
xmlDoc = XDocument.Load(reportPath);
else
xmlDoc = new XmlDocument();
XmlNode rootNode = xmlDoc.CreateElement("Customers");
xmlDoc.AppendChild(rootNode);
XmlNode userNode = xmlDoc.CreateElement("Id");
userNode.InnerText = Id;
rootNode.AppendChild(userNode);
xmlDoc.Save(reportPath);
}
public static void StoreCustomerIntoXML(string Id)
{
string pth = System.Reflection.Assembly.GetCallingAssembly().CodeBase;
string actualPath = pth.Substring(0, pth.LastIndexOf("bin"));
string projectPath = new Uri(actualPath).LocalPath;
string reportPath = projectPath + "Customers\\CustomersListCreated.xml";
XmlDocument xmlDoc = new XmlDocument();
XmlNode rootNode;
if (File.Exists(reportPath))
{
xmlDoc.Load(reportPath);
rootNode = xmlDoc.DocumentElement;
}
else
{
rootNode = xmlDoc.CreateElement("Customers");
xmlDoc.AppendChild(rootNode);
}
XmlNode userNode = xmlDoc.CreateElement("Id");
userNode.InnerText = Id;
rootNode.AppendChild(userNode);
xmlDoc.Save(reportPath);
}

Encode & Decode string in WPF C#

I am trying to encode & decode strings that are saved to an .ini settings file for a WPF app.
encoding & decoding class
class EncryptDecrypt
{
public static string Base64Encode(string plainText)
{
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
return System.Convert.ToBase64String(plainTextBytes);
}
public static string Base64Decode(string base64EncodedData)
{
var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
}
}
The encoding seems to be saved to the .ini file correctly, but decoding the entry from the .ini file seems to output incorrect string as per below;
encoding from password field works fine (on save_click)
inif.Write("APISettings", "HashKey", EncryptDecrypt.Base64Encode(hash_key.Password.ToString()));
but, reload app then navigating to same field/form the decode is not outputting entry correctly (as it is used to check http status of page)..
hash_key.Password = EncryptDecrypt.Base64Decode(inif.Read("APISettings", "HashKey"));
I can see that is outputting the string as weird wingdings characters.
UPDATE
Resolved by instead of saving to .ini file I saved to xml document, see below;
private void Save_Click(object sender, RoutedEventArgs e)
{
//Settings Data
string appfolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string ApplicationPath = System.IO.Path.Combine(appfolder, "MyApp/Application");
if (!Directory.Exists(ApplicationPath)) Directory.CreateDirectory(ApplicationPath);
//Encryption
if (!System.IO.File.Exists(ApplicationPath + #"\credentials.xml"))
{
XmlDocument doc = new XmlDocument();
//(1) the xml declaration is recommended, but not mandatory
XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
XmlElement root = doc.DocumentElement;
doc.InsertBefore(xmlDeclaration, root);
//(2) string.Empty makes cleaner code
XmlElement elementNode = doc.CreateElement(string.Empty, "Credentials", string.Empty);
doc.AppendChild(elementNode);
//Base URL
XmlElement elementNodeBaseUrl = doc.CreateElement(string.Empty, "BaseUrl", string.Empty);
elementNode.AppendChild(elementNodeBaseUrl);
elementNodeBaseUrl.InnerText = base_url.Text.ToString();
XmlElement elementNodeAdminPath = doc.CreateElement(string.Empty, "AdminPath", string.Empty);
elementNode.AppendChild(elementNodeAdminPath);
elementNodeAdminPath.InnerText = EncryptDecrypt.Base64Encode(admin_path.Password.ToString());
XmlElement elementNodeAdminName = doc.CreateElement(string.Empty, "AdminName", string.Empty);
elementNode.AppendChild(elementNodeAdminName);
elementNodeAdminName.InnerText = EncryptDecrypt.Base64Encode(admin_name.Password.ToString());
XmlElement elementNodeAdminPassword = doc.CreateElement(string.Empty, "AdminPassword", string.Empty);
elementNode.AppendChild(elementNodeAdminPassword);
elementNodeAdminPassword.InnerText = EncryptDecrypt.Base64Encode(admin_password.Password.ToString());
XmlElement elementNodeHashKey = doc.CreateElement(string.Empty, "HashKey", string.Empty);
elementNode.AppendChild(elementNodeHashKey);
elementNodeHashKey.InnerText = EncryptDecrypt.Base64Encode(hash_key.Password.ToString());
XmlElement elementNodeUpdated = doc.CreateElement(string.Empty, "Updated", string.Empty);
elementNode.AppendChild(elementNodeUpdated);
elementNodeUpdated.InnerText = DateTime.Now.ToString();
doc.Save(ApplicationPath + #"\credentials.xml");
}else{
XmlDocument doc = new XmlDocument();
//(1) the xml declaration is recommended, but not mandatory
XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
XmlElement root = doc.DocumentElement;
doc.InsertBefore(xmlDeclaration, root);
//(2) string.Empty makes cleaner code
XmlElement elementNode = doc.CreateElement(string.Empty, "Credentials", string.Empty);
doc.AppendChild(elementNode);
//Base URL
XmlElement elementNodeBaseUrl = doc.CreateElement(string.Empty, "BaseUrl", string.Empty);
elementNode.AppendChild(elementNodeBaseUrl);
elementNodeBaseUrl.InnerText = base_url.Text.ToString();
XmlElement elementNodeAdminPath = doc.CreateElement(string.Empty, "AdminPath", string.Empty);
elementNode.AppendChild(elementNodeAdminPath);
elementNodeAdminPath.InnerText = EncryptDecrypt.Base64Encode(admin_path.Password.ToString());
XmlElement elementNodeAdminName = doc.CreateElement(string.Empty, "AdminName", string.Empty);
elementNode.AppendChild(elementNodeAdminName);
elementNodeAdminName.InnerText = EncryptDecrypt.Base64Encode(admin_name.Password.ToString());
XmlElement elementNodeAdminPassword = doc.CreateElement(string.Empty, "AdminPassword", string.Empty);
elementNode.AppendChild(elementNodeAdminPassword);
elementNodeAdminPassword.InnerText = EncryptDecrypt.Base64Encode(admin_password.Password.ToString());
XmlElement elementNodeHashKey = doc.CreateElement(string.Empty, "HashKey", string.Empty);
elementNode.AppendChild(elementNodeHashKey);
elementNodeHashKey.InnerText = EncryptDecrypt.Base64Encode(hash_key.Password.ToString());
XmlElement elementNodeUpdated = doc.CreateElement(string.Empty, "Updated", string.Empty);
elementNode.AppendChild(elementNodeUpdated);
elementNodeUpdated.InnerText = DateTime.Now.ToString();
doc.Save(ApplicationPath + #"\credentials.xml");
}
Thread.Sleep(1000);
SaveButton.Visibility = Visibility.Hidden;
onclick_progress.Visibility = Visibility.Visible;
showProgress();
}

Convert XML to string

I am currently working on a project where I have send values ("PFOID" and "Quantity") to a stored procedure in a XML format.
the required XML format is something like this
<string>
<PFOID>04676723-2afb-49ff-9fa1-0131cabb407c</PFOID>
<Quantity>90</Quantity>
</string>
My code looks like this.
internal void UpdateQuantity(PFO pfo)
{
string pfoIds = "<PFO>" + "<PFOID>" + pfo.PFOId.ToString() + "</PFOID>" + " " + "<Quantity>" + pfo.PlannedQty.ToString() + "</Quantity>" + "</PFO>";
//pfoIds = pfoIds.Replace("<","<").Replace(">",">");
// string pfoIds = pfo.PFOId.ToString() + pfo.PlannedQty.ToString();
//XDocument d = new XDocument(pfoIds,
// new XElement
// ("PFO",
// new XElement("PFOID", pfo.PFOId.ToString()),
// new XElement("Quantity", pfo.PlannedQty.ToString())
// )
// );
List<string> pfoIdList = new List<string>();
pfoIdList.Add(pfoIds);
XmlSerializer serializer = new XmlSerializer(pfoIdList.GetType());
StringBuilder xmlString = new StringBuilder();
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
settings.Encoding = new UTF8Encoding();
XmlWriter writer = XmlWriter.Create(new StringWriter(xmlString), settings);
//XDocument xDoc = XDocument.Load(pfoIds);
//XmlNode xNode = xmlDoc.SelectSingleNode("PFOID", "Quantity");
//string onlyvalue = xNode.InnerText;
//System.Xml.Linq.XDocument xDoc = new XDocument();
////System.Xml.Linq.XNode xNode =new System.Xml.Linq.XDocument();
//XmlDocument xmlDoc = new XmlDocument();
//xmlDoc.Load(pfoIds);
//XmlNode xNode = xmlDoc.SelectSingleNode("PFOID", "Quantity");
//string onlyvalue = xNode.InnerText;
//serializer.WriteObject(writer, SelectedStoreIds.ToArray());
serializer.Serialize(writer, pfoIdList);
if (writer != null)
writer.Close();
xmlString.ToString();
{
Context.PFOValidateUpdateData(xmlString.ToString(), WebContext.Current.User.UserID, op =>
{
IsProcessing = false;
if (ValidateUpdateCompleted != null)
ValidateUpdateCompleted(this, EventArgs.Empty);
}, null);
}
}
}
}
I tried Using XmlDocument and XmlNodes but unfortunately silverlight system.xml assembly dont have these extensions in its library.
Can anyone help me out with this please, I would really be great full to you. Thank you very much.
It looks like this... Sorry I used white spaces between & lt;
& lt; PFOID>" 04676723-2afb-49ff-9fa1-0131cabb407c & lt;/ PFOID &
gt;" & lt; Quantity & gt;" 90 & lt;/Quantity & gt;"
I don't know if it is a possible solution for you, but you can try to do something like this.
// Create a DataSet with one table containing two columns.
DataSet dataSet = new DataSet("dataSet");
DataTable table = dataSet.Tables.Add("string");
table.Columns.Add("PFOID", typeof(string));
table.Columns.Add("Quantity", typeof(value));
DataRow row;
row = table.NewRow();
row["PFOID"]= "04676723-2afb-49ff-9fa1-0131cabb407c";
row["Quantity"]= 90;
table.Rows.Add(row);
// Display the DataSet contents as XML.
Console.WriteLine(dataSet.GetXml());

Run time XML creation in c# and saving the data

Trying to create dynamic XML file and save the data to it, however i am able to save the last entry and not all the entries. Any thoughts?
To generate XML file with needed nodes:
GenerateXML()
XmlDocument doc = new XmlDocument();
XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
doc.AppendChild(docNode);
XmlNode albums = doc.CreateElement("albums");
doc.AppendChild(albums);
XmlNode album = doc.CreateElement("album");
albums.AppendChild(album);
XmlNode title = doc.CreateElement("title");
albums.AppendChild(title);
doc.Save(System.Windows.Forms.Application.StartupPath + "\\albums.xml");
The output from button click gives me either 10 records or 100 records or some number of records:
//album is a class returned by web service
if (Elements.Count > 0)
{
string path = System.Windows.Forms.Application.StartupPath + "\\albums.xml";
//Read the file stream in read mode
FileStream READER = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
System.Xml.XmlDocument albumSpecs = new System.Xml.XmlDocument();
albumSpecs.Load(READER);
FileStream WRITER = null;
GenerateXML();
//Create a FileStream for writing
WRITER = new FileStream(path, FileMode.Open, FileAccess.Write, FileShare.ReadWrite);
XmlElement root = doc.DocumentElement;
XmlNodeList nodes = root.SelectNodes("//albums");
for (int i = 0; i < ResultsList.Items.Count - 1; i++)
{
album = (Album)ResultsList.Items[i];
foreach (XmlNode node in nodes)
{
node["title"].InnerText = album.Title;
}
}
//Write the data to the filestream
doc.Save(WRITER);
}
I get the last entry data in the XML and not all the entries returned.
<?xml version="1.0" encoding="UTF-8"?>
<albums>
<album />
<title>She will be loved</title>
</albums>
How do i build run time XML based on the # of entries returned?
First load already saved xml into XmlDocument and then add new elements into it ...
GenerateXML()
string xmlFilePath = Path.Combine(System.Windows.Forms.Application.StartupPath, "albums.xml");
XmlDocument doc = new XmlDocument();
XmlNode albums = null;
if (!File.Exists(xmlFilePath))
{
XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
doc.AppendChild(docNode);
albums = doc.CreateElement("albums");
doc.AppendChild(albums);
}
else
{
doc.Load(xmlFilePath);
albums = doc.ChildNodes[1];
}
XmlNode album = doc.CreateElement("album");
albums.AppendChild(album);
XmlNode albumName = doc.CreateElement("name");
album.AppendChild(albumName);
XmlNode title = doc.CreateElement("title");
album.AppendChild(title);
doc.Save(xmlFilePath);
Try adding elements to your XML document ?
for (int i = 0; i < ResultsList.Items.Count - 1; i++)
{
album = (Album)ResultsList.Items[i];
foreach (XmlNode node in nodes)
{
node["title"].InnerText = album.Title;
}
}
This sample of code isnt doing much, because you only have one element to iterate on ...
Edit :
I imagine you want to do something like this :
for(int i = 0; i < ResultsList.Items.count -1; i++)
{
XmlNode child = doc.createElement("Title");
doc.AppendChild .....
}
doc.save;

Categories

Resources