Getting the output of .exe program in IIS under windows server 2012 - c#

We have our own C++ compiled OCR as .exe file that takes the image location as a parameter and return a string, and we place it in folder within our web-API 2 application folder, now we start the OCR as a process from the web-api, get the output and return it back.
everything works good in a local machine, when we deploy the API in the server, the output cannot be retrieved unless we replace the Application pool identity with the Admin in the application pool. At this stage we need to use the Application pool identity (or any other user but the admin) and still be able to retrieve the output from the process here is our code:
ProcessStartInfo info = new ProcessStartInfo
{
WorkingDirectory = enginepath,
CreateNoWindow = true,
UseShellExecute = false,
FileName = enginepath+"//"+"OCR.exe",
RedirectStandardOutput = true,
Arguments = " "+imageFilepath
};
using (Process process = Process.Start(info))
{
using (StreamReader reader = process.StandardOutput)
{
string result = reader.ReadToEnd();
return result;
}
}
we tried all the popular ways from giving the right permissions,loading the user profile=true, and still can't be able to retrieve the output.
*we need to be able to get the output within the web server application.

Related

C# EFS, Windows Encrypt Or Dycrypt Fails when Impersonated

I need to write a file while impersonated as another user John (Member of administrator).
What happens:
File is written and created, then all Access Control is removed and added (Full Control).
No matter where in this process i try to Encrypt file access is denied
using FileOptions
Using File.Encrypt.
my worked around to at least encrypt was with opening another impersonation later on.
But No matter what i do, i can't Decrypt or even read the encrypted Text file.
If file is encrypted reading or decrypting fails, even though i can read or write just fine while impersonated.
In some scenarios Everything works fine, But after a system restart or logout, again fails with access denied.
For impersonation i used this answers Impersonation
using (impersonate = new ImpersonateUser(ImpersonationType.WinIdentity, Domain, User, SecurePassword))
{
System.Diagnostics.Debug.WriteLine($"Before Impersonation: {Environment.UserName}");
done = impersonate.RunImpersonated(() =>
{
System.Diagnostics.Debug.WriteLine($"After Impersonation: {Environment.UserName}");
//if (Util.IsWindowsEncrypted(ConfigFullPath)) File.Decrypt(ConfigFullPath);
var json = File.ReadAllText(ConfigFullPath);
var configFile_data = SerializationUtil.Deserialize<Config>(json);
//if (!Util.IsWindowsEncrypted(ConfigFullPath)) File.Encrypt(ConfigFullPath);
});
}
A working repository to reproduce is available here Repository containing full sample,
See CreateConfig or ReadConfig method in Config.cs
(if you were able to create and read a encrypted file, check if after
restart it is the same)
A Workaround i just found was to create a Process before doing any impersonation.
using (Process cmd = new Process())
{
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = $"/c",
UseShellExecute = false,
UserName = user,
Password = pass,
LoadUserProfile = true
};
cmd.StartInfo = startInfo;
cmd.Start();
}

Seeing console output of a sub process started by a .net application

My application creates a set of sub processes that runs in the background. These processes all have logging both to file and to console. Is it posssible to open up cmd and see the console output of a process after it has been created outside of cmd?
var p = new Process
{
StartInfo =
{
FileName = path,
Arguments = arguments,
WindowStyle = ProcessWindowStyle.Hidden
}
};
p.Start();
You can't access the console of the sub-process, but you can redirect the output (stdout and stderr, ideally), and pipe them to your own console/display. An example of redirecting stdout of a sub-process is shown in full on MSDN

How to execute Git commands using cmd.exe being called from another application?

I have an application that generates some files. Once the files are generated, i want to then perform some Git commands to start a local repository. I have spent a few days on multiple solutions and endless googling but i can't get this to work as expected.
If i manually kick off the .exe, locally or on a server, it works perfectly. However, when the application(MVC) calls the .exe it doesn't work locally or on a server. I will provide the code that calls the .exe itself and then what the .exe code is doing.
MVC call to run .exe
//Call git exe
var processInfo = new ProcessStartInfo()
{
Arguments = Arg1 + " " + Arg2,
UseShellExecute = false,
FileName = #"C:\Foo.exe"
};
var process = new Process()
{
StartInfo = processInfo
};
process.Start();
process.WaitForExit();
This .exe gets launched without issue so this part is working i think. I checked it via task manager.
Git command execution
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
RedirectStandardInput = true,
UseShellExecute = false,
WorkingDirectory = Properties.Settings.Default.OutPutDirectory
},
};
process.Start();
using (var writer = process.StandardInput)
{
writer.WriteLine("git init");
writer.WriteLine("git add --all");
writer.WriteLine("git commit --author=\"" + ParseUserNameFromEmail() + " <" + _userEmailAddress + ">\" -m \"Initial Commit\"");
}
If i execute this part manually from the cmd prompt it works perfect on both local and server. But as soon as this .exe is called from an MVC app, it runs but the git repo isn't created as expected. I am at a total lost. I have tried running the process with my creds and a service account. I have also tried capturing the output in hope to shed light on what the issue could be but it's just empty on error and output redirects :(.

Printing a PDF from ASP .Net (c#) using Acrobat Reader

I am trying to print a PDF using ASP (C#) through Adobe Reader -the problem is it does work on my local machine but not on server. On my local it starts Adob eReader in minimized state and I can see the file present inside Printer's "See what's printing" window. But on the server I can see the process has started from Task Manager but there's no UI visible as well no file in printer's list.
I though it may be a permission issue but after trying the following steps - it still does not work.
What I have tried.
As by default it runs under DefaultAppPool user - so I created a new App pool under the admin user, it now starts the process under admin but still I can't see the UI and no output on printer.
I added permission "Allow service to interact with desktop" to IIS Admin Service following this article https://support.microsoft.com/en-us/help/555134 - but no difference.
My current code
string args = string.Format("/s /o /h /t \"{0}\" \"{1}\"", filepath, printerName);
var startInfo = new ProcessStartInfo {
FileName = Properties.Settings.Default.AdobeReaderPath,
Arguments = args,
CreateNoWindow = true,
ErrorDialog = false,
UseShellExecute = false,
Verb = "print",
WindowStyle = ProcessWindowStyle.Minimized,
RedirectStandardInput = true,
RedirectStandardOutput = true
};
var process = Process.Start(startInfo);
In the Application Pool Advanced settings, make sure you set the option
"Load User Profile" to True on the server.

How can i pass values from a C# form into Python

I am using Visual C# as UI and Python in the background.
Enter the details on a visual C# form.
Clicking a button should run a Python program which should embed the details given in the form into an XML file.
Python should process the XML and ingest into a system.
Python should monitor for the success from logs and return back the value to be displayed in C# form.
Is this possible?
You could start your python in a new process in the background and pass the form items as arguments in the process start information as if you were running the python script from the command line, like so:
var start = new ProcessStartInfo
{
FileName = _pathToPythonExecutable,
Arguments = string.Format(" {0} --arg1 {1}",_pathToYourPythonScript, //formItemValue),
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardInput = true,
RedirectStandardError = true,
WorkingDirectory = _currentWorkingDirectory
};
using (Process process = Process.Start(start))
{
// Do stuff
}
You'll see that in my start information, I have told the process to Redirect StandardInput, Standard Output and Standard Error. This is another way that you can pass data between the processes.
You would write to standard input like so:
process.StandardInput.Write(input);
process.StandardInput.Close();
Standard output and Standard Errors are streams, so you can read them like so
// This would be the same for standard error
using (StreamReader reader = process.StandardOutput)
{
result = reader.ReadToEnd();
}

Categories

Resources