How to open cmd from windows service? - c#

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?

Related

Execute Powershell script from C# with administrator privilege and permissions

I'm traying to execute a Powershell script through C# with administrator privilege.
I've tryied in many ways but with no results.
The best I can do is start a process (System.Diagnostics.Process.Start(p)) with runas Verb. This way, if the user that execute the service is an administrator, I can run my powershell script.
But, what i need is to execute the service with a low privilege user, and, when needed, "login" with the administrator and execute the powershell script.
I've tryied to Impersonate the administrator, but it didn't worked...
The answer Execute PowerShell as an administrator from C# didn't solve the problem, I still can't run my script. The answers are from 2009, i hope someone had solved this kind of issue in the meantime.
// powershell script execution
var processInfo = new System.Diagnostics.ProcessStartInfo
{
Verb = "runas",
LoadUserProfile = true,
FileName = "powershell.exe",
Arguments = scriptPath,
RedirectStandardOutput = true,
UseShellExecute = false
};
var p = System.Diagnostics.Process.Start(processInfo);
Impersonation should work. However, I usually avoid it as I don't like storing user credentials if I don't have to.
I ran into a need for something similar to this in an application I'm working on.
The app runs in IIS and most of the time doesn't need (and shouldn't have) full administrator access.
To deal with this scenario, I have a separate application running (a windows service) that has full admin privileges.
It accepts request from the IIS application and executes the appropriate administrative function.
My IIS app and Windows Service talk over AMQP (with RabbitMQ). However, you could easily use whatever communication channel you prefer - HTTP, TCP, or even just create a file and have the admin application look for the file.

Launch a command shell from a console application run via Windows Task Scheduler

I have a Windows console application that is launched via a schedule setup in Task Scheduler. This console application, as part of its normal runtime, will launch a command prompt in order to run a java program. No, I have no control over the design of the Java program. It was supplied to me as is and I have no rights or access to make changes to it. I also cannot implement it in another language. I must use what was given to me.
At any rate, when my console application tries to run the command prompt it will work just fine if I'm launching the application manually. However, when I try it as an action within Task Scheduler, my console application will start and run as expected until it needs to launch the command prompt. At this point, the console application exits. No error message or code is provided.
How do I get the command prompt window to start as a new window from within my console application when no one is logged into the server?
Thanks for any hints or suggestions you can provide.
* UPDATE *
Here is the code snippet that launches the program from within my console application:
string parameter_save_path = #"C:\output\folder"
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo start_info = new System.Diagnostics.ProcessStartInfo();
start_info.WorkingDirectory = #"C:\mtselect-client";
start_info.FileName = "cmd.exe";
start_info.Arguments = "/C run.bat \"" + parameter_save_path + "\"";
process.StartInfo = start_info;
process.Start();
process.WaitForExit();
The run.bat is what launches the java program.
I think it's too late for this message, but...
Maybe in your batch file you are running your java application with something like: java -jar ApplicationName
First I would do should be comment out the "#echo off" from the batch file, next trace out the batch lines with one echo "x" (being x a natural number starting from 1 and increasing by 1 in each ocurrence). Next I will add a line with java -version, and so I will be sure java app is installed and accesible.
Maybe java needs be ran by an authenticated user and so have java_home defined. Maybe the application needs some JVM parameters like memory size, etc.
Have good luck, tell me and I will try to help

Invoke console app from windows service

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.

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.

Process.Start() not spawning new process under the same user

I was always under the impression that when you're running a process as (domain\user) mydomain\myuser, when using Process.Start() it would start this new process using the same credentials - mydomain\myuser.
The issue I'm having is that my Process.Start() call seems to be creating a process under the SYSTEM account which is causing me permission issues in the started process (which must run under an admin account due to the work it does). If it changes things - I'm spawning this process (a custom built exe) from within a windows installer.
Any suggestions? I've read about windows group policies (possibly) having an impact on this, but if I'm honest, it's lost on me.
EDIT: a little snippet:
Where exename and commandLine are parameters for this method body:
ProcessStartInfo procInfo = new ProcessStartInfo(exeName, commandLine);
procInfo.WorkingDirectory = workingDirectory;
procInfo.UseShellExecute = false;
procInfo.CreateNoWindow = true;
Process process = Process.Start(procInfo);
Process.WaitForExit();
return process.ExitCode;
Either set procInfo.UseShellExecute to true, or execute cmd as a process with your exe as a parameter to the cmd command. When UseShellExecute is set to false, here are a lot of interesting side effects: UseShellExecute
Your impression is true. Process.Start() will always start the new process under current user's credentials - unless you provide alternative credentials in the ProcessStartInfo or use one of the overloads that take credentials.
There must be another problem - share a snippet of your code.
UPDATE
OK! You did not mention anything about installer. All MSI installers will be running under system since they will be run by "Windows Installer" which you can check and they run under SYSTEM.

Categories