I have a file watch service, written in C#, that I need to launch an application when it detects the file drop. I am using notepad as a test application to launch. The file watcher is working fine, but I cant get notepad to launch. Any assistance with what I am missing would be great.
Code that fires when the file drop is detected:
public void FileCreated(object source, FileSystemEventArgs inArgs)
{
Process LaunchApp = new Process();
LaunchApp.StartInfo.FileName = ConfigurationManager.AppSettings["AppStartPath"];
LaunchApp.Start();
// Process.Start(ConfigurationManager.AppSettings["AppStartPath"]);
Log.WriteLine(" File added: " + DateTime.Now + " " + inArgs.FullPath);
}
Path reference from the app.config:
<add key="AppStartPath" value="Notepad.exe"/>
I also tried:
<add key="AppStartPath" value="C:\Windows\System32\Notepad.exe"/>
I have a file watch service,
Services run in a separate security context to processes in a user logon session.
This can be seen if you add the Session ID column to Task Manager's Processes tab, or – better, in Process Explorer.
Any processes the service launches will run in the service's own context: not the user. There are very good security reasons for this.
To perform interactive operations from a service you need a per user agent that is run in the user's context. Typically the service listens on a named pipe and the user agent is run from the startup group (or Run key in the registry). The agent connects to the named pipe and can respond to requests from the service (or the service from the user agent).
Related
I'm trying to get a UI ( browsers like chrome, firefox, IE, ... ) running using a web application.
When i use the following code (on my local machine and on a server)
Process.Start(#"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe");
Process.Start(#"C:\Program Files (x86)\Mozilla Firefox\firefox.exe");
Process.Start(#"C:\Program Files\Internet Explorer\iexplore.exe");
in a console application this is no problem. All three start up with no issues.
class Program
{
static void Main(string[] args)
{
Process.Start(#"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe");
...
}
}
When i try this from a controller method, this does not work.
public class MyController : Controller
{
public ActionResult QuickStart()
{
Process.Start(#"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe");
...
}
}
If i start my own custom executable it does run ( my test executable writes a file to the disk ) but it doesn't show the console that it is supposed to. )
From what i've found this is because the system doesn't have any context as for what user this ui would have to be shown ? So i tried impersonating every possible user ( doesn't work because impersonating isn't the same as getting the current session as a logged in user ? ) and i've tried starting the process for every possible WindowsIdentity possible and yet still notting happend.
Does anyone know what i could do to make this work ?
Whenever your app uses other credentials it creates a new session. To get round this you would need to make a small systray type app so you can login as some account and run this app which listens for commands from your service, and then pops up on that session whatever it is you need it to, and it will be visible to the user that intermediary app runs as.
We have a Windows Service that checks a configuration file, and based on those settings, starts a new Process (let's call this ClusterProcess) which connects to a database and does the actual functionality.
There is a test project, that cuts out the Windows Service's part in the play, and just provides ClusterProcess with the necessary settings.
For our current test environment, we have the database on a cloud and I would say, rather restricted permissions.
My problem is this: when I run the test project, ClusterProcess gets its settings and things happen on the database. However, when I run the Windows Service, nothing gets changed on the database.
I've been using log4net to try and see where things fall over, but it seems to fail silently.
So the Windows Service calls this:
_ClusterRunnner.StartAllClusters();
In this method mentioned above, this is (amongst other things) what happens, and I get both log statements:
_ClusterProcesses = new List<Process>();
log.Debug("Cluster Name: " + cluster.Name + " ConfigPath: " + _ConfigPath);
_ClusterProcesses.Add(Process.Start(startInfo));
log.Debug("After process spawn.");
Okay, so the Process that it should start is ClusterProcess.exe, and in the Main method of that project I don't get any of the log statements that should be given, for instance:
log.Debug("Going to Start Processing");
_ClusterProcessor = new ClusterProcessor(config);
_ClusterProcessor.StartProcessing();
log.Debug("Finished Processing");
With log4net I have a special logger for ClusterProcess.exe (two appenders, a RollingFileAppender and an AdoNetAppender) and similar appenders for the Windows Service. (The Windows Service process holds a lock to its RollingFileAppender, so I had to create a special one for ClusterProcess.exe. The AdoNetAppenders are for nicely formatted logs after the connection to the database has been made.)
But now, the test project just calls this directly:
ClusterProcessor x = new ClusterProcessor(config);
x.StartProcessing();
and it works! I get the log statements in StartProcessing() and the database is changed.
So any ideas?
From my experience with services they run with very limited rights.
So if your Test(possible windows application) runs perfectly then I guess it has something to do with user rights.
I guess you can't realy access the filesystem so if your logger writes to a place on the harddrive you should think about the windows event log --> Write to Windows Application Event Log without registering an Event Source
To try if it has something to do with user rights just open your service in the windows service settings and let it log on as your administrator account and see if it has something to do with this.
Background:
I created a service that will trigger the execution of an application when certain conditions have been met. This service is setup to run under the same windows user account that is used to log on to the system via RDP. I also created the .NET application that is trigger via this service. This application looks for a configuration file on disk (found in the ProgramData folder for the application) uses the settings found in the configuration file to affect the output of this application.
Problem:
When the application is ran by the user interactively the application runs great. However when the service triggers the application to run it appears that the application is not loading the correct values from the configuration files. It's almost as though the application when ran from a service has its own configuration file, and is not using the one found in ProgramData.
I'm just looking for some insight to why this may be happening. I have seem some odd behavior from Windows 7 and Windows 2008 R2 when running applications via scheduled tasks or as a service. It's almost like interactive applications and service applications have different environments on the same system running as the same user...
Note: The service executable is also found in the same folder as the triggered application. I would expect that the working directory by default would be the services running directory.
public int ExecRun()
{
Process proc = new Process();
proc.StartInfo = new ProcessStartInfo
{
FileName = "C:\\Program Files\\TEST\\runme.exe",
Arguments = "/DS:TEMP"
};
proc.Start();
proc.WaitForExit();
return proc.ExitCode;
}
Try adding the working directory info:
Process proc = new Process();
proc.StartInfo = new ProcessStartInfo
{
FileName = "C:\\Program Files\\TEST\\runme.exe",
WorkingDirectory="C:\\Program Files\\TEST",
Arguments = "/DS:TEMP"
};
It sounds like the service that triggers the execution of the application also needs to set the working directory. If you're using the Process class, you'll need to set the StartInfo.WorkingDirectory property the path where your application resides.
This has been solved.
Unfortunately, I think I wasted all your time with this question. The users is running this service on a second system (other than the one they claimed was having this issue). They copied the same configuration to both systems which would've been fine if they had setup both systems the same way, but alas they did not. The file did not exist on the system throwing the error, but both systems were setup to log exceptions to the same location.
The user had to disable the second service, or setup the configuration file correctly.
I have a small Windows Forms application that needs to be able to run an external application an unlimited number of times without closing that application after each run.
The external application runs as a single instance and is very resource hungry and slow to load. The basic workflow is as follows:
1: Wait for a trigger to load the external app
2: Trigger raised, open the external app with a command line reference
3: Monitor a log file
3: External app processes the command line data and writes to the log file
4: Log file changed, so send next command line to (already open) external app
5: Go to step 3
The problem I have is that I cannot find a way of loading the external application without first closing/killing the process.
applicationProcess.StartInfo.FileName = commandLine;
applicationProcess.Start();
// Watch for change in log file and then...
applicationProcess.StartInfo.FileName = commandLine;
applicationProcess.Start();
and so on, but if I don't
applicationProcess.Kill();
before I re-issue the applicationProcess.Start() method I get a thread exception.
I think what I need to do is to disconnect from the applicationProcess once it has started, but cannot find any mechanism to do this.
Any advice/direction would be much appreciated.
Thanks.
If you intend to launch a new instance of your external application, then just allocate a new Process() object. Create one Process() object each time you launch your external application, rather than trying to re-use the original one.
If you intend to manipulate an existing instance of your external application, one that you already launched, then you don't need to call Start() again, just continue using applicationProcess.
Does it work when you create a new applicationProcess and keep the old ones in a List or something simmilar?
I have found a solution to this problem by creating a batch file launches the application. The workflow is as follows:
1: My application launches the batch file with a command-line argument
2: The batch file runs-re-runs the main application
3: My application kills and disposes of the process.
Step 3 simply closes the process that is running the batch file, not the main application process - which I need to stay open.
The batch file couldn't be simpler:
#echo off
"C:\Program Files (x86)\Microsoft Office\Office14\Excel.exe" %1
I have run this on a loop for over one hour and have found no problems.
I need to call a console application to load data into another desktop application on the remote server that located within the corporate domain.
Users will enter the web page and upload data to asp.net web server, which after transformation should call that console application. Users are located remotely and do not have any other access except the web server.
I decided to lower the security web application context and let the asp.net working process to start the console application on the current IIS 6.0 web server
What I have done:
I changed the security account for the application pool for Local System;
I added ASPNET Account and IIS_WPG IIS Process Account to Administrators group;
I added “Allow service to interact with desctop” for “IIS Admin Service” and “World Wide Web Publishing Service” processes and restarted the machine;
I tried to start BAT-file at server side through the test page code-behind, but failed:
protected void btnStart_Click(object sender, EventArgs e)
{
Process process = new Process();
process.StartInfo.FileName = #”C:\run.bat”;
process.StartInfo.UseShellExecute = false;
process.Start();
process.WaitForExit();
}
The error was access denied.
Please help me to find any workable idea how to start the bat-file at web server side.
Thanks
Try setting UseShellExecute to true instead of false. After all, batch files run in a shell - so you need a shell to execute it. (Another option is to run cmd.exe and pass the name of the batch file in as an argument, e.g. "cmd.exe /k c:\run.bat")
You might also want to try creating a simple .NET app which just (say) creates a file with a timestamp in. That way you can test the "can I start another process" bit separately from the "can I get the batch file to work" bit.
Put that particular batch file in your application itself.
string str_Path = Server.MapPath(".") + "\\run.bat";
ProcessStartInfo processInfo = new ProcessStartInfo(str_Path);
processInfo.UseShellExecute = false;
Process batchProcess = new Process();
batchProcess.StartInfo = processInfo;
batchProcess.Start();
Take a look at this example: Run Interactive Command Shell or Batch Files From ASP.NET
It uses little different approach. They suggest running cmd.exe and executing command line by line.