I am trying send pdf file to printer using soap client from web.
Using job in ax works fine.
I'am tried: winAPI::shellExecute(adobeExe, adobeParm);
Enable AOS printing on the AOS server
http://www.artofcreation.be/2014/01/27/how-to-print-any-file-in-ax/
But does not work for me.
Maybe for someone has managed to do it?
Maybe need with ghostScript or sumatraPDF ? or...?
Thanks in advance.
#File //File macro
System.Diagnostics.ProcessStartInfo processInfo;
System.Diagnostics.Process process;
System.Exception interopException;
// Parameters
Filename fileName = #"C:\test\test.pdf";
PrinterName printername = UserPrinterHandler::getDefaultPrinter();
;
printerName = '"' + printerName + '"';
try
{
// assert permissions
new InteropPermission(InteropKind::ClrInterop).assert();
process = new System.Diagnostics.Process();
processInfo = process.get_StartInfo();
processInfo.set_UseShellExecute(true);
processInfo.set_CreateNoWindow(true);
processInfo.set_FileName(fileName);
// the argument is the printer name
processInfo.set_Arguments(printerName);
// set the verb to printto
processInfo.set_Verb('printto');
processInfo.set_WindowStyle(System.Diagnostics.ProcessWindowStyle::Hidden);
process.Start();
// revert asserted permissions
CodeAccessPermission::revertAssert();
}
Log into the server as the AOS user account and make sure the printer is added, or re-add it. Can't hurt to do it again as your user account too.
Related
I am using the PrintDocument for printing directly to the network printer using asp.net with and C#. The application hosted in IIS with Windows authentication. I am not getting the error and also the PrintStatus is Printing. But we can not see the printed document in the printer and also there is no errors in the printer.
System.Drawing.Printing.PrintDocument printdoc = new System.Drawing.Printing.PrintDocument();
printdoc.DefaultPageSettings.PaperSize = new PaperSize("Custom", 4, 3);
printdoc.OriginAtMargins = true;
// Set the printer name
PrinterSettings printer = new PrinterSettings();
printer.PrinterName = SqlDatabaseUtility.GetZebraPrinterName();
string fullName = CheckPrinterConfiguration(printer.PrinterName);
if (!String.IsNullOrEmpty(fullName))
{
printdoc.PrinterSettings.PrinterName = fullName;
// Handle printing
if (printdoc.PrinterSettings.IsValid)
{
printdoc.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(printdoc_PrintPage);
printdoc.PrinterSettings.Copies = 2;
printdoc.Print();
}
}
Just a theory, but the PrintDocument class is a descendant of Component and so implements IDisposable.
In the same way that you don't leave SqlConnection instances undisposed, you should call Dispose() on your printdoc instance so that any unmanaged resources held by the PrintDocument instance - such as a handle to the printer device, perhaps - get released.
Put a using clause around your printing block as below. It might help with your problem, but even if it does not it is proper practice.
using (System.Drawing.Printing.PrintDocument printdoc = new System.Drawing.Printing.PrintDocument())
{
...
}
The next line of enquiry would be to follow up on the "user permissions" suggestion in the comment. Assuming that your code works if you run it in a test console application, a quick test for this would be to change the user account of your web app's Application Pool to be your own account. If your web app starts printing, then you know that permissions are the problem.
I have a web site running in its own Application Pool (IIS 8). Settings for the pool are default i.e. recycle every 29 hours.
Our web server only has 8gb RAM and I have noticed that the worker process for this web site regularly climbs to 6gb RAM and slows the server to a crawl. This is the only site currently on the web server.
I also have SQL Express 2016 installed as well. The site is using EF version 6.1.3.
The MVC site is very straightforward. It has a GETPDF controller which finds a row in a table, gets PDF info stored in a field then serves it back to the browser as follows :-
using (eBillingEntities db = new eBillingEntities())
{
try
{
string id = model.id;
string emailaddress = Server.HtmlEncode(model.EmailAddress).ToLower().Trim();
eBillData ebill = db.eBillDatas.ToList<eBillData>().Where(e => e.PURL == id && e.EmailAddress.ToLower().Trim() == emailaddress).FirstOrDefault<eBillData>();
if (ebill != null)
{
// update the 'Lastdownloaded' field.
ebill.LastDownloaded = DateTime.Now;
db.eBillDatas.Attach(ebill);
var entry = db.Entry(ebill);
entry.Property(en => en.LastDownloaded).IsModified = true;
db.SaveChanges();
// Find out from the config record whether the bill is stored in the table or in the local pdf folder.
//
Config cfg = db.Configs.ToList<Config>().Where(c => c.Account == ebill.Account).FirstOrDefault<Config>();
bool storePDFDataInEBillTable = true;
if (cfg != null)
{
storePDFDataInEBillTable = cfg.StorePDFDataInEBillDataTable;
}
// End of Modification
byte[] file;
if (storePDFDataInEBillTable)
{
file = ebill.PDFData;
}
else
{
string pathToFile = "";
if (string.IsNullOrEmpty(cfg.LocalPDFDataFolder))
pathToFile = cfg.LocalBackupFolder;
else
pathToFile = cfg.LocalPDFDataFolder;
if (!pathToFile.EndsWith(#"\"))
pathToFile += #"\";
pathToFile += ebill.PDFFileName;
file = System.IO.File.ReadAllBytes(pathToFile);
}
MemoryStream output = new MemoryStream();
output.Write(file, 0, file.Length);
output.Position = 0;
HttpContext.Response.AddHeader("content-disposition", "attachment; filename=ebill.pdf");
return new FileStreamResult(output, "application/pdf");
}
else
return View("PDFNotFound");
}
catch
{
return View("PDFNotFound");
}
Are there any memory leaks here?
Will the file byte array and the memory stream get freed up?
Also, is there anything else I need to do concerning clearing up the entity framework references?
If the code looks OK, where would be a good place to start looking?
Regards
Are there any memory leaks here?
No.
Will the file byte array and the memory stream get freed up?
Eventually, yes. But that may be the cause of your excessive memory use.
Also, is there anything else I need to do concerning clearing up the entity framework references?
No.
If the code looks OK, where would be a good place to start looking?
If this code is the cause of your high memory use, it's because you are loading files into memory. And you're loading two copies of each file in memory, once in a byte[] and copying to a MemoryStream.
There's no need to do that.
To eliminate the second copy of the file use the MemoryStream(byte[]) constructor instead of copying the bytes from the byte[] to an empty MemoryStream.
To eliminate the first copy in memory, you can stream the data into a temporary file that will be the target of your FileStreamResult, or initialize the FileStreamResult using a ADO.NET stream.
See https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/sqlclient-streaming-support
If you go to ADO.NET streaming your DbContext, will need to be scoped to your Controller, instead of a local variable, which is a good practice in any case.
In addition to David's advice. I noticed that I was doing the following
**db.eBillDatas.ToList<eBillData>()**
therefore I was getting all the data from the database then fetching it again with the where clause.
I didn't notice the problem until the database started to fill up.
I removed that part and now the IIS worker processing is about 100mb.
I am trying to read an Excel sheet using C# which is to be loaded by end user from fileUpload control.
I am writing my code to save the file on server in event handler of another button control(Upload). But when I click on Upload Button I am getting this exception:
The process cannot access the file 'E:\MyProjectName\App_Data\sampledata.xlsx' because it is being used by another process.
Here is the code that I have used in event handler:
string fileName = Path.GetFileName(file_upload.PostedFile.FileName);
string fileExtension = Path.GetExtension(file_upload.PostedFile.FileName);
string fileLocation = Server.MapPath("~/App_Data/" + fileName);
//if (File.Exists(fileLocation))
// File.Delete(fileLocation);
file_upload.SaveAs(fileLocation);
Even deleting the file is not working, throwing the same exception.
Make sure, some other process is not accessing that file.
This error might occurs whenever you are trying to upload file, without explicitly removing it from memory.
So try this:
try
{
string fileName = Path.GetFileName(file_upload.PostedFile.FileName);
string fileExtension = Path.GetExtension(file_upload.PostedFile.FileName);
string fileLocation = Server.MapPath("~/App_Data/" + fileName);
//if (File.Exists(fileLocation))
// File.Delete(fileLocation);
file_upload.SaveAs(fileLocation);
}
catch (Exception ex)
{
throw ex.Message;
}
finally
{
file_upload.PostedFile.InputStream.Flush();
file_upload.PostedFile.InputStream.Close();
file_upload.FileContent.Dispose();
//Release File from Memory after uploading
}
The references are hanging in memory, If you are using Visual Studio try with Clean Solution and Rebuild again, if you are in IIS, just do a recycle of your application.
To avoid this problems try to dispose the files once you used them, something like:
using(var file= new FileInfo(path))
{
//use the file
//it will be automatically disposed after use
}
If i have understood the scenario properly.
For Upload control, I don't think you have to write code for Upload Button. When you click on your button,your upload control has locked the file and using it so it is already used by one process. Code written for button will be another process.
Prior to this, check whether your file is not opened anywhere and pending for edit.
The problem with flex applications is that a user can download it and run it on his local machine or possibly host it on another site. Is it possible to lock a flex application to a domain name to prevent such acts?
Sure, you'll do something like this in your application initialization area :
var domainList : String = 'mysite.com,anothersite.com';
var domainCheck : String = this.url.split('/')[2];
var foundValidDomain : Boolean = false;
for each ( var domainChecking : String in domainList.split(',')){
if( domainCheck.toUpperCase().indexOf(domainChecking.toUpperCase()) >= 0 ){
mx.controls.Alert.show( 'check success: "' + domainCheck + '" against: "' + domainChecking );
foundValidDomain = true;
break;
}else{
mx.controls.Alert.show( 'check failed: "' + domainCheck + '" against: "' + domainChecking );
}
}
if( !foundValidDomain ){
// oh noes! mad hax!
this.visible = false; // or however you want to lock it down
return;
}
Make sense? :)
Now, if you want to lock it down more, you can have your app post to a server with a key string and have the server send some encrypted time-sensitive instructions back (send date/time to server and back, etc). This would add another layer of hassle having to implement the server side as well. This is probably overkill for most applications.
You'll have to write the code yourself, but you could access the URL variable of the application tag and disable the app if the domain is not your domain.
I wouldn't call this an unbeatable measure, but I don't think anything is.
I'm not sure why this 'problem' is unique to Flex applications.
Take a look at this link http://www.richardlord.net/blog/protecting-a-swf
Basically, you can solve the problem by locking down the domain as you say, and also you can potentially encrypt your code using commercial solutions - which are discussed in the link. I think the main point is if you publish Flex code externally you want people to run it.
So I know how to send emails with attachments... thats easy.
The problem now is I need to add an MailMessage, that has an attachment of its own, to a different MailMessage. This will allow the user to review things and take the email that is pre-made and send it if everything is ok.
I am not sure this will be the final work flow, but I would like to know if easy.
I see a bunch of software out there that is for money, the users getting these emails will be using an outlook client.
This would be deployed to a cheap shared hosting solutions, must be able to run in Meduim Trust!
I would prefer not to have to lic a 3rd party software, No $ :(
Any ideas would be awesome.
MailMessages cannot be attached to other MailMessages. What you will do is create an .msg file, which is basically a file that stores an e-mail and all of its attachments, and attach that to your actual MailMessage. MSG files are supported by Outlook.
For more information about the file extension, go here: http://www.fileformat.info/format/outlookmsg/
As Justin said, there is no facility to attach one MailMessage to another in the API. I worked around this using the SmtpClient to "deliver" my inner message to a directory, and then attached the resulting file to my outer message. This solution isn't terribly appealing, as it has to make use of the file system, but it does get the job done. It would be much cleaner if SmtpDeliveryMethod had a Stream option.
One thing to note, the SmtpClient adds X-Sender/X-Receiver headers for the SMTP envelope information when creating the message file. If this is an issue, you will have to strip them off the top of the message file before attaching it.
// message to be attached
MailMessage attachedMessage = new MailMessage("bob#example.com"
, "carol#example.com", "Attached Message Subject"
, "Attached Message Body");
// message to send
MailMessage sendingMessage = new MailMessage();
sendingMessage.From = new MailAddress("ted#example.com", "Ted");
sendingMessage.To.Add(new MailAddress("alice#example.com", "Alice"));
sendingMessage.Subject = "Attached Message: " + attachedMessage.Subject;
sendingMessage.Body = "This message has a message attached.";
// find a temporary directory path that doesn't exist
string tempDirPath = null;
do {
tempDirPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
} while(Directory.Exists(tempDirPath));
// create temp dir
DirectoryInfo tempDir = Directory.CreateDirectory(tempDirPath);
// use an SmptClient to deliver the message to the temp dir
using(SmtpClient attachmentClient = new SmtpClient("localhost")) {
attachmentClient.DeliveryMethod
= SmtpDeliveryMethod.SpecifiedPickupDirectory;
attachmentClient.PickupDirectoryLocation = tempDirPath;
attachmentClient.Send(attachedMessage);
}
tempDir.Refresh();
// load the created file into a stream
FileInfo mailFile = tempDir.GetFiles().Single();
using(FileStream mailStream = mailFile.OpenRead()) {
// create/add an attachment from the stream
sendingMessage.Attachments.Add(new Attachment(mailStream
, Regex.Replace(attachedMessage.Subject
, "[^a-zA-Z0-9 _.-]+", "") + ".eml"
, "message/rfc822"));
// send the message
using(SmtpClient smtp = new SmtpClient("smtp.example.com")) {
smtp.Send(sendingMessage);
}
mailStream.Close();
}
// clean up temp
mailFile.Delete();
tempDir.Delete();