I am trying to automate updating some data on my server. Windows Server 2008 R2.
There are asp.net core 2.1 application that has code below
var timeoutMs = 5000;
var process = new Process();
process.StartInfo.FileName = exePath;
process.StartInfo.Arguments = arguments;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.Start();
return process.WaitForExit(timeoutMs));
And here comes tricky part.
When I use exePath=svn.exe arguments=update "someWorkingFolderPath", process hangs and returns false after timeout (regularly update from cmd takes like couple of milliseconds)
Then repository corrupts and locks itself (because update does not exited correctly) and when I run 'svn update' on cmd it tells me to call svn cleanup.
!AND! When repository in this locked state, process with same argumentsdoesn't hang (because of same svn errot), until I run cleanup that breaks locks on working folder. Then it hangs again.
Calling 'svn log "folderPath"' also hangs process. Anytime
As you can see I am not redirecting any streams, I can run all this commands successfully manually from cmd. Application pool starts from same local administrator identity which I am using for cmd (not perfect, I know, but that's not a subject). I am using svn command line tools that comes with TortoiseSVN.
What may cause such problems?
Days later I found out where the problem was and how to solve.
Actually is kinda of simple mistake, but still it made me struggle, so just in case I post this answer
After running "svn auth" from my service, I learned that there was no credentials cache loaded. There is setting in Application Pool in IIS7 "Load user profile" and it was set to false in my situation. After setting it to true (and restarting the pool), svn loaded my credentials cache and all worked just fine.
I have no guess why svn does not time out on "svn update" without credentials cache after half an hour, if there were a proper error message, I would've sort it out faster
Related
Its hard to place everything in the title, but I hope I can explain this as good as I can. Basicly I made a C# Console Application that reads a certain file every now and then. The Application runs on a Virtual Machine from Google Instances. Now I have created another Console Application that is capable of managing the other application, like closing them or restarting the executables.
The Issue:
When I start the Console Application by hand (manual), it works fine and reads the files like it should. I could close and open this as much as I like and it still works. The problem is when my second Console Application tries to restart the first Console Application. The restart works fine and most functions like certain ftp connections work, but it stops reading files and gives a null back as result. There happen to be no debug errors nor does it display an error on the console.
What I want is that the second application could restart my first application without making it run where some functions appear to be blocked.
The Code I use:
string loc = File.ReadAllText(Directory.GetCurrentDirectory() + "\\"+ "location.txt");
Process p = new Process();
p.StartInfo.FileName = loc;
p.StartInfo.UseShellExecute = true;
p.Start();
I tried running it as p.StartInfo.Verb = "runas"; but this has no positive result either. Could this be an issue with the Google Virtual Machine, possible firewall settings or code related issues.
Extra
This code does work on my own laptop and so does it work after restarting.
Hi fellow software developers
So I need to start a CMD process in my .NET MVC web project. This is my function that I pass the command I need to call:
private void ExecuteCommandSync(string command)
{
System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);
// Hide the CMD window:
procStartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
// The following commands are needed to redirect the standard output.
procStartInfo.UseShellExecute = true;
// Now we create a process, assign its ProcessStartInfo and start it
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
proc.WaitForExit();
}
The command calls a program that starts a linear programming framework that solves a problem which takes 20 seconds to finish.
The problem is that nothing happens when this function is called! It works fine outside the IIS, but not in IIS. The IIS web server runs on a Windows Server 2012. My web project is called from outside of our local network, where the web server is running, does some work, calls my synchronous method and waits for it to finish and ends by returning the result of the call as a JSON object.
This question suggests that it might have something with user privileges. In the Application Pools for the web project in Advanced Settings -> Identity I have tried to change from ApplicaitonPoolIdentity to Local System (which has high privileges) but no luck (as explained here).
Does anyone have any suggestions to how I can solve this problem? Any advice would be greatly appreciated.
you must run project pool under user have privilege's to execute exec.
I am trying to run an antivirus scan on an uploaded file in an ASP.Net web app. We are using Sophos so have access to their command line API sav32cli. In the code I use:
Process proc = new Process();
proc.StartInfo.FileName = #"C:\Program Files (x86)\Sophos\Sophos Anti-Virus\sav32cli.exe";
proc.StartInfo.Arguments = #"-remove -nc " + SavedFile;
proc.StartInfo.Verb = "runas";
proc.Start();
proc.WaitForExit();
int exitCode = proc.ExitCode;
When stepping through the code, when attached to the w3wp process on dev server, the code just jumps from one line to the next seemingly doing nothing at all. When running from code on dev server, it performs as expected scanning file and deleting if it is seen as a virus.
The server is running IIS 8.0, and the app built in .Net Framework 4. I have changed the machine config to allow the process to run as SYSTEM account, in accordance to these instructions. https://support.microsoft.com/en-us/kb/317012#%2Fen-us%2Fkb%2F317012
<processModel userName="SYSTEM" password="AutoGenerate" />
Is there something I'm missing? What is the best practice for this kind of implementation?
EDIT: When called, the Process returns an ExitCode of 2 (Error stopped execution), rather than the expected 0 (Scan worked, no viruses), or 3 (Scan worked, viruses found).
EDIT 2: As per comment below I changed the code to:
Process proc = new Process();
proc.StartInfo.FileName = #"C:\Program Files (x86)\Sophos\Sophos Anti-Virus\sav32cli.exe";
proc.StartInfo.Arguments = #"-remove -nc " + SavedFile;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proc.Start();
StringBuilder output = new StringBuilder();
while (!proc.StandardOutput.EndOfStream)
{
string line = proc.StandardOutput.ReadLine();
output.AppendLine(line);
}
proc.WaitForExit();
int exitCode = proc.ExitCode;
ASPxMemo2.Text = exitCode.ToString() + Environment.NewLine + output.ToString();
output is always empty when run over IIS, but is populated correctly when running from code.
EDIT 3: Instead of looking at StandardOutput we looked at StandardError and it revealed this error:
Error initialising detection engine [0xa0040200]
(Possible insufficient user Admin rights.)
For the time being we are going to move to another method of virus checking, but would still like to know a possible solution if anyone has it.
You will need to make sure that the application pool that is running your .NET application inside IIS has execute permissions to your file
"C:\Program Files (x86)\Sophos\Sophos Anti-Virus\sav32cli.exe"
You may also need to add this permission to the folder location where the file to be scanned is uploaded (c:\temp) for example
You may also need to have administrator privileges to run the anti virus scan since IIS8 does not run as an administrator. When you are debugging visual studio uses your current logged in windows user(unless you use runas) so this will explain why it would work when debugging.
Have you tried running your web process in elevated trust?
Configuring .NET Trust Levels in IIS 7
<system.web>
<securityPolicy>
<trustLevel name="Full" policyFile="internal"/>
</securityPolicy>
</system.web>
ASP.NET Trust Levels and Policy Files
Most likely the permissions are not configured correctly on the content being scanned (the uploads folder) or the worker process user doesn't have the full permissions it needs to use Sophos. You know the executable itself is accessible by the worker process because you are getting exit codes and error messages that are specific to Sophos.
Because your process will delete files that are perceived as threats you need to grant the user running the process modify or full control permissions on the folders that store the uploaded files.
By default you could use the IIS_IUSRS group for ApplicationPoolIdentity processes, but you can verify (and modify) the user in IIS Manager > App Pools > Advanced.
This answer has more details
Here are some ideas:
Create the process using a different user with elevated privileges on the folder, see for reference start-a-net-process-as-a-different-user
If the previous suggestion fails, login one time on the server using the credentials used in point 1. It will configure registry entries connected to the user profile, some programs requires it.
Develop a simple .net service running on the server and monitoring the upload folder. The service has more probability running the Sophos scan succesfully. Here is a reference on service creation using .net.
The service may also talk to your web page using DB/file system/ etc.. so the operation may seem synchronous.
These are my 4 cents :-)
I made new project (ASP.NET MVC Web Application) using Visual Studio Web 2013 Express Edition. Loading index page, redirects and everything works fine, except that in some part of my code I need to create Process and execute it, wait for it to finish, parse output of that external application and show that output to the user. However I get nothing. While debugging the code line by line:
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = Tool;
info.Arguments = filename + " " + avArray;
info.CreateNoWindow = true;
info.UseShellExecute = false;
info.RedirectStandardOutput = true;
Process p = new Process();
p.StartInfo = info;
p.Start();
p.WaitForExit();
Process exits immediately, someone would say it is pretty fast program, but application needs at least 5 seconds (sometimes 20 seconds) to complete.
What I think is happening is that process is not created in the first place, as my IIS settings or whatever other settings are not allowing me to run this EXE. What do I do to change this?
I've been trying to this for the past 2 weeks, I've read probably every post about it, and tried every solution suggested. I am choosing to write on this post since it is the most recent.
First of all, I am using VS2013, testing on IIS Express, and then on IIS 8.5., the webpages version is 3, and the target framework 4.5. And I am assuming that (as with my case) the goal is to launch the process on the server.
What I learned:
Using IIS Express should allow you to run the process without problems. You can try to allow it to launch the window, or start your process through the shell just to be sure that it is actually launching (a shell window should popup and close). If this happens, verify that you are giving the correct path to to your program, etc. So far so good.
Going into the IIS 8.5 is a totally different matter. Theoretically, the bad way of doing it should be preatty straight-forward: you create an app-pool for that server, give it a high privileged account (local system or network system, for instance); go to AdministrativeTools->Services->IIS, LogOn tab, and allow interaction with the desktop. You should be able to do the same as in IISExpress, but in my case is just the same as with a low privilege account.
I actually started by trying just to use impersonation, but also was not able to launch the process with IIS8.5. EDIT: I retried this again today, and the api won't even run if I enable impersonation.
I've spent more time than I would like with this, any input on why I can't get this to work properly with IIS8.5 (#clzola: IIS Express should do the job) is very welcome.
I have created a windows service that checks a database for errors and if a specific one shows up I want it to perform an IISRESET command.
The problem is, if I run and IISRESET command without the elevated privileges then it won't actually do the reset. So I have my code doing all I want, but I'm not sure if the IISRESET command is being run as an administrator and I don't know how to verify that.
Here is the code I have
ErrorCheckerEventLog.WriteEntry("Performing IISReset", EventLogEntryType.Warning);
Process process = new Process();
process.StartInfo.Verb = "runas";
process.StartInfo.FileName = "iisreset.exe";
process.StartInfo.UseShellExecute = true;
process.StartInfo.CreateNoWindow = false;
process.StartInfo.RedirectStandardError = false;
process.StartInfo.RedirectStandardOutput = false;
process.Start();
process.WaitForExit();
ErrorCheckerEventLog.WriteEntry("IISReset finished", EventLogEntryType.Information);
In the Application event log I get these:
Listener Adapter protocol 'net.tcp' successfully connected to Windows Process Activation Service.
Listener Adapter protocol 'net.pipe' successfully connected to Windows Process Activation Service.
In the system event log I get these:
IIS start command received from user testing\neil.kenny. The logged data is the status code.
It all looks good to me, but I'm still not sure it actually did the reset. It could have just ran the iisreset command which then output the access denied message.
How do I properly verify this?
If you want to test it manually:
First thing come to my mind is keep the browser open with any site on the IIS being reset. Press F5 all time. Site will go down and soon will be up again.
Check in event viewer and look for event entries indicating IIS has been restarted (Check System logs). This question might help. here you have a pic. One image is better than thousand words:
What to look for exactly:
Several events indicating that some services has been stopped. Source is Service Control Manager. Among them look for the one saying "The World Wide Web Publishing Service entered stopped state"
Event from source IIS-IISReset with content "IIS stop command received from user xxxx"
Several events indicating that some services has been started. Source is Service Control Manager. Among them look for the one saying "The World Wide Web Publishing Service entered running state"
Event from source IIS-IISReset with content "IIS start command received from user xxxx"
Just a thought ... depending on your requirements you could do something like ...
1.
Call up a web page or wcf endpoint that lives on a site hosted on the iis instance that you wrote to put something in the application state.
2.
Run your code.
3.
Call it again with params telling it to retrieve the application variable, if its null and takes a while chances are that app got reloaded due to an iisreset.
Not ideal if your code has nothing to do with the apps hosted on the box so then I figured ... why not just retrieve that event log information?
There's an example of that on this: Read event log in C# ... question, admittedly a very simple one but you're looking in a specific time period that was very recent and logs read from the most recent down, thus rendering your search very quick (e.g. should be in the top say 100 events on the busiest of servers).