I have created a web service to take all files found in a folder specified, eg C:/Incoming/20121018 and email them as attachments to an email address that I specify.
I can send a mail with one attachment successfully, but I thought I would pass several files via an array to be sent as attachments. The only problem is that when I try to read the folder containing the files, I get a Permission error, even though I have rights to that folder. Any idea on where I'm going wrong?
See my code below:
[WebMethod]
public string Sending_Email(string strEmailAddrFrom, string[] strEmailAddrTo, int intTotalEmailTo, string [] strAttachement)
{
DateTime LeadDate;
LeadDate = DateTime.Now.Date;
string Year = Convert.ToString(LeadDate.Year);
string Month = Convert.ToString(LeadDate.Month);
string Day = Convert.ToString(LeadDate.Day);
string[] arr1 = new string[150];
string Loc = "C:\\Incoming\\" + "" + Year + "" + Month + "" + Day + "";
StreamReader reader = File.OpenText(Loc);
string contents = reader.ReadToEnd();
reader.Close();
DirectoryInfo di = new DirectoryInfo(Loc);
FileInfo[] fileList = di.GetFiles(".*.");
int count = 0;
foreach (FileInfo fi in fileList)
{
arr1[count] = fi.Name;
}
EmailAlert NewMail = new EmailAlert();
return NewMail.EmailSent(strEmailAddrFrom, strEmailAddrTo, intTotalEmailTo, arr1);
}
your error lies here you are trying to open folder as stream which is not right way.
StreamReader reader = File.OpenText(Loc);
string contents = reader.ReadToEnd();
reader.Close();
Related
I want to display list of all files(.jpg,.mp3,.psd,.tiff etc) from local storage(hard disk space) and the path of local storage gets generated when SQL query gets fired for eg. I have fields folder_name, Subfolder_name and Id.
So suppose Query: Select Folder_name,Subfolder_name From Table where Id = 101;
suppose I get output Folder_name=Users,Subfolder_name = Public. Now this value must gets passed in the path for eg: Path =C:\Users\Public\. And from this Path I want to display all the files in the same form as they are saved.
In my current implementation I m getting list of files in base64 form.But i want in the Same form as they are saved.for eg. if file is in jpg want to display list of jpg's file.
I m getting list of files in base64 form .
public List<Image> GetImagesBySourceKey(string ID)
{
List<Image> images = new List<Image>();
string sqlQuery = "select folder_name,Subfolder_name from Table where Id= '" +
Id+ "'";
foreach (DataRow dataRow in ExecuteQuery(sqlQuery))
{
images.Add(new Models.Image()
{
folder_name= dataRow["folder_name"].ToString(),
Subfolder_name = dataRow["Subfolder_name"].ToString()
});
DirectoryInfo d = new DirectoryInfo(#"C:\\Users\\bhagyeshc\\source\\repos\\abcd\\abcd\\" +
images[0].FileName + "\\" + Subfolder_name);
FileInfo[] Files = d.GetFiles("*.*"); //Getting files
foreach (FileInfo file in Files)
{
Image image = new Image();
var path = Path.Combine("~\\" + images[0].FileName + "\\" + Subfolder_name+ "\\" + file.Name);
image.Code = ImageBase64(path);
images.Add(image);
}
}
return images;
}
private string ImageBase64(string path)
{
path = System.Web.Hosting.HostingEnvironment.MapPath(path);
var ext = System.IO.Path.GetExtension(path);
var contents = System.IO.File.ReadAllBytes(path);
MemoryStream ms = new MemoryStream(contents);
byte[] imageBytes = ms.ToArray();
string base64String = Convert.ToBase64String(imageBytes);
return base64String;
}
DirectoryInfo d = new DirectoryInfo(#"D:\"+Folder_name+"\"+SubFolder_name");
FileInfo[] Files = d.GetFiles("*.jpg"); //Getting Text files
string str = "";
foreach(FileInfo file in Files )
{
str = str + ","+file.Name;
}
str will return all files under this folder
i need to find and delete all lines wich contain the word "recto",
i did search in stackoverflow forum, but all what i found is do that (delete the line) using path (Directory & FileName).
in my case i want to delete the line contain "recto" in all fils with specific extention (*.txt) in the directory.
thanks for help
here is my code so far
string sourceDir = #"C:\SRCE\";
string destinDir = #"C:\DIST\";
string[] files = Directory.GetFiles(sourceDir);
foreach (string file in files)
{
using (StreamReader sr_ = new StreamReader
(sourceDir + Path.GetFileName(file)))
{
string line = sr_.ReadLine();
if (line.Contains("recto"))
{
File.Copy(file, destinDir + Path.GetFileName(file));
string holdName = sourceDir + Path.GetFileName(file);
}
sr_.DiscardBufferedData();
sr_.Close();
}
}
}
You can try something like this. You were only identifying the files with the word but not making any try to remove it. At the end, you were copying the files that included the word "recto"
string sourceDir = #"C:\SRCE\";
string destinDir = #"C:\DIST\";
string[] files = Directory.GetFiles(sourceDir);
foreach (string file in files)
{
using (StreamReader sr_ = new StreamReader
(sourceDir + Path.GetFileName(file)))
{
string res = string.Empty;
while(!sr_.EndOfStream)
{
var l = sr_.ReadLine();
if (l.Contains("recto"))
{
continue;
}
res += l + Environment.NewLine;
}
var streamWriter = File.CreateText(destinDir + Path.GetFileName(file));
streamWriter.Write(res);
streamWriter.Flush();
streamWriter.Close();
}
}
If the files are not really big you can simplify a lot your code reading all lines in memory, processing the lines with Linq and then rewriting the files
string sourceDir = #"C:\SRCE\";
string destinDir = #"C:\DIST\";
string[] files = Directory.GetFiles(sourceDir);
foreach (string file in files)
{
var lines = File.ReadLines(file);
var result = lines.Where(x => x != "recto").ToArray();
File.WriteAllLines(Path.Combine(destinDir, Path.GetFileName(file)), result);
}
I am trying to send an email when the lastwritetime is more than 16 minutes. I want to loop through my files and check lastwritetime. When more than 16 minutes old send an email alert. I am looking to use the local or system time where the images are stored. I have gotten this far, but the system emails too often and it does not alert when I run a test and the images have not updated. What am I doing wrong?
try
{
string files = #"\\cyclops-ch2-10\users\!SptEntEng\Desktop\ScreenScrapes\ChicagoSkyvision\ScreenScrape\ScreenScrape.png";
string files1 = #"\\cyclops-ch2-10\users\!SptEntEng\Desktop\ScreenScrapes\ChicagoSeachange\ScreenScrape\ScreenScrape.png";
string files2 = #"\\cyclops-ch2-10\users\!SptEntEng\Desktop\ScreenScrapes\IndianaSkyvision\ScreenScrape\ScreenScrape.png";
string files3 = #"\\cyclops-ch2-10\users\!SptEntEng\Desktop\ScreenScrapes\IndianaSeachange\ScreenScrape\ScreenScrape.png";
string files4 = #"\\cyclops-ch2-10\users\!SptEntEng\Desktop\ScreenScrapes\DetroitSkyvision\ScreenScrape\ScreenScrape.png";
string files5 = #"\\cyclops-ch2-10\users\!SptEntEng\Desktop\ScreenScrapes\MichiganSeachange\ScreenScrape\ScreenScrape.png";
string files6 = #"\\cyclops-ch2-10\users\!SptEntEng\Desktop\ScreenScrapes\LansingSkyvision\ScreenScrape\ScreenScrape.png";
string files7 = #"\\cyclops-ch2-10\users\!SptEntEng\Desktop\ScreenScrapes\MinnesotaSeachange\ScreenScrape\ScreenScrape.png";
string files8 = #"\\cyclops-ch2-10\users\!SptEntEng\Desktop\ScreenScrapes\HoustonSeachange\ScreenScrape\ScreenScrape.png";
var FilePaths = new List<string>();
FilePaths.Add(files);
FilePaths.Add(files1);
FilePaths.Add(files2);
FilePaths.Add(files3);
FilePaths.Add(files4);
FilePaths.Add(files5);
FilePaths.Add(files6);
FilePaths.Add(files7);
FilePaths.Add(files8);
foreach (string file in FilePaths)
{
FileInfo fi = new FileInfo("ScreenScrape.png");
if (fi.LastWriteTime < DateTime.Now.AddMinutes(16))
{
client.Send(CyclopsCentral);
break;
}
}
Your check will always be true as you are comparing to future time.
if (fi.LastWriteTime < DateTime.Now.AddMinutes(16))
You need to change it to -16
if (fi.LastWriteTime < DateTime.Now.AddMinutes(-16))
i am using dropzone to upload multiple files to the server. files will be uploaded to server while file names will be stored in table.
i am trying to add file names in session.
the problem here is that it doesn't add multiple file names inside single session
here is my code :
string imageSessList = context.Session["imageNames"].ToString(); //if i put this line at the begining, then the debugger doesn't even moves to foreach block
foreach (string s in context.Request.Files)
{
HttpPostedFile file = context.Request.Files[s];
string fileName = file.FileName;
string fileExtension = file.ContentType;
string strUploadFileExtension = fileName.Substring(fileName.LastIndexOf(".") + 1);
string strAllowedFileTypes = "***jpg***jpeg***png***gif***bmp***"; //allowed file types
string destFileName = "";
List<string> lstImageNames = new List<string>();
// else upload file
if (!string.IsNullOrEmpty(fileName))
{
if (strAllowedFileTypes.IndexOf("***" + strUploadFileExtension + "***") != -1) //check extension
{
if (context.Request.Files[0].ContentLength < 5 * 1024 * 1024) //check filesize
{
// generate file name
destFileName = Guid.NewGuid().ToString() + "." + strUploadFileExtension;
string destFilePath = HttpContext.Current.Server.MapPath("/resourceContent/") + destFileName;
//Save image names to session
lstImageNames.Add(destFileName);
context.Session["imageNames"] = lstImageNames;
file.SaveAs(destFilePath);
strMessage = "Success " + destFileName;
}
else
{
strMessage = "File Size can't be more than 5 MB.";
}
}
else
{
strMessage = "File type not supported!";
}
}
} // foreach
context.Response.Write(strMessage);
}
here i am able to add only single filename to session, not multiple.
how to store and maintain multiple file names in single session :
context.Session["imageNames"]
you need to get current list from session
List<string> lstImageNames= (List<string>)Session["imageNames"];
if(lstImageNames==null)
lstImageNames = new List<string>(); // create new list in the first time
now add new item to it.
lstImageNames.Add(destFileName);
set back to session
context.Session["imageNames"] = lstImageNames;
I'm having issues with a bit of code that I am writing in C#.
I am sending a document using the MailMessage and SMTP components. I copy the files that I wish to send to a temp directory such as c:\temp, loop through the documents and attach them to the email.
The email sends fine, however when I try to delete the files from the temp directory, I get the following error:
The process can not access the file because it is being used by another process
I can't understand why this is happening. Below is the code that processes the documents
public void sendDocument(String email, string barcode, int requestid)
{
string tempDir = #"c:\temp";
//first we get the document information from the database.
Database db = new Database(dbServer, dbName, dbUser, dbPwd);
List<Document> documents = db.getDocumentByID(barcode);
int count = 0;
foreach (Document doc in documents)
{
string tempPath = tempDir + "\\" + doc.getBarcode() + ".pdf";
string sourcePath = doc.getMachineName() + "\\" + doc.getFilePath() + "\\" + doc.getFileName();
//we now copy the file from the source location to the new target location
try
{
//this copies the file to the folder
File.Copy(sourcePath, tempPath, false);
}
catch (IOException ioe)
{
count++;
//the file has failed to copy so we add a number to the file to make it unique and try
//to copy it again.
tempPath = tempDir + "\\" + doc.getBarcode() + "-" + count + ".pdf";
File.Copy(sourcePath, tempPath, false);
}
//we now need to update the filename in the to match the new location
doc.setFileName(doc.getBarcode() + ".pdf");
}
//we now email the document to the user.
this.sendEmail(documents, email, null);
updateSentDocuments(documents, email);
//now we update the request table/
db.updateRequestTable(requestid);
//now we clean up the documents from the temp folder.
foreach (Document doc in documents)
{
string path = #"c:\temp\" + doc.getFileName();
File.Delete(path);
}
}
I would of thought that the this.sendEmail() method would of sent the email before returning to the sendDocument method, as I think it is the smtp object that is causing the deletes to fail.
This is the sendEmail method:
public void sendEmail(List<Document> documents, String email, string division)
{
String SMTPServer = null;
String SMTPUser = null;
String SMTPPwd = null;
String sender = "";
String emailMessage = "";
//first we get all the app setting used to send the email to the users
Database db = new Database(dbServer, dbName, dbUser, dbPwd);
SMTPServer = db.getAppSetting("smtp_server");
SMTPUser = db.getAppSetting("smtp_user");
SMTPPwd = db.getAppSetting("smtp_password");
sender = db.getAppSetting("sender");
emailMessage = db.getAppSetting("bulkmail_message");
DateTime date = DateTime.Now;
MailMessage emailMsg = new MailMessage();
emailMsg.To.Add(email);
if (division == null)
{
emailMsg.Subject = "Document(s) Request - " + date.ToString("dd-MM-yyyy");
}
else
{
emailMsg.Subject = division + " Document Request - " + date.ToString("dd-MM-yyyy");
}
emailMsg.From = new MailAddress(sender);
emailMsg.Body = emailMessage;
bool hasAttachements = false;
foreach (Document doc in documents)
{
String filepath = #"c:\temp\" + doc.getFileName();
Attachment data = new Attachment(filepath);
emailMsg.Attachments.Add(data);
hasAttachements = true;
}
SmtpClient smtp = new SmtpClient(SMTPServer);
//we try and send the email and throw an exception if it all goes tits.
try
{
if (hasAttachements)
{
smtp.Send(emailMsg);
}
}
catch (Exception ex)
{
throw new Exception("EmailFailure");
}
}
How to I get around this problem with a process hogging the file I wish to delete.
I can delete the file(s) once the application finishes.
You're email message isn't being Disposed, try disposing it after you've sent it:
try
{
if (hasAttachements)
{
smtp.Send(emailMsg);
}
}
catch ...
finally
{
emailMsg.Dispose();
}
The first step is to figure out what process is holding onto the file in question. I would grab the SysInternals toolkit and use the handle.exe command to determine what process is holding onto the file.
Without knowing what process has the file open, there is no way to fix this problem.
Sysinternals Link: http://technet.microsoft.com/en-us/sysinternals/default.aspx
Here's a trick I just discoverred, which will hopefully be of use to other folk?
Before adding attachments to a message, create the attachment in a using wrapper. This ensures it gets disposed of correctly, allowing the file to be successfully deleted. I'm not sure if the send also needs to be in this loop; (when I tested, emails didn't get through at first, then half an hour later I got flooded, so decided to leave testing for a time when the network was a little calmer).
using (Attachment attachment = new Attachment(filename))
{
message.Attachments.Add(attachment);
client.SendAsync(message, string.Empty);
}
File.Delete(filename);
Works OK for me anyway :)
Good luck,
JB