How to Print file with using Task Scheduled - c#

My console Application is working when double clicking application and it downloads .zip files from mail then send pdfs to printer. However, Problem is that when I use task scheduled to run this app, it reads mail then download .zip files but it doesnt send pdf files to printer. I didnt Understand what problem is that. How can I handle this ?
static void Main(string[] args)
{
ExchangeService exchange = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
exchange.Credentials = new WebCredentials("mail", "password);
exchange.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
if (exchange != null)
{
SearchFilter sf = new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));
FindItemsResults<Item> result = exchange.FindItems(WellKnownFolderName.Inbox, sf, new ItemView(20));
foreach (Item item in result)
{
EmailMessage message = EmailMessage.Bind(exchange, item.Id);
message.IsRead = true;
message.Update(ConflictResolutionMode.AutoResolve);
List<Attachment> zipList = message.Attachments.AsEnumerable().Where(x => x.Name.Contains(".zip")).ToList();
foreach (Attachment Attachment in zipList)
{
if (Attachment is FileAttachment)
{
FileAttachment f = Attachment as FileAttachment;
f.Load("C:\\pdfFiles\\" + f.Name);
string zipPath = #"C:\pdfFiles\" + f.Name;
string extractPath = #"C:\pdfFiles\" + Path.GetRandomFileName();
ZipFile.ExtractToDirectory(zipPath, extractPath);
string[] filePaths = Directory.GetFiles(extractPath, "*.pdf",
SearchOption.TopDirectoryOnly);
foreach (string path in filePaths)
{
SendToPrinter(path);
}
}
}
}
}
}
static void SendToPrinter(string path)
{
var printerName = "EPSON L310 Series";
ProcessStartInfo info = new ProcessStartInfo();
info.Verb = "PrintTo";
info.FileName = filePath;
info.CreateNoWindow = true;
info.Arguments = "\"" + printerName + "\"";
info.WindowStyle = ProcessWindowStyle.Hidden;
Process p = new Process();
p.StartInfo = info;
p.Start();
System.Threading.Thread.Sleep(3000);
}
By the way, code which is bottom work but I need to use above
static void SendToPrinter(string path)
{
PdfDocument pdf = new PdfDocument();
pdf.LoadFromFile(path);
pdf.Print();
pdf.Dispose();
}

My console Application is working when double clicking application
It appears that taskscheduler is configured to run under a different account than currently logged in user.
Check the user-account that is configured in the task scheduler to trigger the console app and ensure that its the same account/user that you have logged in to the computer as.
Edit Task > General > Security Options > When running the task use the following account > Select *your* account
If your task is interactive (has a GUI) Checkmark Run only when user is logged on

Related

How to use printer on server [duplicate]

This question already has an answer here:
How to run console application which is send pdf to printer in server?
(1 answer)
Closed 2 years ago.
I download .zip file from outlook then send pdf files to printer. It works on my local machine while compiling, However I setup published app on server, it downloads .zip file from outlook and open it but it can not send to printer . How can I handle that?
This is my code:
static void Main(string[] args)
{
ExchangeService exchange = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
exchange.Credentials = new WebCredentials("mail#", "password");
exchange.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
if (exchange != null)
{
SearchFilter sf = new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));
FindItemsResults<Item> result = exchange.FindItems(WellKnownFolderName.Inbox, sf, new ItemView(1));
foreach (Item item in result)
{
EmailMessage message = EmailMessage.Bind(exchange, item.Id);
message.IsRead = true;
message.Update(ConflictResolutionMode.AutoResolve);
List<Attachment> zipList = message.Attachments.AsEnumerable().Where(x => x.Name.Contains(".zip")).ToList();
foreach (Attachment Attachment in zipList)
{
if (Attachment is FileAttachment)
{
FileAttachment f = Attachment as FileAttachment;
f.Load("C:\\TEST\\" + f.Name);
string zipPath = #"C:\TEST\" + f.Name;
string extractPath = #"C:\TEST\" + Path.GetRandomFileName();
ZipFile.ExtractToDirectory(zipPath, extractPath);
string[] filePaths = Directory.GetFiles(extractPath, "*.pdf",
SearchOption.TopDirectoryOnly);
foreach (string path in filePaths)
{
SendToPrinter(path);
}
}
}
}
}
}
static void SendToPrinter(string path)
{
try
{
var printerName = "EPSON L310 Series";
ProcessStartInfo info = new ProcessStartInfo(path);
info.Verb = "PrintTo";
info.UseShellExecute = false;
info.CreateNoWindow = true;
info.WindowStyle = ProcessWindowStyle.Hidden;
info.Arguments = "\"" + printerName + "\"";
Process p = new Process();
p.StartInfo = info;
p.Start();
p.WaitForInputIdle();
System.Threading.Thread.Sleep(3000);
if (false == p.CloseMainWindow())
p.Kill();
}
catch (Exception ex)
{
Console.WriteLine("error:", ex.Message);
Console.ReadLine();
}
}
As I said, everything is work fine but printer not working. I can print pdf manually I mean machine works. Also this app works on my local machine
You need to change:
info.UseShellExecute = false;
to:
info.UseShellExecute = true;
since the path is a path to a PDF file, not an executable.
As per the docs:
When you use the operating system shell to start processes, you can
start any document (which is any registered file type associated with
an executable that has a default open action) and perform operations
on the file, such as printing, by using the Process object. When
UseShellExecute is false, you can start only executables by using the
Process object.
Additionally:
If you set the WindowStyle to ProcessWindowStyle.Hidden,
UseShellExecute must be set to true.
You are using Hidden - thus UseShellExecute must be true.

Executing Process on a remote Machine c#

i connected over WMI on a remote Machine.
username and password is correctly set.
var options = new ConnectionOptions();
servicePath = "\\\\Testserver\\root\\cimv2";
options.EnablePrivileges = true;
options.Username = username;
options.Password = pwd;
serviceScope = new ManagementScope(servicePath, options);
serviceScope.Connect();
this is the code sequence i want to run on the remote machine
Process process = new Process();
process.StartInfo.FileName = "diskpart.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
process.StandardInput.WriteLine("list volume");
process.StandardInput.WriteLine("exit");
string output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
// extract information from output
string table = output.Split(new string[] { "DISKPART>" }, StringSplitOptions.None)[1];
var rows = table.Split(new string[] { "\n" }, StringSplitOptions.None);
for (int i = 3; i < rows.Length; i++)
{
if (rows[i].Contains("Volume"))
{
int index = Int32.Parse(rows[i].Split(new string[] { " " }, StringSplitOptions.None)[3]);
string label = rows[i].Split(new string[] { " " }, StringSplitOptions.None)[8];
Console.WriteLine($#"Volume {index} {label}:\");
}
}
if i am going to call the process over wmi like this...
object[] theProcessToRun = { "diskpart" };
using (var managementClass = new ManagementClass(serviceScope, new ManagementPath("Win32_Process"), new ObjectGetOptions()))
{
managementClass.InvokeMethod("Create", theProcessToRun);
}
i can call the process, but havent the possibilites to hand over the commands i would like to execute in this process...
How to solve this ?
You can use a script to be passed in as part of the command line arguments that will contain your command.
Reference: https://www.computerhope.com/diskpart.htm
Also you should redirect your output to a file using cmd as you should get your output directly either.
For script, make sure you use a unc that other machine/user has access to. For output file, make sure you use a unc that other machine/user can write to and you can read from via the program.

Cannot start process from IIS

the issue I'm facing is this:
I'm trying to start AcrobatReader from my C# WebApplication using a Process.
https://msdn.microsoft.com/en-us/library/system.diagnostics.process(v=vs.110).aspx
When I'm running the application in IIS Express(running under my default user account) everything goes right and I can open the file I want on Acrobat Reader.
Instead, when I'm trying to deploy on IIS(running under IIS APPPOOL\xxx) the process can't start AcrobatReader.
I've already tried to assign permissions on AcrobatReader to IIS_IUSRS and also to IIS APPPOOL\xxx but nothing change
Tried also to add IIS APPPOOL\xxx to administrators group but no luck
` `ProcessStartInfo info = new ProcessStartInfo();
info.FileName = Constants.ACROBAT_READER_PATH;
info.Arguments = args;
info.Verb = "Printto";
info.CreateNoWindow = true;
info.WindowStyle = ProcessWindowStyle.Hidden;
info.UseShellExecute = false;
info.Domain = Environment.MachineName;
info.UserName = "AdminUser";
string password = "AdminPassword";
System.Security.SecureString securePassword = new System.Security.SecureString();
foreach (char c in password)
securePassword.AppendChar(c);
info.Password = securePassword;
try
{
//The following security adjustments are necessary to give the new
//process sufficient permission to run in the service's window station
//and desktop. This uses classes from the AsproLock library also from
//Asprosys.
IntPtr hWinSta = GetProcessWindowStation();
WindowStationSecurity ws = new WindowStationSecurity(hWinSta,
System.Security.AccessControl.AccessControlSections.Access);
ws.AddAccessRule(new WindowStationAccessRule("AdminUser",
WindowStationRights.AllAccess, System.Security.AccessControl.AccessControlType.Allow));
ws.AcceptChanges();
IntPtr hDesk = GetThreadDesktop(GetCurrentThreadId());
DesktopSecurity ds = new DesktopSecurity(hDesk,
System.Security.AccessControl.AccessControlSections.Access);
ds.AddAccessRule(new DesktopAccessRule("AdminUser",
DesktopRights.AllAccess, System.Security.AccessControl.AccessControlType.Allow));
ds.AcceptChanges();
using (Process process = Process.Start(info))
{
}
}
catch (Exception ex)
{
}
Thank you for your time

How to add authentication property for login to directory path when running batch file in WCF?

I have class in my WCF service to execute batch file. when I test to run the batch file in shared directory, everything is fine, the batch was executed, but when I try to run the batch file from secure diretory, I get error "ACCESS DENIED". How to add login property so I can access my secured directory to execute my batch file?
here is my code:
public string ExecuteBat()
{
string hasil = "";
ProcessStartInfo processInfo = new ProcessStartInfo(#"D:\Secure\command.bat");
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = false;
Process process = Process.Start(processInfo);
process.WaitForExit();
if (process.ExitCode == 0)
{
hasil = "BAT EXECUTED!";
}
else
{
hasil = "EXECUTE BAT FAILED";
}
return hasil;
}
The ProcessStartInfo class has properties for Domain,UserName and Password that, when set, start the process under those credentials, something like this:
ProcessStartInfo processInfo = new ProcessStartInfo(#"D:\Rpts\SSIS_WeeklyFlash_AAF_1.bat");
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = false;
processInfo.Domain= "MyCompanyDomain";
processInfo.UserName = "username";
//Secure string is an odd beast, so you need something like this:
SecureString ss = new SecureString();
string password = "p#$$w0rd";
foreach (char c in password)
{
ss.AppendChar(c);
}
processInfo.Password = ss;
...

How can i run as another user an app

I know that this is question was already asked but i couldn't find any answer . I have this code i'm trying to run an app with a specific user but gives error that file could not be found even if the file is there.
static void Main(string[] args)
{
System.Diagnostics.ProcessStartInfo myProcess = new System.Diagnostics.ProcessStartInfo("cinegy.exe");
myProcess.WorkingDirectory =Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)+ "\\Cinegy\\Cinegy Workflow 8.5.8\\";
System.Security.SecureString password = new System.Security.SecureString();
string uspw = "mypass";
foreach (char c in uspw)
{
password.AppendChar(c);
}
myProcess.UserName = "myuser";
myProcess.Password = password;
myProcess.Domain = "mydomain";
myProcess.UseShellExecute = false;
try
{
System.Diagnostics.Process.Start(myProcess);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.ReadLine();
}
}
}
Thanks
Error is |The system cannot find the file specified|
If you use
UseShellExecute = false
it ignores WorkingDirectory
You can either set UseShellExecute to true and have a cmd shell. Or you add the location of the process to path of the process you are running:
string path = System.Environment.GetEnvironmentVariable("path");
path += ";" + Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86) + "\\Cinegy\\Cinegy Workflow 8.5.8\\";
System.Environment.SetEnvironmentVariable("path", path);

Categories