How does this log method work in a .NET application? - c#

I am working on a .NET project using C# and I have the following doubt.
I have this method that write some error information into a .log file in a specific directory on my file system:
private static void writeErrorLog(string error)
{
string date = DateTime.Now.ToString("yyyyMMdd_HHmmss");
string currDir = Directory.GetCurrentDirectory();
System.IO.File.AppendAllText(currDir + "\\FILE\\LOG\\Error_" + date + ".txt", error);
}
Ok this writeErrorLog() method will be called into some try catch block of my code, something like this:
try
{
currentAttachmentFileData = currentAttachmentFile.OpenBinary();
currentAttachementModel = new AttachmentModel(currentAttachment, currentAttachmentFileData);
attachmentsModelList.Add(currentAttachementModel);
}
catch (Exception ex)
{
//writeLog(2, String.Format("Unable to read the attachment, it may be corrupted {0} - {1}", fileName, ex.Message));
writeErrorLog("Errore inserimento attachment. Numero protocollo: " + recNumber
+ " Data protocollo: " + recDate
+ " Nome attachment: " + currentAttachmentFile
+ " INFO: " + ex.ToString() + " | " + ex.Message + " | " + ex.StackTrace);
}
It happens in different places of my code.
My doubt is: the file is the same, so it means that it will be added a new line to this file every time that an error occours.
Is it my reasnong correct?

The file name is string date = DateTime.Now.ToString("yyyyMMdd_HHmmss"); so it changes every second.
You should definitely add some abstraction here and hide writeErrorLog behind an interface. Behind the interface you could have your own implementation of writeErrorLog, but as others suggested I would strongly recommend using libs over your custom solution.
More on available libraries:
benchmarking-5-popular-net-logging-libraries
dotnetlogging.com

Related

Revit API - Grids & Levels - GetDatumExtentTypeInView - issue with grids

I'm trying to get the grid extent types. its either gonna be "model" or "specificView"
with the code i have, I am able to get the Levels extent types but not the Grid extent types.
I've found these sources so far that have helped.
https://forum.dynamobim.com/t/switching-between-2d-and-3d-extent-levels-grid/10980/2
https://www.revitapidocs.com/2019/b3498ccf-1180-e0fd-502c-6c767f5b42cc.htm
https://disqus.com/home/discussion/revit-api-docs/setverticalextents_method_60/#edit-3254927585
This is the error im getting:
Exception thrown: 'Autodesk.Revit.Exceptions.ArgumentException' in RevitAPI.dll
Error StackTrace: at Autodesk.Revit.DB.DatumPlane.GetDatumExtentTypeInView(DatumEnds datumEnd, View view)
at ChangeGridExtentsTo2D.Command.Execute(ExternalCommandData commandData, String& message, ElementSet elements)
Error Data: System.Collections.ListDictionaryInternal
Error Source: RevitAPI
Error TargetSite: Autodesk.Revit.DB.DatumExtentType GetDatumExtentTypeInView(Autodesk.Revit.DB.DatumEnds, Autodesk.Revit.DB.View)
Here is my code so far:
FilteredElementCollector colGrids = new FilteredElementCollector(doc)
.WhereElementIsNotElementType().OfCategory(BuiltInCategory.OST_Grids)
.OfClass(typeof(Grid));
Debug.WriteLine("colGrids count: " + colGrids.GetElementCount()); //output is 3 which is correct
FilteredElementCollector colLevels = new FilteredElementCollector(doc)
.WhereElementIsNotElementType().OfCategory(BuiltInCategory.OST_Levels)
.OfClass(typeof(Level));
Debug.WriteLine("colLevels count: " + colLevels.GetElementCount()); // output is 7 which is correct
using (Transaction tx = new Transaction(doc))
{
try
{
tx.Start("Changing extends to 2d");
foreach (DatumPlane xLevels in colLevels)
{
//x.GetDatumExtentTypeInView(DatumEnds.End0, uidoc.ActiveView);
Debug.WriteLine(xLevels.Name + ": " + xLevels.GetDatumExtentTypeInView(DatumEnds.End0, uidoc.ActiveView));
Debug.WriteLine(xLevels.Name + ": " + xLevels.GetDatumExtentTypeInView(DatumEnds.End1, uidoc.ActiveView));
}
foreach (DatumPlane xGrids in colGrids)
{
Debug.WriteLine(xGrids.Name + ": " + xGrids.GetDatumExtentTypeInView(DatumEnds.End0, uidoc.ActiveView));
}
tx.Commit();
}
catch (Exception e)
{
Debug.WriteLine("Error StackTrace: " + e.StackTrace);
Debug.WriteLine("Error Data: " + e.Data);
Debug.WriteLine("Error Source: " + e.Source);
Debug.WriteLine("Error TargetSite: " + e.TargetSite);
tx.RollBack();
}
}
PS - I am new to VS IDE so if anyone has any tips on getting more verbose errors like:
what line the error occurs on
the variable or function it crashed at
or anything like that
That would be a huge help
I suggest you work through some simple getting started tutorial on debugging in Visual Studio IDE.
In the debugger, you can step through the code line by line, examine the values of all the variables, and much more, thereby answering all your requests above in one fell swoop.

How to convert a few lines of code from vb.net to its c# equivalent

I'm tasked with converting some older VB.net code to C#. Been slowly chipping away at the errors -went from about 100, down now to ~10. The first vb.net code that needs to be converted is:
Try
My.Computer.FileSystem.CopyFile(strFile, strExportPath + "\" + strFileName(0), FileIO.UIOption.OnlyErrorDialogs, FileIO.UICancelOption.DoNothing)
intFilesCopied += 1
My.Computer.FileSystem.MoveFile(strFile, _strPath + "Data\Backup\" + strFileName(0), FileIO.UIOption.OnlyErrorDialogs, FileIO.UICancelOption.DoNothing)
intFilesMoved += 1
Catch ex As Exception
My.Application.Log.WriteException(ex, TraceEventType.Error, "ExportDataToolStripMenuItem_Click")
End Try
My C# attempt is as follows:
try
{
File.Copy(strFile, strExportPath + #"\" + strFileName[0], UIOption.OnlyErrorDialogs,
FileIO.UICancelOption.DoNothing);
intFilesCopied += 1;
File.Move(strFile, _strPath + #"Data\Backup\" + strFileName[0],
UIOption.OnlyErrorDialogs, UICancelOption.DoNothing);
intFilesMoved += 1;
}
catch (Exception ex)
{
Application.Log.WriteException(ex, TraceEventType.Error, "ExportDataToolStripMenuItem_Click");
}
The next piece of VB.NET is the catch portion of the try-catch clauses.
My.Application.Log.WriteException(ex, TraceEventType.Error, "Could not write record to data file " + _strActiveFileName + Environment.NewLine + "Record Data: " + strRecordText);
And for the life of me, cannot find the C#-equivalent for this.
I've tried adding the Microsoft.VisualBasic dll/reference/namespace, but that doesn't work either. Tried to google the C#-equivalent, but couldn't find anything.
The next piece of VB.NET is the catch portion of the try-catch
clauses.
My.Application.Log.WriteException(ex, TraceEventType.Error, "Could not
write record to data file " + _strActiveFileName + Environment.NewLine
+ "Record Data: " + strRecordText);
And for the life of me, cannot find the C#-equivalent for this.
This can be converted by (with reference to Microsoft.VisualBasic.dll):
Microsoft.VisualBasic.ApplicationServices.ApplicationBase MyApplication = new Microsoft.VisualBasic.ApplicationServices.ApplicationBase();
then :
MyApplication.Log.WriteException(ex, TraceEventType.Error, "ExportDataToolStripMenuItem_Click");
And you can check the log file with :
System.Windows.Forms.MessageBox.Show(MyApplication.Log.DefaultFileLogWriter.FullLogFileName);
(just tested on Windows 10)

Best way to fix: Acces to path 'C:\..\USB-map' is denied because map is already used

I am trying to make to create a .cmd file with this code into it: call .\CopyToTarget.cmd w60 glb "C:\Users\oma\me\trunk-r664\USB-map". I am creating this code ~5 times.
But since \trunk-r664\ is already in use it seems like I cannot write: #"\trunk-r664\USB-map" into the .cmd file for some reason. Does anyone know how to fix it? It keeps getting me the error: UnauthorizedAccesExpection was unhandled, ccess to the path 'C:\Users\me\Desktop\trunk-r664\USB-map' is denied.
using (StreamWriter sw = File.CreateText(Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
+ "\\trunk-r664\\trunk\\cmd\\custom\\RunAll.cmd"))
{
for (int j=0;j<installeerlijst64.Count;j++)
{
sw.WriteLine("call .\\CopyToTarget.cmd " + installeerlijst64[j] + " glb" +
File.CreateText(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + #"\trunk-r664\USB-map"));
}
}
I tried this too, but it tells me I am using an illegal character:
"\""+File.CreateText(Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
+ #"\trunk-r664\USB-map" + "\""));
File.CreateText will create a new file. First time when for loop execute, it will create and open the file USB-map and hold the handle of that file. During second iteration of for loop, it will try to do the same thing. Hence, already in use error.
Remove File.CreateText and you will get the desired result.
sw.WriteLine("call .\\CopyToTarget.cmd " + installeerlijst64[j] + " glb " + "\"" +
Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + #"\trunk-r664\USB-map" + "\"");

Windows Service, Plugin load trouble

I have written a plugin system inspired from NotePad.NET, this plugin system read all DLL File in given folder and load them at runtime if they match my Interface using reflection. code is below
foreach (string file in System.IO.Directory.GetFiles(dir + "\\plugins\\", "*.dll", System.IO.SearchOption.AllDirectories))
if (file.EndsWith(".dll"))
{
Assembly dll = Assembly.LoadFrom(file);
foreach (Type t in dll.GetTypes())
{
try
{
log.WriteLine("Trying to match " + t.BaseType.FullName + " with " + typeof(Acoustical.PluginBase.FileFormatBase).FullName + " and " + typeof(Acoustical.PluginBase.ReportBase).FullName);
if (t.BaseType.FullName == typeof(FileFormatBase).FullName)
{
log.WriteLine(" we compare for " + t.BaseType.FullName);
try
{
fileformatPlugin.Add((dynamic)Activator.CreateInstance(t));
}
catch (Exception ex)
{
log.WriteLine("Error in loading File Plugin ::" + ex.Message + "\r\n" + ex.StackTrace);
}
continue;
}
else if (t.BaseType.FullName == typeof(ReportBase).FullName)
{
log.WriteLine(" we compare for " + t.BaseType.FullName);
reportPlugin.Add((dynamic)Activator.CreateInstance(t));
continue;
}
}
catch (Exception ex) {
log.WriteLine("Error in loading Plugin ::" + ex.Message + "\r\n" + ex.StackTrace);
}
}
dll = null;
}
Above code shows the part where Iterate over all found files in folder and than load them.
The above code works for me if I use the Windows Form or WCF interface application, it works on Windows service but doesn't guarantee that. It 60-70% of time on recompile doesn't load the plugin, then I after 10-15 attempts it sometime load plugins or sometime load only 1-2 plugins.
as you see I put Try catch on almost all lines to trace where the error is coming but no error is showing up. Since it is Windows SErvice it is not possible to debug when this code is written on ONStartup event.
I did see "We compare for" line in log, but when we try to see fileformatplugin got any element it's count remain 0 and error line is not there in log.
Any advice?

C# / Webservice app on server throwing strange exception

We use ADP for employee information. I had to create a small app that called some web services that ADP has to pull employee information. The app is fairly procedural..not really object orientated in a sense. Basically I go through some web services to pull general information, work information, employee status, etc.
I have most of this data writing out to a text file as a log so I can ensure that everything is working correctly. Finally got it all done, and it works perfect on my local machine. Thought I'd just copy the entire structure onto a server and use windows scheduler to schedule the exe to run nightly (once a day). When it tries to run the app it looks like it is dying when it calls the first web service. The task scheduler log says:
""ADP.job" (ADP.exe)
Started 2/11/2010 2:14:34 PM
"ADP.job" (ADP.exe)
Finished 2/11/2010 2:14:38 PM
Result: The task completed with an exit code of (e0434f4d)."
So I checked the event viewer and it says this:
EventType clr20r3, P1 adp.exe, P2 1.0.0.0, P3 4b745bb9, P4 adp, P5 1.0.0.0, P6 4b745bb9, P7 289, P8 2d, P9 system.io.filenotfoundexception, P10 NIL.
For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.
I put in some console.writelines to see where it is failing...
Here is a simple example of main:
static void Main(string[] args)
{
OpenTextFile();
Console.WriteLine("About to process employee work information...");
tw.WriteLine("About to process employee work information...");
//work info service
EmpWorkInfo();
}
And inside of opentextfile:
public static void OpenTextFile()
{
//used to log data
String sLogName;
Console.WriteLine("Inside of opentextfile");
if (Directory.Exists(logPath))
{
//directory exists
}
else
{
Directory.CreateDirectory(logPath);
}
Console.WriteLine("Inside of opentextfile2");
sLogName = "log_" + DateTime.Today.ToString("MM_dd_yyyy") + ".txt";
tw = new StreamWriter(logPath + sLogName);
}
I see all the console.writelines on the server but as soon as it hits this line from main:
EmpWorkInfo();
Thats when all hell breaks lose (basically it doesn't work). The EmpWorkInfo() is simply a function to get work related information from a web service (as I said this works locally).
static void EmpWorkInfo()
{
Console.Writeline("THIS NEVER PRINTS!!!");
SQLClass s=null;
// Create the web service proxy client.
GetEmployeeWorkInfoService oService = new GetEmployeeWorkInfoService();
oService.Timeout = Int32.MaxValue;
// Serialize the UsernameToken into XML.
// Create the UsernameToken as defined in the WS-I secure profile.
UsernameToken oUsernameToken = new UsernameToken(USERNAME, SECRET);
System.Xml.XmlElement oSecurityHeaderXml =
oUsernameToken.GetXml(new System.Xml.XmlDocument());
ADP.GetEmployeeWorkInfoWebService.SecurityHeaderType oSecurityHeader = new ADP.GetEmployeeWorkInfoWebService.SecurityHeaderType();
oSecurityHeader.Any = new System.Xml.XmlElement[] { oSecurityHeaderXml };
oService.Security = oSecurityHeader;
GetEmployeeWorkInfoRequestFilter oFilter = new GetEmployeeWorkInfoRequestFilter();
//filter by thyssenkrupp company
oFilter.Companies = new String[] { COMPANY_IDENTIFIER };
GetEmployeeWorkInfoRequest oRequest = new GetEmployeeWorkInfoRequest();
oRequest.Filter = oFilter;
try
{
EmployeeWorkInfoType[] arPersonalInfo = oService.GetEmployeeWorkInfo(oRequest);
try
{
s = new SQLClass();
}
catch (Exception e)
{
throw new System.Exception(e.Message.ToString());
}
for (int i = 0; i < arPersonalInfo.Length; i++)
{
String stID = arPersonalInfo[i].EmployeeKey.Identifier.EmployeeId; //employee number
String stEmailAddress = arPersonalInfo[i].WorkInfo.EmailAddress; //employee email address (work)
String stFax = arPersonalInfo[i].WorkInfo.Fax; //employee fax number
DateTime dtHireDate = arPersonalInfo[i].WorkInfo.OriginalHireDate;
String stPhone = arPersonalInfo[i].WorkInfo.Phone; //employee phone number
String stWireless = arPersonalInfo[i].WorkInfo.Wireless; //employee wireless number
tw.WriteLine("Processing ID:" + stID + " Email Work: " + stEmailAddress + " Fax Work: " + stFax + " Hire Date: " + dtHireDate + " Phone Work: " + stPhone + " Wireless Work: " + stWireless + ".");
Console.WriteLine("Processing ID:" + stID + " Email Work: " + stEmailAddress + " Fax Work: " + stFax + " Hire Date: " + dtHireDate + " Phone Work: " + stPhone + " Wireless Work: " + stWireless + ".");
s.SetSQLCommand("dbo.ADP_uiEmployeeWorkInfo");
s.AddSQLCmdParameter("#EmployeeNumber", System.Data.SqlDbType.VarChar, stID);
s.AddSQLCmdParameter("#EmailAddress", System.Data.SqlDbType.VarChar, stEmailAddress);
s.AddSQLCmdParameter("#Fax", System.Data.SqlDbType.VarChar, stFax);
s.AddSQLCmdParameter("#HireDate", System.Data.SqlDbType.DateTime, dtHireDate);
s.AddSQLCmdParameter("#Telephone", System.Data.SqlDbType.VarChar, stPhone);
s.AddSQLCmdParameter("#Mobile", System.Data.SqlDbType.VarChar, stWireless);
s.SQLExecuteNonQuery();
Console.WriteLine("Processed ID:" + stID + " Email Work: " + stEmailAddress + " Fax Work: " + stFax + " Hire Date: " + dtHireDate + " Phone Work: " + stPhone + " Wireless Work: " + stWireless + ".");
Console.WriteLine(Environment.NewLine);
}
s.CloseSQLDB();
s.Dispose();
}
//catch any exception from adp side.
catch (Exception e)
{
throw new System.Exception(e.Message.ToString());
}
}
This functions code is irrelevant (its ugly but do not let that bother you, the code works...). My issue is I cannot even get to the first console.writeline of that function. Is there anything special I need to do when it comes to working with webservices?
Edit
Logpath is defined as simply a static string outside of main:
private static string logPath = Environment.CurrentDirectory + "\\log\\";
I suspect that your application is not able to load the types referenced in that function - EmpWorkInfo.
1) Can you run this application on the target server in a commannd window (cmd.exe) ?
2) Are you using any assemblies from ADP that are installed in the global assembly cache (GAC)? Run "gacutil -l" on your localmachine to see if you are using any assemblies from ADP that are installed in thr gac. If they are, you will need to install these into the machine on which you are running the app.
Does logPath have a trailing backslash? Either way, you ought to use Path.Combine, rather than the string catenation operator (+).
What happens if you comment out all the code in EmpWorkInfo() apart from the first Console.Writeline? Does it still not get written out?
Found out I need the Microsoft.Web.Services3 dll installed on the server.
Continuation on "feroze" answer;
If you want to figure out if the 'loading of dependencies' is causing you grief here, i suggest using the "FUSLOGVW.EXE" tool *(part of .Net). When you run this it will give you a little dialog window with a few options. Create a directory somewhere (like "c:\temp\fusion_logs"), set the mode of FUSLOGVW to "log bind failures only", "custom location->c:\temp\fusion_logs".
Now restart your application and check that it failed. Now look into your fusion_logs directory. This should give you sub directories with different (maybe only 1 for now) application names. Inside each directory you will find the log files. These log files contain the "failed assembly loads" and who (which calling assembly) caused them.
They might help your hunt for a working application,
Hope this helps,
Edit: Posted this after you found the cause. The fuslogvw.exe would have shown you the missing assembly.

Categories

Resources