Executing msbuild process through code gets exit code -1073741502 - c#

My application is executing MsBuild.exe using Process.Start(); running as another user. The process is running as a service. When executing the process instantly fails and returns an error code -1073741502.
I am executing my code as a service.
No matter what user, or permissions I grant this occurs (Even as Administrator).
The service user has both the Local Security Policy to Run as a service and Impersonate another user
No matter what my logging methods are not called. Does this means it's failing before it even starts?
Other executables have no problem executing in this manner.
When not executing my code as a service it executes successfully.
WTF is the negative error code 1073741502??(!!) Closest thing i've found is this.
Example code:
void Main(){
var startInfo = new ProcessStartInfo
{
FileName = path,
Arguments = args,
WorkingDirectory = workingPath,
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
LoadUserProfile = true,
Domain = System.Environment.MachineName,
UserName = creds.Username,
Password = generateSecureString(creds.Password)
};
var process = Process.Start(startInfo);
process.OutputDataReceived += process_OutputDataReceived;
process.ErrorDataReceived += process_OutputDataReceived;
process.Exited += process_Exited;
process.EnableRaisingEvents = true;
process.WaitForExit();
}
internal void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
Console.WriteLine(e.Data);
}
void process_Exited(object sender, EventArgs e)
{
var process = ((Process) sender);
Console.WriteLine("Process has finished execution, exit code '{0}'.", process.ExitCode);
}
private SecureString generateSecureString(string password)
{
var secure = new SecureString();
foreach (var c in password.ToCharArray())
{
secure.AppendChar(c);
}
return secure;
}
Any help would be really appreciated. Seems to be a permissions/local security policy issue, but without knowing more it feels like i've reached the "definition of insanity" point of my troubleshooting where i'm just repeating the same actions expecting a different result.
When investigating the Event logs I see the following exception (vague as hell):
Faulting application name: msbuild.exe, version: 12.0.31101.0, time stamp: 0x545443d5
Faulting module name: KERNELBASE.dll, version: 6.3.9600.17668, time stamp: 0x54c846bb
Exception code: 0xc0000142
Fault offset: 0x0009e052
Faulting process id: 0x3e8
Faulting application start time: 0x01d065cdac34cc77
Faulting application path: C:\Program Files (x86)\MSBuild\12.0\Bin\msbuild.exe
Faulting module path: KERNELBASE.dll
Report Id: ecce8b9d-d1c0-11e4-80d7-00155d611ee6
Faulting package full name:
Faulting package-relative application ID:

According to this thread ( Why is this process crashing as soon as it is launched? ), starting a process from a service may result in the native CreateProcessWithLogonW API call which seems to be not working from a service.
I just found this thread because I think I'm facing a similar issue but with the powershell start-process commandlet running in a service (which probably make use of CreateProcessWithLogonW internally.

Related

Microsoft.CognitiveServices.Speech is not calling endpoint

I am trying to throw together a proof of concept project, just to see how good Microsoft's Cognitive Services Speech Transcription is.
I have followed all the examples on their site, but have so far been unsuccessful. Initially I was unable to get it to run at all under one of my existing code bases as x86, it was throwing the error:
An attempt was made to load a program with an incorrect format
Then I created a brand new .net framework x64 console app. And it would start, then crash internally using version 1.4.0 as well as a few other versions I tried and put this error into my event log:
Faulting application name: dotnet.exe, version: 2.1.27415.1, time
stamp: 0x5c672873 Faulting module name:
Microsoft.CognitiveServices.Speech.core.dll, version: 1.3.1.28, time
stamp: 0x5c764ab1 Exception code: 0xc0000094 Fault offset:
0x000000000007567c Faulting process id: 0x6200 Faulting application
start time: 0x01d4f1518c240c4b Faulting application path: C:\Program
Files\dotnet\dotnet.exe Faulting module path:
C:\Users\username.nuget\packages\microsoft.cognitiveservices.speech\1.3.1\runtimes\win-x64\native\Microsoft.CognitiveServices.Speech.core.dll
Finally I found version 1.1.0 which would actually start, (version 1.0.0 would not even allow the app to compile). Now I am running into the issue that the SessionStarted and SessionStopped events are called instantly, but no transcription ever takes place, and using Fiddler it looks like no calls are being made outside of my machine.
Unless Cognitive Services is really buggy, then there must be something simple I am missing. Can anyone point it out?
My goal is to transcribe a 5 minute or less audio file on my local network. Here is the code I am attempting.
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
var file = #"U:\path\file.wav";
ContinuousRecognitionAsync(file).Wait();
Console.WriteLine("End!");
}
public static async Task ContinuousRecognitionAsync(string audiopath)
{
// subscription key and service region. Replace with your own subscription key
// and service region (e.g., "westus").
var config = SpeechConfig.FromSubscription("<my free test key>", "westus");
var audio = Microsoft.CognitiveServices.Speech.Audio.AudioConfig.FromWavFileInput(audiopath);
// Creates a continuos speech recognizer using WAV input.
using (var recognizer = new SpeechRecognizer(config, audio))
{
//Subscribes to events.
recognizer.Recognizing += (s, e) =>
{
Console.WriteLine($"\n Recognizing: {e.Result.Text}.");
};
recognizer.Recognized += (s, e) =>
{
Console.WriteLine($"\n Recognized: {e.Result.Text}.");
};
recognizer.SessionStarted += (s, e) =>
{
Console.WriteLine($"\n SessionStarted: {e.SessionId}.");
};
recognizer.SessionStopped += (s, e) =>
{
Console.WriteLine($"\n SessionStopped: {e.SessionId}.");
};
recognizer.SpeechEndDetected += (s, e) =>
{
Console.WriteLine($"\n SpeechEndDetected: {e.SessionId}.");
};
recognizer.SpeechStartDetected += (s, e) =>
{
Console.WriteLine($"\n SpeechStartDetected: {e.SessionId}.");
};
recognizer.Canceled += (s, e) =>
{
Console.WriteLine($"\n Canceled: {e.SessionId}.");
};
// Starts continuous recognition. Uses StopContinuousRecognitionAsync() to stop recognition.
Console.WriteLine("Say something...");
//await recognizer.StartContinuousRecognitionAsync().ConfigureAwait(false);
await recognizer.StartContinuousRecognitionAsync().ConfigureAwait(false);
Console.WriteLine("Press any key to stop");
Console.ReadKey();
await recognizer.StopContinuousRecognitionAsync().ConfigureAwait(false);
}
}
EDIT: After some changes, and moving the wav file locally (it was on a mapped drive), it did briefly try to run a transcription on the file, but no valid text was ever returned, only blank strings.
Transcription via microphone is working just fine. But as soon as I throw one of my .wav files at it Cognitive Services is once again crashing with the Exception code: 0xc0000094. I even tried the code that half worked, and that is also throwing the same error now.
I figured out the issue, it turned out to be the .wav files themselves. As near as I could tell, they were valid wave files. With WAV listed at the top of the binary file if you looked at it in Notepad++. However, they consistently caused Cognitive Services to crash. And the one time I got it to take one, it was unable to read it and just started running in an infinite loop returning blank strings.
I solved the issue by running the files through a double conversion. I converted them to .m4a files, then back to .wav files. Once I did that they all started working perfectly.
I originally thought it was because I was storing the files remotely on a mapped drive. However, access via mapped drive worked just fine once the files were fixed.
Hopefully Microsoft will add better error handling to the Cognitive Services wrapper. And allow the API to handle more than just wav file types.

IIS hosted WCF service is not able to start a process

I have a WCF service on a server,when I send a request from client application, the service will run a process to communicate with network nodes,this process is critical in my service and if it doesn't run the entire service is useless. the problem is this process never runs :(
I have been reading solutions for about two days but none of them helped me , I have give the service administrator privileges and check if the .exe file path is correct here is my code any help would be appreciate.
try
{
myprocess.StartInfo.UseShellExecute = false;
myprocess.StartInfo.CreateNoWindow = true;
myprocess.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
myprocess.StartInfo.RedirectStandardOutput = true;
myprocess.StartInfo.FileName = myprocessPathAndName;
myprocess.StartInfo.WorkingDirectory =
Path.GetDirectoryName(myprocessPathAndName);
myprocess.StartInfo.Arguments = ConfigName;
myprocess.Start();
Log("myprocess Runnig " , sw);
Log(myprocessPathAndName, sw);
Log(myprocess.StartInfo.WorkingDirectory, sw);
}
catch (Exception e)
{
Log("Failed to run myprocess : " + e.Message, sw);
}
here is the log
7/26/2017 4:05:15 AM : myprocessRunnig
7/26/2017 4:05:15 AM : C:\inetpub\wwwroot\Station\COM\Dn\myprocess.exe
7/26/2017 4:05:15 AM : C:\inetpub\wwwroot\Station\COM\Dn
First:
Check the return value of your myprocess.Start() method call. If the process has started successfully, it would return true. Log the return value.
Process.Start()
Second: (you may be already doing this)
After the process has started, you should have to have a wait call for the process to run and complete.
Process.WaitForExit()
Third:
How do you determine that the process has not started ? Are you able to check the process in Task Manager ? It is possible that the process is starting and failing. Is there any log created by your process ? Have you checked the event log ?
Fourth:
Does your process have any UI component ? Do note that when running as a Service (in Windows Vista and later), the service cannot show a UI. It would just hang.
Fifth:
Are you able to manually run your process with the same user ID as your Service ? You can use RunAs or PsExec to run your process under the appropriate user ID.
Sixth:
You can redirect the standard error as well and read from it to see whether your process has written any exception
e.g.,
process.StartInfo.RedirectStandardError = true;
string errResult = process.StandardError.ReadToEnd();
You can log the result and check it.
Seventh:
You should also log the exit code of your process
process.WaitForExit();
var exitCode = process.ExitCode;

why my web service is unable to process request after handling 2000 requests successfully?

My web service will convert doc, text and pdf files into flash files using print2flash software, but it's working fine for approximately 2000 requests after that it is not proceesing,I'm getting operation time out error message.If I restart the machine the service is working fine for another 2000 requests.
Can anyone help me what could be the reason?and how to resolve this issue?
here is my code where I'm getting the problem.
Print2Flash3.Server2 obj = new Print2Flash3.Server2();
Print2Flash3.BatchProcessingOptions batchProcess = new BatchProcessingOptions();
batchProcess.BeforePrintingTimeout = 60000;
batchProcess.AfterPrintingTimeout = 10000;
batchProcess.PrintingTimeout = 120000;
batchProcess.ActivityTimeout = 30000;
batchProcess.KillProcessIfTimeout = ThreeStateFlag.TSF_YES;
batchProcess.ApplyChanges();
obj.ConvertFile(inputFilename, outputFullPath, null, batchProcess, null);
This is my error log information
The User Profile Service has started successfully.
Windows Management Instrumentation Service started sucessfully
Event code: 3001 Event message: The request has been aborted. Event
time: 10/31/2013 12:15:25 PM Event time (UTC): 10/31/2013 12:15:25 PM
Event ID: c0911a4071c940c580fc3d75d3c36f6e Event sequence: 2826
Event occurrence: 1 Event detail code: 0 Application information:
Application domain: /LM/W3SVC/1/ROOT/code-17-130276759869328000
Trust level: Full
Application Virtual Path: /code
Application Path: C:\inetpub\wwwroot\code\
Machine name: server Process information:
Process ID: 1048
Process name: w3wp.exe
Account name: server\Administrator Exception information:
Exception type: HttpException
Exception message: Request timed out.
Request information:
Request URL: url
Request path: path
User host address: server
User:
Is authenticated: False
Authentication Type:
Thread account name: server\Administrator Thread information:
Thread ID: 13
Thread account name: server\Administrator
Is impersonating: False
Stack trace:
this is the error message that I'm getting continuously.
There are several causes to this also Kirk Woll has added some good points.
1.There might be an infinite loop which causes the service to hang
Ex. exception handling method calls the same method for exception handeling.
Check EventLogs in EventViewer to get these kind of error if any.
2.Memory leak, may be your application is not releasing the memory after use.
Close any unwanted connection, dispose unused object after your work is done.
Try any memory leak tool
Suggestion:
If the above two situation fails then you can automate recycling the application pool for the service.
EDIT:
try the following.
obj.ConvertFile(inputFilename, outputFullPath, null, batchProcess, null);
//not sure if your object has similar methods or not but you can give it a try.
obj.Close();
obj.Dispose();
or use the using style.
using(Print2Flash3.Server2 obj = new Print2Flash3.Server2())
{
Print2Flash3.BatchProcessingOptions
batchProcess = new BatchProcessingOptions();
batchProcess.BeforePrintingTimeout = 60000;
batchProcess.AfterPrintingTimeout = 10000;
batchProcess.PrintingTimeout = 120000;
batchProcess.ActivityTimeout = 30000;
batchProcess.KillProcessIfTimeout = ThreeStateFlag.TSF_YES;
batchProcess.ApplyChanges();
obj.ConvertFile(inputFilename, outputFullPath, null, batchProcess, null);
}
EDIT2:
obj.ConvertFile(inputFilename, outputFullPath, null, batchProcess, null);
obj = null; //As the object is not disposable, you need to release the memory
//manually.
If Print2Flash3.Server2 is a custom class then derive it from IDisposable interface and implement the Dispose method.
public class Server2 : IDisposable
{
....
....
public void Dispose()
{
this = null;
}
}

Running a Windows Scheduled Task from ASP.net

I have a Windows scheduled task that runs a database import process every hour, but I'd like users to be able to kick it off out-of-schedule by hitting a button in an ASP.net dashboard (running in IIS6 on Windows Server 2003).
The following works perfectly in code-behind ...
var proc = new Process
{
StartInfo =
{
UseShellExecute = false,
FileName = #"C:\Windows\System32\schtasks.exe",
Arguments = "/run /tn Loader",
RedirectStandardError = true,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
proc.Start();
proc.WaitForExit();
... but only if the application pool identity is set to Local System (not ideal!). If I leave it as Network Service, the task does not start. So it is presumably a permissions issue.
Is there a way ASP.net can kick off a scheduled task on the server without running the application as Local System? If not, what good alternatives are there?
Update: if nobody on SO knows, I guess it is not possible so I will go with my idea of having my web application write requests to a database table (doubling as an audit log) and creating a second task to poll that table and kick off the main task.
Update your schedule task to trigger off a specific event. Then have your website log that event when the button is clicked - thus starting your scheduled task.
Ex:
In my installer I create an event log source for my program, since creating the source requires administrative privileges (you can also use the command line to create the source)
if (EventLog.SourceExists("MyApp"))
{
EventLog.CreateEventSource("MyApp", "Application");
}
Then in my application, I create an event log entry when the button is clicked.
private void btnOpenOtherApp_Click (object sender, EventArgs e)
{
try
{
var log = new EventLog
{
Source = "MyApp"
};
log.WriteEntry("Start MyOtherApp", EventLogEntryType.Information, 1337);
}
catch (Exception ex)
{
...
}
}
And the task scheduler set to open MyOtherApp when the event is logged.
You need an administrator user in windows. This code will help you to call the task:
var securePass = new System.Security.SecureString();
foreach (char c in "my_password")
{
pass.AppendChar(c);
}
var proc = new Process
{
StartInfo =
{
UseShellExecute = false,
FileName = #"C:\Windows\System32\schtasks.exe",
Arguments = "/run /tn Loader",
UserName = "myAdminUser", //NEW
Password = securePass, //NEW
RedirectStandardError = true,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
proc.Start();
proc.WaitForExit();
If your application needs to run as SYSTEM Account you can use this arguments:
If the /RU username and /RP Password parameters match the currently
logged-in user, the task will run interactively (visible in the
foreground).
For the system account, /RU username can be written as "", "NT
AUTHORITY\SYSTEM" or "SYSTEM", a Password is not required. The system
account has full access to the local machine but has no permissions on
any other machines (or mapped drives) across the Network.
Source: http://ss64.com/nt/schtasks.html
You can utilize the cache of ASP.NET to run schedule tasks. I personally used this and it worked like charm. Ofcourse it has some limitation (Accuracy) but you can adjust/change.
https://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/
Regards
If using a 3rd party scheduler service such as Quartz.NET is not an option, and changing permissions is not allowed either (not a good idea in any case) another possibility is to to write a helper Windows service as a bridge between ASP.NET application and Windows scheduler. You would store list of tasks in a DB and a sequence of events would be something like this:
When you need to run a task, from ASP.NET GUI you set flag in the DB for that task
Helper service runs on schedule to check the DB at given intervals - sees the flag, starts the task, reset the flag.
Oh and there're libraries out there (e.g. http://taskscheduler.codeplex.com/ and others) that wrap Window Task Scheduler, so you don't have to execute them directly, but rather in a nice managed way.

How can I execute a batch script in a windows service in C#?

I'm trying to execute a .bat script in a C# windows service but it doesn't seem to be working.
So the script I am trying to execute, startup.bat, in turn calls another script, call catalina.bat ..., which in turn executes start java ...
I can execute startup.bat manually but I want to run it as a Windows service. When I try to do that in a C# windows service application, nothing seems to happen. My Windows service code looks like this:
public class MyService : ServiceBase
{
public static void Main(string[] args)
{
ServiceBase.Run(new MyService());
}
protected override void OnStart(string[] args)
{
base.OnStart(args);
this.RunScript(#"bin\startup.bat");
Thread.Sleep(1000);
}
protected override void OnStop()
{
base.OnStop();
this.RunScript(#"bin\shutdown.bat");
Thread.Sleep(1000);
}
private void RunScript(string processFileName)
{
var startInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = "/C " + Path.Combine(#"C:\server", processFileName),
CreateNoWindow = true,
ErrorDialog = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
UseShellExecute = false,
WindowStyle = ProcessWindowStyle.Hidden
};
startInfo.EnvironmentVariables.Add("CATALINA_HOME", #"c:\server");
var process = new Process();
process.StartInfo = startInfo;
process.Start();
}
}
I don't understand why this doesn't execute. What am I doing wrong?
And yes, you may notice I'm trying to launch Tomcat on Windows as a service with C#. Well I'm doing that because I haven't been able to use tomcat7.exe for various reasons but it's probably better to not ask why I'm doing such things. Whatever the reason is, what I'm doing here should also work, shouldn't it?
Update in response to Gabe's suggestion:
If I set UseShellExecute = true I get an exception:
System.InvalidOperationException: The Process object must have the UseShellExecute property set to false in order to redirect IO streams.
at System.Diagnostics.Process.StartWithShellExecuteEx(ProcessStartInfo startInfo)
at System.Diagnostics.Process.Start()
at MyService.RunScript(String processFileName)
So I set RedirectStandardError and RedirectStandardOutput to false, which yields this error:
System.InvalidOperationException: The Process object must have the UseShellExecute property set to false in order to use environment variables.
at System.Diagnostics.Process.StartWithShellExecuteEx(ProcessStartInfo startInfo)
at System.Diagnostics.Process.Start()
at MyService.RunScript(String processFileName)
argh! I feel exasperated!
Run "cmd.exe" and pass "startup.bat" as an argument.
To close the loop on this, the problem was indeed Windows security permission issues.
The suggestion made here seemed to resolve my issue.
Try setting "Allow service to interact with desktop" in your service setting.
Possible duplicate - Run Batch-Files in Windows Service while logged off
If your script runs fine as an interactive user but not as a service then there are a couple of obvious possible causes:
Your service is running under a user account that is unable to perform the actions in the script.
Your script tries to interact with the desktop but can't because of session 0 isolation.
These suggestions are essentially guesses but with so little information it's hard to do better.
Try:
FileName = "%comspec%",
Arguments = "/C " + Path.Combine(#"C:\server", processFileName),

Categories

Resources