Try catch when opening a text file for read - c#

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.

Related

Can't Write to Windows Application Log (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.

Log.txt of an unhandled exception of type 'System.InvalidOperationException'

I am currently working on a way to log into a text file an exception error of type System.InvalidOPerationException via a try{}... catch{} block. My concern is that Log.txt outputs:
Message :Exception of type 'System.Exception' was thrown.
StackTrace :
Date :4/21/2016 9:50:42 AM
Ideally I'd like it to be a bit more informative on the nature of the exception such those revealed by Microsoft Visual Studio dialog box. As an illustration:
An unhandled exception of type System.InvalidOPerationException occured
inSystem.dll
Additional information: the given ColumnName .... does not match up with
any column in datasource
see below the try....catch block applied on my method:
EDIT
try
{
// call method
}
catch (InvalidOperationException exc)
{
using (StreamWriter writer = new StreamWriter(logPath, true))
{
writer.WriteLine("Message :" + exc.Message + "<br/>" +
Environment.NewLine + "StackTrace :" + exc.StackTrace +
"" + Environment.NewLine + "Date :" +
DateTime.Now.ToString());
writer.WriteLine(Environment.NewLine + "-----------------------------------------------------------------------------"
+ Environment.NewLine);
}
}
Any relevant idea would be appreciated. Thanks in advance.

Use Sharepoint Copy web service to copy folder and contents

I am trying to make a program that copies all of a Sharepoint folder's contents (all subfolders and files) into another Sharepoint folder. Both of these folders will be on the same Sharepoint site.
However, I am trying to do this remotely - if possible*. Therefore, I have tried using the Copy web service without success. The Copy web service appears to only work with copying files, not folders. In addition, I cannot determine a way to iterate through the folder's contents to copy everything - it will only copy one item.
Thank you for any insights or tips,
Scott
*From a custom CRM workflow activity
~~Edited for clarification~~
In the end, I decided to create my own custom web service in Sharepoint that I was able to successfully access from Microsoft CRM. If anyone is interested, I've pasted the C# code I used to copy the folder structure:
public String CopyFolderContents(String sourceURL, String folderURL, String destinationURL)
{
try
{
#region Copying Code
//Get the SPSite and SPWeb from the sourceURL
using (SPWeb oWebsite = new SPSite(sourceURL).OpenWeb())
{
//Get the parent folder from the folderURL
SPFolder oFolder = oWebsite.GetFolder(folderURL);
//Create a list of all files (not folders) on the current level
SPFileCollection collFile = oFolder.Files;
//Copy all files on the current level to the target URL
foreach (SPFile oFile in collFile)
{
oFile.CopyTo(destinationURL + "/" + oFile.Name, true);
}
//Create a list of all folders on the current level
SPFolderCollection collFolder = oFolder.SubFolders;
//Copy each of the folders and all of their contents
String[] folderURLs = new String[collFolder.Count];
int i = 0;
foreach (SPFolder subFolder in collFolder)
{
folderURLs[i++] = subFolder.Url;
}
for (i = 0; i < folderURLs.Length; i++)
{
SPFolder folder = collFolder[folderURLs[i]];
folder.CopyTo(destinationURL + "/" + folder.Name);
}
}
#endregion Copying Code
}
catch (Exception e)
{
#region Exception Handling
String Message;
if (e.InnerException != null)
Message = "MESSAGE: " + e.Message + "\n\n" +
"INNER EXCEPTION: " + e.InnerException.Message + "\n\n" +
"STACK TRACE: " + e.StackTrace + "\n\n" +
"Source: " + sourceURL + "\n" +
"Folder: " + folderURL + "\n" +
"Destination: " + destinationURL;
else
Message = "MESSAGE: " + e.Message + "\n\n" +
"STACK TRACE: " + e.StackTrace + "\n\n" +
"Source: " + sourceURL + "\n" +
"Folder: " + folderURL + "\n" +
"Destination: " + destinationURL;
throw new Exception(Message);
#endregion Exception Handling
}
return "Operation Successful!";
}
All I did was add this method into a Sharepoint web service and called it from CRM and it works.
Thanks to everyone who provided other answers,
Scott
There is a simple solution to this problem , as its just about copy and paste use the simple XCOPY command
XCOPY Copy files and/or directory trees to another folder. XCOPY is similar to the COPY command except that it has additional switches to specify both the source and destination in detail.
To copy a folder including all subfolders
XCOPY C:\utils\* D:\Backup\utils /s /i
here /i defines the destination as a folder
for more detail please refer this link

Issue regarding exception details c#

I was trying to capture exception details with the below code, but it is not giving error in details.
I was trying to download a file from our ftp server with code like ftp classes. When file was not found, I fire the above method and pass in the exception. Unfortunately the method printed the following:
Error occured and Error details as follows
Exception occured in file
Exception occured in method SyncRequestCallback
Exception occured in line & column number 0 0
Here is my code. How can I capture the exception details (e.g. line number, method where the exception was thrown, etc.)?
public static string GetException(Exception ex)
{
//Get a StackTrace object for the exception
StackTrace st = new StackTrace(ex, true);
//Get the first stack frame
StackFrame frame = st.GetFrame(0);
//Get the file name
string fileName = frame.GetFileName();
//Get the method name
string methodName = frame.GetMethod().Name;
//Get the line number from the stack frame
int line = frame.GetFileLineNumber();
//Get the column number
int col = frame.GetFileColumnNumber();
string strBody = "Hi,<br/><br/>";
strBody = strBody + "Error occured and Error details as follows<br/>";
strBody = strBody + "Error message " + ex.Message + "<br/>";
strBody = strBody + "Exception occured in file " + fileName + "<br/>";
strBody = strBody + "Exception occured in method " + methodName + "<br/>";
strBody = strBody + "Exception occured in line & column number " + line + " " + col + "<br/><br/>Thanks";
return strBody;
}
Thanks
In order to capture more information you'll need to deploy .pdb files generated on build. This will allow you to know specific line where error happened.
As a side note, it seems to me that you're reinventing the wheel creating such a complex logic to log. There plenty of frameworks that will do the dirty job for you as log4net.
Calling ToString on an exception generally generates a readable version of the public details. And only the details available to the exception will be shown, so if the app is not running in debug mode and doesn't have corresponding *.pdb files (or you don't have them to attach, after the fact) - and symbols loads - then you can't get detailed source information.

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