The file creates and emails just fine. But when I attempt to delete or modify it for an indeterminate amount of time thereafter I get the dreaded "Cannot access file because it is in use by another program" message. I've seen it before with documents created in itextsharp, but it was because a PdfStamper was left open. Not sure what it locking it now. Tried using WhoLockMe to see what's going on but it doesn't work on Windows 7 X 64. Tried using LockHunter but it just says that the file isn't locked by any processes. The location of the file is limited to admins and I have confirmed no other admins are in the file when this occurs.
public string SubmitWeekly(string store, string techId, string date, WeeklyHeader header, string latLon, string device, List<CPEquipment> equipment)
{
PdfReader templateReader = null;
PdfReader overFlowReader = null;
PdfStamper templateStamper = null;
PdfStamper overFlowStamper = null;
try
{
string result = "Success";
string year = date.Right(4);
string footerText = string.Format("Submitted {0} near {1} on device {2}", date, latLon, device);
string template = #"C:\Templates\WeeklyInspectionFormCombined.pdf";
string overflowTemplate = #"C:\Templates\WeeklyInspectionOverflowForm.pdf";
string newFile = string.Format(#"C:\Documents\{0}\{1}\Weekly Inspection {2} {3}.pdf", year, techId, store, date);
string overFlowFile = string.Format(#"C:\Documents\{0}\{1}\Weekly Inspection Pg 2 {2} {3}.pdf", year, techId, store, date);
string directory = string.Format(#"C:\Documents\{0}\{1}", year, techId);
templateReader = new PdfReader(template);
//Check for directory and create if doesn't exist
if (!Directory.Exists(directory))
Directory.CreateDirectory(directory);
templateStamper = new PdfStamper(templateReader, new FileStream(newFile, FileMode.Create));
AcroFields templateFields = templateStamper.AcroFields;
AcroFields overFlowFields = null;
int equipCnt = 1;
int attachCnt = 1;
//Extract stand alone items from equipment list
List<CPEquipment> seUnits = (from s in equipment
where s.Serial == s.AttachedTo && s.Status != "ATTACHMENT"
select s).ToList();
//Extract attachments from equipment list
List<CPEquipment> attachments = (from a in equipment
where a.Status == "ATTACHMENT"
select a).ToList();
//Set header and footer info in new file
templateFields.SetField("Store Number", store);
templateFields.SetField("Technician", techId);
templateFields.SetField("Week Of", date.WeekOf());
templateFields.SetField("Street Address", stAddress);
templateFields.SetField("City", stCity);
templateFields.SetField("Comments", header.Comments + "\nTrained:\t" + header.Trained + "\nOn:\t" + header.Topics);
templateFields.SetField("Footer", footerText);
//Set security info in new file
templateFields.SetField("WL", header.WL == "True" ? "Yes" : "No");
templateFields.SetField("TL", header.TL == "True" ? "Yes" : "No");
templateFields.SetField("CC", header.CC == "True" ? "Yes" : "No");
//Set equipment lines in new file
int maxLines = seUnits.Count > 20 ? 20 : seUnits.Count;
while (equipCnt <= maxLines)
{
CPEquipment current = seUnits.ElementAt(equipCnt - 1);
CPEquipment trailer = (from t in equipment
where t.AttachedTo == current.Serial && t.AttachedTo != t.Serial && t.Status != "ATTACHMENT"
select t).FirstOrDefault();
templateFields.SetField("ModelRow" + equipCnt, current.Model);
templateFields.SetField("SerialRow" + equipCnt, current.Serial);
templateFields.SetField("StatusRow" + equipCnt, current.Status);
templateFields.SetField("Tool TurnedRow" + equipCnt, current.ToolTurned);
templateFields.SetField("Last PMRow" + equipCnt, current.LastPmDate + " " + current.LastPmHours);
templateFields.SetField("Current HoursRow" + equipCnt, current.CurrentHours);
templateFields.SetField("TagRow" + equipCnt, current.Tag);
templateFields.SetField("StExpiresRow" + equipCnt, current.State + " " + current.Expiration);
if (trailer != null)
{
templateFields.SetField("Trailer ModelRow" + equipCnt, trailer.Serial);
templateFields.SetField("Trailer VINRow" + equipCnt, trailer.Model);
templateFields.SetField("TagRow" + equipCnt, trailer.Tag);
templateFields.SetField("StExpiresRow" + equipCnt, trailer.State + " " + trailer.Expiration);
}
equipCnt++;
}
//Set overflow lines if any
if (seUnits.Count > 20)
{
overFlowReader = new PdfReader(overflowTemplate);
overFlowStamper = new PdfStamper(overFlowReader, new FileStream(overFlowFile, FileMode.Create));
overFlowFields = overFlowStamper.AcroFields;
overFlowFields.SetField("Store", store);
overFlowFields.SetField("Footer", footerText);
while (equipCnt > 20 && equipCnt < seUnits.Count)
{
CPEquipment current = seUnits.ElementAt(equipCnt - 1);
CPEquipment trailer = (from t in equipment
where t.AttachedTo == current.Serial && t.AttachedTo != t.Serial
select t).FirstOrDefault();
overFlowFields.SetField("ModelRow" + (equipCnt - 20), current.Model);
overFlowFields.SetField("SerialRow" + (equipCnt - 20), current.Serial);
overFlowFields.SetField("StatusRow" + (equipCnt - 20), current.Status);
overFlowFields.SetField("Tool TurnedRow" + (equipCnt - 20), current.ToolTurned);
overFlowFields.SetField("Last PMRow" + (equipCnt - 20),
current.LastPmDate + " " + current.LastPmHours);
overFlowFields.SetField("Current HoursRow" + (equipCnt - 20), current.CurrentHours);
overFlowFields.SetField("TagRow" + (equipCnt - 20), current.Tag);
overFlowFields.SetField("StExpiresRow" + (equipCnt - 20),
current.State + " " + current.Expiration);
if (trailer != null)
{
overFlowFields.SetField("Trailer ModelRow" + (equipCnt - 20), trailer.Serial);
overFlowFields.SetField("Trailer VINRow" + (equipCnt - 20), trailer.Model);
overFlowFields.SetField("TagRow" + (equipCnt - 20), trailer.Tag);
overFlowFields.SetField("StExpiresRow" + (equipCnt - 20),
trailer.State + " " + trailer.Expiration);
}
equipCnt++;
}
overFlowStamper.FormFlattening = true;
overFlowReader.Close();
overFlowStamper.Close();
}
//Set attachment fields and update attachment in db
foreach (CPEquipment attach in attachments)
{
templateFields.SetField("SNRow" + attachCnt, attach.Serial);
templateFields.SetField("MR" + attachCnt, attach.Model);
attachCnt++;
}
//Flatten forms and close readers and stampers
templateStamper.FormFlattening = true;
templateReader.Close();
templateStamper.Close();
//Set up email
MailMessage mail = new MailMessage(new MailAddress("me#mydomain.com"),
new MailAddress(techMail));
mail.Attachments.Add(new Attachment(newFile));
if (equipCnt > 20)
mail.Attachments.Add(new Attachment(overFlowFile));
mail.Subject = "Weekly Inspection";
SmtpClient client = new SmtpClient(//Hidden);
client.Send(mail);
return result;
}
catch (Exception e)
{
if (templateStamper != null)
{
templateStamper.FormFlattening = true;
templateStamper.Close();
}
if (overFlowStamper != null)
{
overFlowStamper.FormFlattening = true;
overFlowStamper.Close();
}
if (templateReader != null)
templateReader.Close();
if (overFlowReader != null)
overFlowReader.Close();
return "Submit Weekly: " + e.Message;
}
}
A using Statement with the PdfStamper and FileStream should solve your problem. If you don't need to save the PDF(s), you can replace FileStream with a MemoryStream to save you the extra step of deleting the file(s) after sending the email attachments.
Related
I have a situation where I replicate a pdf from an existing pdf blank 'certificate', The replica pdf contains some personal info that was added to the 'blue print' copy.
After mailing this to the user I want to delete it again so as not to save a copy on the server.
No matter what I do, however, I get the error message
The process cannot access the file 'certificate#672712.pdf' because it is being used by another process.
It is pretty clear what the message means, what I want to know is how I should alter the code for the certificate creation part so that is 'released' after words.
This is the code that I use.
try
{
string suffix = (DateTime.Now.Day % 10 == 1 && DateTime.Now.Day != 11) ? "st of"
: (DateTime.Now.Day % 10 == 2 && DateTime.Now.Day != 12) ? "nd of"
: (DateTime.Now.Day % 10 == 3 && DateTime.Now.Day != 13) ? "rd of"
: "th of";
string dateToday = string.Format("{0:dd}{1} {0:MMMM yyyy}", DateTime.Now, (suffix));
Random generator = new Random();
string referenceNumber = "#" + generator.Next(0, 1000000).ToString("D6");
string bluePrint = HttpContext.Current.Server.MapPath("~/Certificates/blue_print.pdf");
if (certificateNumber != "")
{
referenceNumber = certificateNumber;
}
string certificate = HttpContext.Current.Server.MapPath("~/Certificates/certificate_" + referenceNumber + ".pdf");
PdfReader reader = new PdfReader(bluePrint);
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(certificate, FileMode.Create)))
{
reader.SelectPages("1");
var pageSize = reader.GetPageSize(1);
PdfContentByte pbover = stamper.GetOverContent(1);
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
pbover.SetColorFill(BaseColor.DARK_GRAY);
Font font = new Font(bf);
font.Size = 32;
ColumnText.ShowTextAligned(pbover, Element.ALIGN_LEFT, new Phrase(UserName, font), 90, 305, 0);
}
reader.Close();
return referenceNumber;
}
catch (Exception exe)
{
return exe.Message.ToString();
}
in my controller method I call the methods in this sequence.
//certificate
var reference = UtilityService.GenerateCertificate(String.Format("{0} {1}", firstName, lastName), "");
//Mail the certificate
string message = await MailService.MailTheCertificate(user.Email, "Well done", "Well done on completing the course", reference);
//THE ERROR HAPPENS AS I AM TRYING TO DELETE THE CERTIFICATE
FileInfo file = new FileInfo(HttpContext.Current.Server.MapPath("~/Certificates/certificate_" + reference + ".pdf"));
file.Delete();
return Ok("success");
when i run this code after 30 second give me error 'time out expire' . error comming exactly after fill dataset . by the way i add connection time out = 0 to my app config but still the problem is the same . so how i can set connection time out for this dataset
public void ExportInvoicesAccount()
{
var q = from h in hmsdb.TransHdrs
where h.Account.AccountsContracts.First().AccountsMain.ID == _mainaccid
&& h.PayMethod == "R"
&& h.CancelDate == null
&& h.TransDate >= _fromdate
&& h.TransDate <= _todate
group h by new
{
amID = h.Account.AccountsContracts.First().AccountsMain.ID,
amcode = h.Account.AccountsContracts.First().AccountsMain.Code,
amName = h.Account.AccountsContracts.First().AccountsMain.EngName,
acccode = h.AccountCode,
accid = h.AccountID,
accname = h.Account.EngName
} into qg
select new
{
amID = qg.Key.amID,
amCode = qg.Key.amcode,
amName = qg.Key.amName,
acccode = qg.Key.acccode,
accid = qg.Key.accid,
accname = qg.Key.accname
};
if (_facccode != "" && _taccccode == "")
{
q = q.Where(f => f.acccode == _facccode);
}
if (_facccode != "" && _taccccode != "")
{
q = q.Where(f => Convert.ToInt32(f.acccode) >= Convert.ToInt32(_facccode) && Convert.ToInt32(f.acccode) <= Convert.ToInt32(_taccccode) && f.acccode != "C" && f.acccode != "10281501مكرر ");
}
foreach (var x in q)
{
try
{
ClaimDS ds = new ClaimDS();
SP_EClaims_StatmentOfAccountGeneralTableAdapter adapt = new SP_EClaims_StatmentOfAccountGeneralTableAdapter();
ds.EnforceConstraints = false;
adapt.Fill(ds.SP_EClaims_StatmentOfAccountGeneral, x.amID, x.accid, 0, _fromdate, _todate, _inout,0,0,0, 0);
if (ds.SP_EClaims_StatmentOfAccountGeneral.Rows.Count != 0)
{
InvoicesByAcc rptinv = new InvoicesByAcc();
rptinv.SetDataSource(ds);
ExportOptions expop = new ExportOptions();
DiskFileDestinationOptions dfdo = new DiskFileDestinationOptions();
PdfRtfWordFormatOptions pdfop = new PdfRtfWordFormatOptions();
FolderPath = _path + x.amCode + " - " + x.amName + "\\";
bool exists = System.IO.Directory.Exists(FolderPath);
if (!exists)
System.IO.Directory.CreateDirectory(FolderPath);
fpath = FolderPath;
rptinv.ExportOptions.ExportFormatType = ExportFormatType.PortableDocFormat;
rptinv.ExportOptions.ExportDestinationType = ExportDestinationType.DiskFile;
DiskFileDestinationOptions objDiskOpt = new DiskFileDestinationOptions();
if (_inout == "O")
{
objDiskOpt.DiskFileName = FolderPath + "\\" + x.acccode + "-" + "0000" + "-0000" + "-" + "001" + "-OUT" + ".pdf";
}
else if (_inout == "I")
{
objDiskOpt.DiskFileName = FolderPath + "\\" + x.acccode + "-" + "0000" + "-0000" + "-" + "001" + "-IN" + ".pdf";
}
else
{
objDiskOpt.DiskFileName = FolderPath + "\\" + x.acccode + "-" + "0000" + "-0000" + "-" + "001" + "-ALL" + ".pdf";
}
rptinv.ExportOptions.DestinationOptions = objDiskOpt;
rptinv.Export();
rptinv.Dispose();
rptinv.Close();
}
GC.Collect();
ds.Dispose();
ds.Clear();
}
catch (Exception ex)
{
string logpath = FolderPath + "E_Claim_ErrorLog.txt";
// This text is added only once to the file.
if (!File.Exists(logpath))
{
// Create a file to write to.
using (StreamWriter sw = File.CreateText(logpath))
{
//sw.WriteLine(ex.Message + "( " + "AccountMainID: " + x.amID + " - " + "AccountID: " + x.accid + " - "+ "ConsID: " + x.consid + " - " + "MRN: " + x.mrn + " )");
}
}
// This text is always added, making the file longer over time
// if it is not deleted.
using (StreamWriter sw = File.AppendText(logpath))
{
sw.WriteLine(ex.Message + " SP_EClaims_StatmentOfAccountGeneral" + "ExportInvoicesAccount" + "( " + "AccountMainID: " + x.amID + " - " + "AccountID: " + x.accid + " - " + "ConsID: " + "0" + " - " + "MRN: " + "0" + " )");
}
//MessageBox.Show(ex.Message + "AccountMainID: " + x.amID + "-"+ "AccountID: " + x.accid + "ConsID: " + x.consid + "MRN: " + x.mrn );
}
}
}
I have the following code segment that sends an email to users based on 'RequestApproval' being set to true on their records in a SQL table - it works perfectly.
SmtpClient mySmtpClient = new SmtpClient();
List<SigList> LST_SigList = LK_CRFData.SigLists.Where(x => x.RequestApproval == true).ToList();
string URL = sponsorURL + OB_CRF.id;
foreach (SigList OB_SigList in LST_SigList)
{
string Name = OB_SigList.UserName.Trim();
Name = Name.Substring(0, Name.IndexOf("."));
Name = Name[0].ToString().ToUpper() + Name.Substring(1, Name.Length - 1);
MailMessage myMessage = new MailMessage("SponsorApproved#nhs.net", OB_SigList.EmailAddress);
myMessage.Subject = "Sponsor has approved the request on the " + TB_DateTimeofImplementationStart.Text.Substring(0, 10) + " for \"" + TB_CNNO.Text + " " + TB_Title.Text + "\"";
myMessage.Body = "Dear " + Name + ", \n\nThe sponsor has now approved CN NO : " + TB_CNNO.Text + "\nTitle : " + TB_Title.Text + "\nImplementation Date : " + TB_DateTimeofImplementationStart.Text.Substring(0, 10) + "\n\nClick the link to open the document:\n" + URL;
mySmtpClient.Send(myMessage);
}
However, for certain functions, I want to send the email where 'Request approval is set to True OR False. I've ammended it to the following to no avail:
List<SigList> LST_SigList = LK_CRFData.SigLists.Where(x => x.RequestApproval == true || x.RequestApproval == false).ToList();
It still sends emails out the old way -only to those who have Request Approval' set to true.
Any ideas?
Thanks
I need help here.I don't know how to tell to labels from different stringBuilder to go on different .doc files.In my if() statements in need to tell to write labels from first stringBuilder and in another if() statement should write labels from another stingBuilder in another .doc file. Below is my code:
StringBuilder strBody = new StringBuilder();
StringBuilder strBody1 = new StringBuilder();
strBody.Append(#"<html " +
"xmlns:o='urn:schemas-microsoft-com:office:office' " +
"xmlns:w='urn:schemas-microsoft-com:office:word'" +
"xmlns='http://www.w3.org/TR/REC-html40'>" +
"<head><title>Time</title>");
strBody1.Append(#"<html " +
"xmlns:o='urn:schemas-microsoft-com:office:office' " +
"xmlns:w='urn:schemas-microsoft-com:office:word'" +
"xmlns='http://www.w3.org/TR/REC-html40'>" +
"<head><title>Time</title>");
strBody.Append("<body lang=EN-US style='tab-interval:.5in'>" +
"<p style='color:red; font-size:13px'>" +
Label47.Text +"<br/>" +
Label45.Text +"X "+
Label48.Text +" " +
Label54.Text +"</p>" +
"</div></body></html>").Append(strBody1.ToString());
strBody1.Append("<body lang=EN-US style='tab-interval:.5in'>" +
"<p style='color:red; font-size:13px'>" +
Label12.Text +"<br/>" +
Label11.Text +"X "+
Label13.Text +" " +
Label17.Text +"</p>" +
"</div></body></html>");
if (Session["one"] != null && Session["two"] != null && Session["three"] != null)
{
{
string path = #"c:\Backup\kitchen.doc";
string path2 = #"c:\Backup\bar.doc";
if (!File.Exists(path) && !File.Exists(path2))
{
using (StreamWriter sw = File.CreateText(path))
{
using (StreamWriter sw2 = File.CreateText(path2))
{
if (Label53.Text == "4")
{
sw.WriteLine(strBody);
}
else if (Label53.Text == "1")
{
sw2.WriteLine(strBody);
if (Label44.Text == "4")
{
sw.WriteLine(strBody1);
}
else if (Label44.Text == "1")
{
sw2.WriteLine(strBody1);
}
}
I think there is a missing closing } in your if conditions. The
else if (Label53.Text == "1")
did not have a closing }
Updated if conditions
if (Label53.Text == "4")
{
sw.WriteLine(strBody);
}
else if (Label53.Text == "1")
{
sw2.WriteLine(strBody);
}
if (Label44.Text == "4")
{
sw.WriteLine(strBody1);
}
else if (Label44.Text == "1")
{
sw2.WriteLine(strBody1);
}
I am trying to create a hash text file. The code works, the problem is that once the streamwriter starts the process it won't stop until it is finished. I want to break up the output file into smaller parts. How do I stop the streamwriter and start a new file without starting the process over again?
string infile = #"ntlmchar.txt";
string hashfile = #"ntlmhash.txt"; //File that includes the hash and clear test
string charfile = #"ntlmchar.txt"; //File that only has the clear text
string oldCharFile = ""; //Temp file to apply to infile.
int cint = 1; //The number of characters in the file
string str_cint = cint.ToString(); //convert cint to string
int pint = 1; //The number of parts to the character file
string str_pint = pint.ToString(); //convert pint to string
int cm = 4; //Max number of characters
int pm = 4000; //Man number of parts
int line = 0; //line index number
while (cint <= cm)
{
if (!File.Exists(infile))
{
for (int ci =1; ci <= cm; ci++)
{
str_cint = cint.ToString();
for (int pi =1; pi <= pm; pi++)
{
str_pint = pint.ToString();
// System.Console.WriteLine("Inner for loop cint file does not exist" +cint +" pint " + pint);
// System.Console.WriteLine("Inner for loop str_cint file does not exist " + str_cint + " cint " + cint);
charfile = "ntlmchar" + str_cint + "_" + str_pint + ".txt";
pint = pi;
oldCharFile = charfile;
infile = oldCharFile;
if (File.Exists(infile)) break;
// System.Console.WriteLine("inner loop file " + infile);
}
// System.Console.WriteLine("outer for loop cint " + cint + " pint " + pint);
// System.Console.WriteLine("infile not found " + infile + " " + oldCharFile + " " + charfile + " " + hashfile);
}
// System.Console.WriteLine("No work files found " + infile + " " + oldCharFile + " " + charfile + " " + hashfile);
}
else if (File.Exists(infile))
{
// Create a file to write to.
// System.Console.WriteLine("cint at the start of else if " + cint + " str_cint " + str_cint);
infile = oldCharFile;
str_cint = cint.ToString();
// System.Console.WriteLine("cint after assign to str_cint " + cint + " str_cint " + str_cint);
pint=1;
str_pint = pint.ToString();
hashfile = "ntlmhash" + str_cint + "_" + str_pint + ".txt";
charfile = "ntlmchar" + str_cint + "_" + str_pint + ".txt";
//System.Console.WriteLine(infile + " " + oldCharFile + " " + charfile + " " + hashfile);
// System.Console.WriteLine("Infile found " + cint + " " + pint);
using (StreamWriter h = new StreamWriter(hashfile))
using (StreamWriter c = new StreamWriter(charfile))
using (StreamReader sr = new StreamReader(infile))
{
string i = "";
while ((i = sr.ReadLine()) != null)
{
foreach (string s in alpha)
{
if (line <= 2000000)
{
string j = i + s;
string str = Program.Ntlm(j);
hashfile = "ntlmhash" + str_cint + "_" + str_pint + ".txt";
charfile = "ntlmchar" + str_cint + "_" + str_pint + ".txt";
// System.Console.WriteLine("line before writing to file " + line + " in charfile " + charfile);
h.WriteLine("{0}, {1}", j, str);
c.WriteLine("{0}", j);
line++;
// System.Console.WriteLine("h file" + h + " c file" + c);
}
else
{
h.Flush();
c.Flush();
pint++;
str_pint = pint.ToString();
hashfile = "ntlmhash" + str_cint + "_" + str_pint + ".txt";
charfile = "ntlmchar" + str_cint + "_" + str_pint + ".txt";
line = 1;
System.Console.WriteLine("line after writing to part of file " + line + " in charfile " + charfile);
}
}
}
I assume you're trying to get 2,000,000 items per file? You just need to restructure a little.
Right now you have:
using (StreamWriter h = new StreamWriter(hashfile))
using (StreamWriter c = new StreamWriter(charfile))
using (StreamReader sr = new StreamReader(infile))
{
string i = "";
while ((i = sr.ReadLine()) != null)
{
You need to change your code so that you open the output files later:
using (StreamReader sr = new StreamReader(infile))
{
StreamWriter h = null;
StreamWriter c = null;
try
{
h = new StreamWriter(...);
c = new StreamWriter(...);
string i = "";
while ((i = sr.ReadLine()) != null)
{
// output line here
// and increment line counter.
++line;
if (line > 2000000)
{
// Close the output files and open new ones
h.Close();
c.Close();
h = new StreamWriter(...);
c = new StreamWriter(...);
line = 1;
}
}
}
finally
{
if (h != null) h.Close();
if (c != null) c.Close();
}
}