Can't Write to Windows Application Log (C#) - c#

I'm having a really strange problem with an application I wrote a while back. It has worked without issues, but after leaving it alone for a while, it simply stopped functioning. I'll attach the code here:
try
{
using (Process proc = Process.Start(starter))
{
windowHider();
proc.WaitForExit();
DateTime endStamp = DateTime.Now;
endStamp = truncate(endStamp);
TimeSpan diff = endStamp.Subtract(startStamp);
string programSource = "applicationName";
string logLocation = "Application";
string occurance = "Var='" + varName + "' Var2='"+ var2Name + "' Var3='" + var3Name + "' Var4='" + var4Name + "' Var5='" + var5Name + "' Var6='" + var6Name + "'";
try
{
if (!EventLog.SourceExists(programSource))
{
EventLog.CreateEventSource(programSource, logLocation);
}
else
{
EventLog.WriteEntry(programSource, occurance);
}
}
catch (Exception err)
{
string message = "There was an error with usage logging. Please contact IT.";
MessageBox.Show(message);
errorLogger(message, err.ToString(), ((Control)sender).Name);
this.Close();
}
this.Close();
}
}
When the process that was started exits, the program writes to the application log. For some reason, however, I am getting the following error:
Exception: System.ComponentModel.Win32Exception (0x80004005): The
specified path is invalid
It cites this line as the cause:
EventLog.WriteEntry(programSource, occurance);
Any ideas as to what this sudden problem could be?

I figured it out! There was something corrupted in the registry, and there must have been another corrupted component lurking around somewhere. I changed the sourcename, and it worked without any issues.
The original sourcename works on other machines, which makes me think it was definitely just something wonky with the registry.

Related

"database is locked" C# & SQLite

I keep getting this exception over and over. I've tried separating my query into two separate queries, that didn't work. I've checked to make sure the db connection is closed elsewhere before it's opened during this method, it's definitely closed before the function is called and opened before any queries.
Below iss the code for the function. I've set breakpoints and the query itself is fine. The code is the exact same that I used previously for updating a PIN function, with just the query string changed, so I don't know why it's causing issues:
Code:
public void transferMoney(string senderIban, decimal senderBalance, string receiverIban, decimal transferAmount,string messageOptional)
{
//myBankAccount.AccountPin = updatedPin;
DataTable dtUser = new DataTable();
sqlconnConnection.Open();
string strQuery2 = #"UPDATE Accounts SET Balance = Balance + " + Convert.ToDecimal(transferAmount) + " WHERE GUID = '" + receiverIban + "';"
+ "UPDATE Accounts SET Balance = Balance - " + Convert.ToDecimal(transferAmount) + " WHERE GUID = '" + senderIban + "';";
// example of a Paramaterised SQL statement.
SQLiteCommand sqlcomCommand2 = new SQLiteCommand(strQuery2, sqlconnConnection);
SQLiteDataAdapter sqldatadptAdapter = new SQLiteDataAdapter(sqlcomCommand2); // local SQL data Adaptor
try
{
// sqldatadptAdapter.Fill(dtUser);
sqlcomCommand2.ExecuteNonQuery();
}
catch (Exception ex)
{
// Exception will the "thrown" when there was a problem
throw new Exception($"UPDATE WAS unsuccessful:\n{ex.Message}");
}
finally
{
sqlconnConnection.Close();
}
Maybe you have a DB browser opened? Or you have accessed the DB some other way. This error only occurs when DB is modified or used elsewhere. If you can't find it, I'd suggest restarting PC just in case there something hidden :)
P.S. Posting this as answer as I cannot comment under the question for technical reasons :)

When using checkbox I get Cannot perform '=' operation on System.String and System.Int32

I am using a simple checkbox and everything works fine on my development machine but the end user is getting
"Cannot perform '=' operation on System.String and System.Int32".
I tried varying the code with the same result. My machine is running Windows 8.1 and the end user is on Windows Server 2008 R2.
First I tried this:
if(checkBox1.Checked)
{
this.personnelBindingSource.Filter = ("License =" + arg);
}
next I tried this,
string checkRelated = checkBox1.CheckState.ToString();
if(checkRelated.Equals("Unchecked"))
{
this.personnelBindingSource.Filter = ("License =" + arg);
}
I don't see why it even thinks I am using the '=' operation. Does anyone know why I am getting the error?
EDIT: I had this in the code.
InitializeComponent();
myArgLicense = "'" + myArgLicense + "'";
The above was not a global change so I was not interpreting the scope right in my checkbox routine. I changed the code to Sachu's recommendation it worked fine.
if(checkBox1.Checked)
{
this.personnelBindingSource.Filter = ("License =" + "'" + myArgLicense + "'");
}
The only thing that could be interpreted as int32 is arg, so I would try this:
if(checkBox1.Checked)
{
this.personnelBindingSource.Filter = ("License ='" + arg.ToString() + "'");
}
EDIT: I saw Sachu's comment too late.

"Cannot find Table[0]" - Only in production?

Some code on our production server is suddenly giving us some trouble. Production has not been changed in about a year, and I've confirmed that the database has not changed either.
If I run the same code on my machine (Yay Source Control!), I do not get the error that appears in production and everything works fine. I'll post the code below, but there has to be something else going on.
Correct me if I'm wrong, but if there is no Table[0], that means my query isn't returning any data. Yet, running the same query directly through SQL Management Studio gives me the data I want.
var ds = GetData(queryString);
if (ds.Tables.Count > 0)
{
var ddlDataSet = GetAdds();
}
private List<tAdd> GetAdds()
{
var ds = GetData(queryString);
var aList = new tAdd[ds.Tables[0].Rows.Count];//THIS IS WHERE ERROR HITS
//Do other stuff
...
}
private DataSet GetData(string queryString)
{
var connectionString =
ConfigurationManager.ConnectionStrings["constring"].ConnectionString;
var ds = new DataSet();
try
{
var connection = new SqlConnection(connectionString);
var adapter = new SqlDataAdapter(queryString, connection);
adapter.Fill(ds);
}
catch (Exception ex)
{
ErrorPanel.Visible = true;
ErrorPanel.Enabled = true;
SearchPanel.Enabled = false;
const string NotificationsEmail = "mailto:emailguy#email.com";
ErrorAlertLabel.Text =
"An err happened. " +
"Please contact the people who do stuff ";
ErrorAlertLabel.Visible = true;
ErrorMessageLiteral.Text = "<br />" + "<br />" +
"Message: " + ex.Message + "<br />" +
"StackTrace: " + ex.StackTrace + "<br />" +
"Inner Exception: " + ex.InnerException + "<br />" +
"Full Detals: " + ex + "<br />";
ErrorMessageLiteral.Visible = true;
}
return ds;
}
I may just try republishing the same version again, but who knows if that will fix it. If anyone needs more info please let me know and thank you in advance.
Actual Error Text: "System.IndexOutOfRangeException: Cannot find table 0."
I think you still have a flaw in your error handling that got exposed.
In GetData, you catch any Exception that occurs and set a bunch of UI elements to Visible and populate them with information, but you don't stop the process from continuing. GetData just continues on after the catch block, and returns an empty DataSet. GetAdds is oblivious to the fact that an error occured, tries to access a table in the DataSet that doesn't exist, and throws another exception that is not handled by your code, but is instead handled by ASP.NET, which throws away all of your error information and just shows a generic error page.
I would not use such detailed error handling within a low-level method, but add more global error handling. Since you don't add any meaningful information to the exception, I would just let it bubble up and handle it at the application level.
If you want to add more information to a low-level exception, throw a new exception with more detail, and assign the original exception to the new exception's InnerException property.
Please check whether you have any pdb files in production , if you dont have them than go to your project right click on properties under Build -> Advanced -> debug info -> pdb build this and please run it production,
If you have these than you can get the exact line where it is breaking.
This might occure,if there is a dead lock on the tables on production. or the permissions are missing.
Got it working today. I finally got a-hold of our Web Admin and asked him to restart the web server - this after I'd confirmed that my code and the DB were not the problem.
As soon as the web server booted back up everything was working fine. There are quite a few applications running on the server, so it may have been something getting tangled up.

Try catch when opening a text file for read

I have some code that is attempts to open a file on our network and what I am trying to do is put this into a try|catch block and I am running into a problem. When I try run my code I get an error: The name 'readProfile' does not exist in the current context (CS0103).
I know that since I am defining my streadreader object (readProfile) in the TRY of the try|catch block that I am not able to access the object but I don't know how to fix that. What I am trying to do is catch an error if I am unable to open the file (if someone else has it open, for example). Here is my code:
try {
StreamReader readProfile = new System.IO.StreamReader(ProDirectory.ToString() + #"\" + myProFile.ToString());
} catch (Exception ex) {
datalogger.Fatal(DateTime.Now.ToString() + ": Error while attempting to read file - " + ProDirectory.ToString() + #"\" + myProFile.ToString() + " The error is - " + ex.ToString());
}
If I remove the try|catch block, the code runs fine and does what I expect.
You can define variables outside the try, and then instantiate them inside:
StreamReader readProfile;
try
{
readProfile = new System.IO.StreamReader(ProDirectory.ToString() + #"\" + myProFile.ToString());
}
catch (Exception ex)
{
datalogger.Fatal(DateTime.Now.ToString() + ": Error while attempting to read file - " + ProDirectory.ToString() + #"\" + myProFile.ToString() + " The error is - " + ex.ToString());
// whatever you want to do with readProfile here. Of course, if the issue was that it couldn't create it, it still won't have been created...
}
Declare the StreamReader outside the try block but leave the assignment inside it.

Creating SQL Server backup file (.bak) with c# to any location

I'm trying to write simple application in C# which will allow me to backup, zip and send over ftp my SQL Server database.
One problem I have encountered is that I'm not able to create the backup file (.bak) if I try to do it in different location than "C:\Program Files\Microsoft SQL Server\MSSQL.3\MSSQL\Backup" or "C:\Program Files\Microsoft SQL Server\MSSQL.3\MSSQL\Data" folder. I understand that this is a premission problem. Could someone point me to the resources or write here a short snippet how to programmatically add such a permission to any folder on my system.
Regards
Kris
i assume you are running your programm as a scheduled task ... did you give writing permissions to the target folder for the executing user of the task??
edit:
with permissions you can have 2 scenarios:
windows authenification
mixed authentification
if you are using windows authentification, the read and write permissions of the windows user are taken. otherwise the permissions for the sql server service account.
and this behaviour makes sense to me and maybe hits the nail in your scenario!
edit 2:
i don't want to encourage you to do so ... some admins may hate you when you mess up their acl's
but this may do the trick
btw: Magnus Johansson already gave you a "try-this" link
no matter for which method you go - be sure to hand in the correct user (as descriped above!)
(for full history)
...
side-note:
i know this is not the exact answer to your question, but i would recommend you smo to generate backups ...
like
using Microsoft.SqlServer.Management.Smo;
var bdi = new BackupDeviceItem(/* your path inlcuding desired file */);
var backup = new Backup
{
Database = /* name of the database */,
Initialize = true
};
backup.Devices.Add(bdi);
var server = new Server(this.SqlServer);
try
{
backup.SqlBackup(server);
}
catch (Exception ex)
{
// * log or sth
}
you only have to care for the .dll's. take assemblies for the desired server version (some params/properties vary through different server versions)
more info here
Ok Guys, Magnus and dittodhole! Thanks a lot for your help. I have combined Magnus'es link to the article on setting up permisions on the folder together with some more research and finally I've got it :).
So reassuming, I'm using Smo, and to create a folder with proper permissions I have to look for the group instead of win32_Users. Here you go a short snippet if someone finds this post he can find it usefull:
string tempPath = Directory.CreateDirectory("C:\\path_to_your_folder").FullName;
//set permissions
SelectQuery sQuery = new SelectQuery("Win32_Group",
"Domain='" +
System.Environment.UserDomainName.ToString() +
"'");
try
{
DirectoryInfo myDirectoryInfo = new DirectoryInfo("C:\\path_to_your_folder");
DirectorySecurity myDirectorySecurity = myDirectoryInfo.GetAccessControl();
ManagementObjectSearcher mSearcher = new ManagementObjectSearcher(sQuery);
foreach (ManagementObject mObject in mSearcher.Get())
{
string User = System.Environment.UserDomainName + "\\" + mObject["Name"];
if(User.StartsWith("your-machine-name\\SQL"))
{
myDirectorySecurity.
AddAccessRule(new FileSystemAccessRule(User,
FileSystemRights.FullControl,
AccessControlType.Allow));
}
}
myDirectoryInfo.SetAccessControl(myDirectorySecurity);
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
Again thanks everyone for your help! Stackoverflow rocks!
Here is a procedure is use for back up in C#.Hope it helps
public void BackupDatabase (string BackUpLocation, string BackUpFileName, string
DatabaseName, string ServerName )
{
DatabaseName = "[" + DatabaseName + "]";
string fileUNQ = DateTime.Now.Day.ToString() + "_" + DateTime.Now.Month.ToString() + "_" + DateTime.Now.Year.ToString() +"_"+ DateTime.Now.Hour.ToString()+ DateTime.Now .Minute .ToString () + "_" + DateTime .Now .Second .ToString () ;
BackUpFileName = BackUpFileName + fileUNQ + ".bak";
string SQLBackUp = #"BACKUP DATABASE " + DatabaseName + " TO DISK = N'" + BackUpLocation + #"\" + BackUpFileName + #"'";
string svr = "Server=" + ServerName + ";Database=master;Integrated Security=True";
SqlConnection cnBk = new SqlConnection(svr);
SqlCommand cmdBkUp = new SqlCommand(SQLBackUp, cnBk);
try
{
cnBk.Open();
cmdBkUp.ExecuteNonQuery();
Label1.Text = "Done";
Label2.Text = SQLBackUp + " ######## Server name " + ServerName + " Database " + DatabaseName + " successfully backed up to " + BackUpLocation + #"\" + BackUpFileName + "\n Back Up Date : " + DateTime.Now.ToString();
}
catch (Exception ex)
{
Label1.Text = ex.ToString();
Label2.Text = SQLBackUp + " ######## Server name " + ServerName + " Database " + DatabaseName + " successfully backed up to " + BackUpLocation + #"\" + BackUpFileName + "\n Back Up Date : " + DateTime.Now.ToString();
}
finally
{
if (cnBk.State == ConnectionState.Open)
{
cnBk .Close();
}
}
}
Take a look at this article.
Remember to set the permissions for the account that the SQL Server instance is running with.
Although this may not answer your immediate question, I'd advice you to look into SQL Server Integration Services (SSIS). This looks like the exact thing SSIS was created for, and in the 2008 version there's the possibility to use C# code if needed, should the standard components not do what you need (earlier versions used VB.NET).
MSDN SSIS Info Link 1
SSIS 2005 Tutorial Link 2
Take a look at it.

Categories

Resources