Commands missing on command-line started from IIS 8.5 - c#

I've used a IHttpHandler that compiles SASS files with compass since IIS 7.5. Ever since upgrading to windows 8.1 and IIS 8.5, it's not been working and responds with the follow message:
/*-----------------------------------------------------------------------------------------------
//
// compass compile "theme/default/style/custom.sass" --trace --debug-info --css-dir "data/compass"
//
// 'compass' is not recognized as an internal or external command,
// operable program or batch file.
//
//---------------------------------------------------------------------------------------------*/
Here the portion code that executes the process (ref Dado.Compass.SingleFileHandler.cs):
void IHttpHandler.ProcessRequest(HttpContext context)
{
// Gather Compass Configuration Variables
ReadConfiguration(context);
string baseDir = Path.GetDirectoryName(context.Request.Path).Replace(#"\", "/");
string fileName = Path.GetFileName(context.Request.Path);
string command = String.Format(#"compass compile ""{0}"" --trace --debug-info --css-dir ""{1}""",
(baseDir + "/" + fileName).Trim(new char[] { '\\', '/' }),
_cachePath.Trim(new char[] { '\\', '/' })
);
ProcessStartInfo psi = new ProcessStartInfo()
{
FileName = "cmd.exe",
WorkingDirectory = context.Server.MapPath("~/"),
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
Arguments = "/c " + command
};
using (Process process = new Process { StartInfo = psi }) {
bool hasError = false;
...
I'm running under ApplicationPoolIdentify and have given the same permissions. Also, compass is available when I try to execute it the command from cmd.exe.
Why does the command appear from the IIS instance of the cmd.exe?

I don't know if this is a new setting in Window 8, but it seems there is now a User Path variable and this is the variable that was referencing compass. However, the IIS process worker is the ApplicationPoolIdentity, so it will not receive my User's Path specification.
The solution is to move the referencing location from the User Path variable to the System Path variable.

Related

Run executable in a silent mode

I am executing .exe file in C# using the code below.
If I want to run executable in a silent mode I usually uncomment UseShellExecute and RedirectStandardOutput properties, but this gives me an error:
Unhandled Exception: System.ComponentModel.Win32Exception: The system cannot find the file specified
If I keep a code like this it runs, but the additional command line screen is popping up and closing.
I am running Poisson Surface Reconstruction .exe and wondering if the silent mode is possible or not? Or it must be implemented by author who did this executable?
var proc = new System.Diagnostics.Process {
StartInfo = new System.Diagnostics.ProcessStartInfo {
FileName = "PoissonRecon",
Arguments = "--in " + fileNameIn + " --out " + fileName + " --depth "+depth.ToString()+" --pointWeight 0 --colors",
//UseShellExecute = false,
//RedirectStandardOutput = true,
CreateNoWindow = true,
WorkingDirectory = filePath
}
};
proc.Start();
proc.WaitForExit();
Try adding to arguments line this:
"--mode unattended"
if I'm not mistaken it should make installation silent

How to call a console app as a different user, using a Windows service being run under Local System?

I am basically trying to create and run a Windows Service on a server. This service has mainly 2 jobs,
To log a timestamp to a file on a UNC (different Server path) so as to check access
Call a simple console app using a different user
Now, I have created the windows service, but it won't log in the Server path as it is started via Local system. So I tried to deploy it using a user account with access to the Server Path and it logged, but then the whole point is to us the local system.
So now, i changed the requirement a little bit, Now is it possible to deploy the service as Local System only , but instead of directly logging on the server path, i would rather make the console app do the logging. But how should I make the console app run as a different user account.
This is the code I am using for calling the console app via a different user (mind you the service is run under LocalSystem), and it is either giving the error, "Cannot find the file specified" or "Invalid Directory Name" but i assure you both the things exist. I even used the paths fed in the startInfo by debugging to check.
public static void InitiateCommandProcess()
{
Process process = new Process();
SecureString ssPwd = new SecureString();
string fileName = ConfigurationManager.AppSettings["FileName"];
string workingDirectory = ConfigurationManager.AppSettings["ApplicationDirectory"];
string param = ConfigurationManager.AppSettings["PARAM"];
string userName = "myUserName";
string password = "MyPassWord";
for (int x = 0; x < password.Length; x++)
{
ssPwd.AppendChar(password[x]);
}
ProcessStartInfo startInfo = new ProcessStartInfo
{
UseShellExecute = false,
WindowStyle = ProcessWindowStyle.Hidden,
CreateNoWindow = true,
ErrorDialog = false,
FileName = #"" + fileName,
WorkingDirectory = #"" + workingDirectory,
Arguments = #"" + param,
RedirectStandardOutput = true,
RedirectStandardError = true,
RedirectStandardInput = true,
Domain = "EMEA",
UserName = userName,
Password = ssPwd
};
process.StartInfo = startInfo;
try
{
Logger.Log($"Working in Directory Path : {workingDirectory} );");
Logger.Log($" Username : {userName} and Executing : {fileName}");
process.Start();
Logger.Log($"Process \"{ConfigurationManager.AppSettings["FileName"]}\" Executed at {DateTime.Now}");
}
catch (Exception ex)
{
Logger.Log($"Error occured in command process execution, Message : {ex.Message}", true);
}
}
The server path is like this, "\dfs\folder\folder..."
I am a little new to this so please bear with me.

Trying to transpile a js file in wpf c# project

I'm attempting to call Process.Start to invoke Babel and transpile a js file in my c# project.
I've installed babel into a directory "ES6" using the command:
npm install babel-preset-es2015 --save-dev
the directory C:\ES6\node_modules.bin now has a babel and babel.cmd file
Now I'm attempting to transpile a js file using Process.Start and redirecting the std out to capture the results I can use:
string babelFileName = #"C:\ES6\node_modules\.bin\babel";
var startInfo = new ProcessStartInfo {
FileName = babelFileName,
Arguments = " --presets es2015 " + ViewModel.EditorViewModel.JSFullFilePath,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false
};
string js = ViewModel.EditorViewModel.Javascript;
using (var process = Process.Start(startInfo)) {
var standardOutput = new StringBuilder();
// read chunk-wise while process is running.
while (!process.HasExited) {
standardOutput.Append(process.StandardOutput.ReadToEnd());
}
int exitCode = process.ExitCode;
// make sure not to miss out on any remaindings.
standardOutput.Append(process.StandardOutput.ReadToEnd());
string stdout = standardOutput.ToString();
js = string.IsNullOrEmpty(stdout) ? js : stdout;
}
I've tried to invoke bable using "bable." to get around the missing ".exe" extension but no luck. I get the following exception:
The specified executable is not a valid application for this OS platform.
Hoping someone can point out how I can properly invoke babel to do this.
**UPDATE
I took a look at babel.cmd since this command line does transpile correctly:
C:\ES6\node_modules.bin>babel someES5.js --presets es2015
babel.cmd:
#IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\..\babel-cli\bin\babel.js" %*
) ELSE (
#SETLOCAL
#SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\..\babel-cli\bin\babel.js" %*
)
And modified my C#:
string babeljs = #"C:\ES6\node_modules\babel-cli\bin\babel.js";
var startInfo = new ProcessStartInfo {
FileName = "node.exe",
Arguments = babeljs + " " + ViewModel.EditorViewModel.JSFullFilePath,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
This does essentially echo the un-transpiled js code verbatim. If I now add " --presets es2015 " to the arguments, the process completes successfully but with empty output.
What do I need to add here to get transpiled js from this node.exe process?

c# System.Diagnostics.Process Does Not Do Anything or Throw Error

I wonder if someone can please help me understand why my Process is not working, nor generating an error.
The code below should loop through a directory, find all files with an sqb extension and for each file run a Process as a user account which has elevated privileges on the server.
The process should run an executable sqb2mtf.exe from the same folder as the files are located with an argument such as sqb2mtf.exe file.sqb file.bak for example purposes.
If I use Visual Studio 2013 and step through the code I can see each file being looped through and the Process appears to fire, but no files are converted, nor any errors presented to the variable readToEndError.
var directory = new DirectoryInfo(#"D:\inetpub\Import\");
foreach (var file in directory .EnumerateFiles("*.sqb"))
{
var convert = Path.GetFileNameWithoutExtension(file.ToString());
var process = new Process
{
StartInfo =
{
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardInput = true,
RedirectStandardError = true,
FileName = #"D:\inetpub\Import\sqb2mtf.exe",
UserName = "myUserName",
Domain = "myDomain",
Password = GetSecureString("myPassword"),
Arguments = #"D:\inetpub\Import\" + file + " " + #"D:\inetpub\Import\" + convert + ".bak"
}
};
process.Start();
string readToEndOutput = process.StandardOutput.ReadToEnd();
string readToEndError = process.StandardError.ReadToEnd();
process.WaitForExit();
}
I am going out of my mind, any advice to resolve this would be much appreciated :-)
Update
var directoryInfo = new DirectoryInfo(BackupDirectory);
foreach (var file in directoryInfo.EnumerateFiles("*.sqb"))
{
var convert = Path.GetFileNameWithoutExtension(file.ToString());
var fileName = BackupDirectory + "sqb2mtf.exe";
var arguments = "\"" + BackupDirectory + file + "\" \"" + BackupDirectory + convert + ".bak\"";
var process = new Process
{
StartInfo =
{
CreateNoWindow = true,
UseShellExecute = true,
RedirectStandardOutput = false,
RedirectStandardInput = false,
RedirectStandardError = false,
FileName = fileName,
Arguments = arguments
}
};
process.Start();
process.WaitForExit();
file.Delete();
}
One thing drawing on from the comments by InBetween is the need for quotes, in this case the quotes needed to surround the two separate files.
I can confirm this code does work on IISExpress, impersonating the different user, unfortunately just not IIS 7.5.
A workround was to move this code into a Console Application and install on the server in question, then use a Windows Schedule Task to run as a specific account.
With some legacy apps, I've discovered that I need to pass the arguments as quoted text, otherwise they simply wouldn't work.
Not sure if this is the issue but it's worth the try:
Arguments = "\"D:\\inetpub\\Import\\" + file + " D:\\inetpub\\Import\\" + convert + ".bak\"";
Still it seems strange that the process would simply die silently. I'd double check Domain, UserName and Password.

Executing batch file located on remote machine

I'm trying to execute a batch file that is located on a remote machine with the following line of code:
System.Diagnostics.Process.Start(\\10.0.24.103\somePath\batchFile.bat);
And it blocks on this line of code. When I try to run it manually (by writing that address in Windows Explorer), it works, but I have to accept a security warning message first. I'm assuming this is why it's blocking when it's done through code...is there any way to force it to execute through code?
I solved my problem by adding more detail to the ProcessStartInfo object:
var process = new Process();
var startInfo = new ProcessStartInfo
{
CreateNoWindow = true,
FileName = "cmd.exe",
Arguments = "/c \"\"" + batchFile + "\"\"",
WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory,
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true
};
process.StartInfo = startInfo;
process.Start();
process.WaitForExit(30000);
I needed to specify to use cmd.exe, as well as surrounding the batchFile path in double quotes in case there are spaces in the path.
Try prefacing it with cmd /c(that's a space after /c).
Is this IP address a Windows machine on your domain etc.

Categories

Resources