Invoke console app from windows service - c#

I have a simple windows service which i need to use to invoke a console application.The console app generates pdf to print by opening the adobe reader window.Running the console app works fine to print pdf.But invoking it from service not successful.It doesnt even show up the console window where i log events.
Process pdfprocess = new Process();
pdfprocess.StartInfo.FileName = #"C:\Documents and Settings\xyz\Desktop\dgdfg\PdfReportGeneration\bin\Debug\PdfReportGeneration.exe";
pdfprocess.StartInfo.UseShellExecute = false;
pdfprocess.StartInfo.RedirectStandardOutput = true;
pdfprocess.Start();
But invoking other application like
pdfprocess.StartInfo.FileName = #"C:\Program Files\Adobe\Reader 11.0\Reader\AcroRd32.exe";
works fine.
What will be the reason?

There is probably some permissions issue there (PdfReportGeneration.exe inaccessible under service account or maybe something that it uses...)
I would advise to capture Process Monitor log to see where exactly it fails.

Windows services run in a different window station and cannot interact with the desktop, unless you're using an older version of Windows and tick a checkbox in the service properties in the service manager.

Related

How to open cmd from windows service?

I am creating a Windows Service and using C#. I want open cmd.exe from the service. My operating system is Windows 8. Is it possible from a Windows Service, or is there another alternative for that.
(I want to open cmd.exe after some interval - that's why I chose a windows service)
This won't work. Problem is that you are trying to show UI (Console) from a Windows Service and Windows Service is not running in the context of any particular user. Starting from Vista and later OS Windows Services are running in an isolated session and are disallowed to interact with a user or desktop making it impossible to run.
Depending on what you need there are two solutions to this problem.
If you want the cmd to be opened you might consider using a task scheduled action from Windows Task Scheduler and then perform your actions
If you need just to execute some actions with the cmd.exe, for example copy file, that does not require the UI to be displayed then you can achieve that with the following
Start cmd without creating a window:
ProcessStartInfo processInfo = new ProcessStartInfo
{
WindowStyle = ProcessWindowStyle.Normal,
CreateNoWindow = true,
UseShellExecute = false,
FileName = "cmd.exe",
Arguments = #"/C copy /b Image1.jpg + Archive.rar Image2.jpg"
};
For the further details please check following links:
How can I run an EXE program from a Windows Service using C#?
How can a Windows Service start a process when a Timer event is raised?

Process.Start won't work

I am trying to launch a process from a web page's back-end code/app pool. This process will launch an App that i built myself.
For some reason, the process only works / runs when i start it from VS2013... it never works when i launch it from IIS(7.5) itself.
I am on a Windows 7 machine (both IIS host, and App location), and I've setup my web site to only be accessible via internal network.
Here's the code, followed by the config / attempts to fix the issue:
protected void btn_DoIt_Click(object sender, EventArgs e)
{
string file_text = this.txt_Urls.Text;
if (!String.IsNullOrWhiteSpace(file_text))
File.WriteAllText(ConfigurationManager.AppSettings["filePath"], file_text);
ProcessStartInfo inf = new ProcessStartInfo();
SecureString ss = GetSecureString("SomePassword");
inf.FileName = #"........\bin\Release\SomeExecutable.exe";
inf.Arguments = ConfigurationManager.AppSettings["filePath"];
inf.UserName = "SomeUserName";
inf.Password = ss;
inf.UseShellExecute = false;
//launch desktop app, but don't close it in case we want to see the results!
try
{
Process.Start(inf);
}
catch(Exception ex)
{
this.txt_Urls.Text = ex.Message;
}
this.txt_Urls.Enabled = false;
this.btn_DoIt.Enabled = false;
this.txt_Urls.Text = "Entries received and process started. Check local machine for status update, or use refresh below.";
}
Here are the things I've tried to resolve the issue:
Made sure the executing assembly was built with AnyCPU instead of
x86
Ensured that the AppPool that runs the app, also runs under the same account (SomeUsername) as the ProcessStartInfo specified.
Ensured that the specific user account has full access to the executable's folder.
Ensured that IIS_USR has full access to the executable's folder.
Restarted both the app pool and IIS itself many times over implementing these fixes
I am now at a loss as to why this simply will not launch the app... when i first looked into the event log, i saw that the app would die immediately with code 1000:KERNELBASE.dll, which got me on the AnyCPU config instead of X86 fix... that fixed the event log entries but the app still doesn't start (nothing comes up in task manager), and i get no errors in the event log...
if someone could help me fix this problem i would really appreciate it. This would allow me to perform specific tasks on my main computer from any device on my network (phone, tablet, laptop, etc etc) without having to be in front of my main PC...
UPDATE
The comment to my OP, and ultimate answer from #Bradley Uffner actually nailed the problem on the head: My "app" is actually a desktop application with a UI, and in order to run that application, IIS would need to be able to get access to the desktop and the UI, just like if it were a person sitting down in front of the PC. This of course is not the case since IIS is running only as a service account and it makes sense that it shouldn't be launching UI programs in the background. Also see his answer for one way of getting around this.
Your best bet might be to try writing this as 2 parts. A web site that posts commands to a text file (or database, or some other persistent storage), and a desktop application that periodically polls that file (database, etc) for changes and executes those commands. You could write out the entire command line, including exe path command arguments, and switches.
This is the only way I can really think of to allow a service application like IIS to execute applications that require a desktop context with a logged in user.
You should assign a technical user with enough high priviliges to the running application pool. By default the application pool is running with ApplicationPoolIdentity identy which has a very low priviliges.

IIS 7 Print in not working

I am trying to print a document which is working fine in my Visual studio 2010 application but when i am publishing my project on IIS 7 then printing is not working and i cant see any error in the event viewer .
MyProcess = new Process();
MyProcess.StartInfo.CreateNoWindow = false;
MyProcess.StartInfo.Verb = "print";
MyProcess.StartInfo.FileName = destinationPath;
MyProcess.Start();
MyProcess.WaitForExit(10000);
MyProcess.Close();
When you're running in Visual Studio, you're running as a logged-in, interactive user.
When you're running in IIS, well, you're not any of the above.
The way this is normally done in a web application is to:
Display the document to the user in the browser
Print the document by using the 'window.print' function from JavaScript.
If anyone still cares for an answer..
I had the same problem, solution was to give IIS user access to use installed printers on the computer. When you print from IIS , you're logged in as a system default user who by default doesn't have proper printer access setup in the registry.You need to give printer access to the default system user by adding few entries in the registry. Just follow this tutorial like I did http://support.microsoft.com/?kbid=184291.
It will fix it.
If the printer is not installed on the server, nothing is going to happen.
If you're trying to print from ASP.NET code to a printer attached to the client computer it's never going to work. The server cannot get to and use any resources on the client computers.
2nd and important thing change to LoadUserProfile to true in IIS Application pool.

c# Open IE From Scheduled Task

I have a c# console application that I want to run from task scheduler that has 2 main functions: 1) Closes all Internet Explorer processes; and 2) Restarts Internet Explorer and loads the appropriate website.
The console app does exactly what it is supposed to do if run from the command line, but fails if executed from Task Scheduler.
The app is designed to run on the client computer the only function of which is to load a single website and broadcast the website to our internal TV Channel 195. We have connection issues with our ISP and while the connection issue is usually temporary, Internet explorer needs to be restarted to re-show the website.
I want to set it up to run multiple times each day to eliminate any possible connection issues between the web server and the client.
private static void StartExplorer()
{
Process _process;
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = "iexplore.exe",
Arguments = "-noframemerging -private -k \"http://tv.TheelmAtClark.Com\""
};
try{
_process = Process.Start(psi);
}
catch(Exception Ex)
{
Console.WriteLine(Ex.ToString());
}
}
Is it possible to run the app using task scheduler?
I would recommend that you look at alternative approaches, if possible.
A Firefox plugin like Reload Every is designed to do just this. I use this in our to project to a big screen TV.
However, if you are keen on doing this via Internet explorer, again there are two approaches
1) Something similar to the Firefox plugin I mentioned above - Autorefresher for IE
2) If you insist on having a task scheduler, as you mentioned above, here is how I think you can do it-
To kill all Internet Explorer instances, use PSKill. Invoke it via Process.Start with arguments to kill Internet Explorer.
To launch a new instance, try invoking Process.Start with UseShellExecute=true.

Launching a Desktop Application with a Metro-style app

Is there a way to launch a desktop application from a Metro-style app on Windows 8? I'm trying to create some simple shortcuts to desktop applications to replace the desktop icons on the start screen, which look out of place.
I just need something super simple, preferably in C#, to open an application as soon as the app loads. I'm planning on making these shortcuts for some games, photoshop, etc, not anything I've made myself. They're also just for personal use, so I can use direct paths to applications like "C:\Program Files (x86)\Steam\steamapps\common\Skyrim\TESV.exe"
If you simply want to run a desktop application like (notepad, wordpad, internet explorer etc) then go through Process Methods and ProcessStartInfo Class
try
{
// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.FileName = "C:\Path\To\App.exe";
p.Start();
}
// Exp 2
// Uses the ProcessStartInfo class to start new processes,
// both in a minimized mode.
void OpenWithStartInfo()
{
ProcessStartInfo startInfo = new ProcessStartInfo("IExplore.exe");
startInfo.WindowStyle = ProcessWindowStyle.Minimized;
Process.Start(startInfo);
startInfo.Arguments = "www.northwindtraders.com";
Process.Start(startInfo);
}
On Windows 8 Metro application i discovered this: How to Start a
external Program from Metro App.
All the Metro-style applications work in the highly sand boxed
environment and there is no way to directly start an external
application.
You can try to use Launcher class – depends on your need it may
provide you a feasible solution.
Check this:
Can I use Windows.System.Launcher.LauncherDefaultProgram(Uri) to invoke another metro style app?
Ref: How to launch a Desktop app from within a Metro app?
Metro IE is a special app. You cannot invoke an executable from Metro style apps.
Try this - I have not test yet but may be it will help you..
Launcher.LaunchFileAsync
// Path to the file in the app package to launch
string exeFile = #"C:\Program Files (x86)\Steam\steamapps\common\Skyrim\TESV.exe";
var file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(exeFile);
if (file != null)
{
// Set the option to show the picker
var options = new Windows.System.LauncherOptions();
options.DisplayApplicationPicker = true;
// Launch the retrieved file
bool success = await Windows.System.Launcher.LaunchFileAsync(file, options);
if (success)
{
// File launched
}
else
{
// File launch failed
}
}
I found a solution which is suitable for me. I just made an empty textfile in my app and called it launcher.yourappyouwanttostart and then executed it with
Windows.System.Launcher.LaunchFileAsync("launcher.yourappyouwanttostart");
On the first startup it asks you for the assocation for this file and then you choose the exe file you want to run and from now on every time you execute this file, your app will be started.
I haven't actually tried if it works and it's not really a beautiful solution, but I guess Metro-style apps can launch a URI.
You could then create a desktop-program that is registered for a custom URI scheme that would then do the actual program launching.
What you can do is host external WCF service on your computer with separate installation and connect to it from metro style application using localhost. Then you can do pretty much anything including Process.Start.
I love simple things, so my solution was to use this:
Process.Start("explorer", "shell:AppsFolder\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe!App")
This will start the "new" Sticky Notes coming with Anniversary Update to Windows 10, but it works with all other "Metro" apps I tested.
To find the name of the metro app, from Windows Explorer you have to find it in shell:appsfolder using the AppUserModelId column.

Categories