C# - Command runs from command prompt but not from service - c#

I have a C# (ASP Core) service running on Windows Server 2012 R2 that executes Newman test suites via the command line. The command the service executes works perfectly when run directly in the command prompt, but is not working from the service. To add insult to injury, the very same command DOES work from the service running locally on my dev machine (Windows 10 Pro). I am certain I am running the same command in all instances, as the service outputs the CLI's StandardOutput into a file, the contents of which I paste straight into the command prompt.
EDIT: The service is hosted on IIS.
The error I receive:
module.js:471
throw err;
^
Error: Cannot find module 'C:\Users\MyName\AppData\Roaming\npm\node_modules\newman\bin\newman.js'
at Function.Module._resolveFilename (module.js:469:15)
at Function.Module._load (module.js:417:25)
at Module.runMain (module.js:604:10)
at run (bootstrap_node.js:393:7)
at startup (bootstrap_node.js:150:9)
at bootstrap_node.js:508:3
The command I'm running (all paths are the same in every instance):
"C:\Program Files\NodeJS\node.exe" C:\Users\MyName\AppData\Roaming\npm\node_modules\newman\bin\newman.js run https://api.getpostman.com/collections/MyCollectionURI -r cli,junit --reporter-junit-export D:\TestHarnessServiceLogs\XML\{FilenameFromDatetime}.xml -e https://api.getpostman.com/environments/MyEnvironmentURI --disable-unicode
C# to build and run command:
//Build over multiple lines to make it vaguely readable, then string replace away the newlines so it runs as one command
string runTestCmd = $#"{_nodeExecutablePath}
{_newmanDotJsFile} run
{collectionPath}
-r cli,junit
--reporter-junit-export {_junitReportPathWithFilename}
-e {environmentPath}
--disable-unicode"
.Replace(Environment.NewLine, " ")
.Replace("\t", "");
File.WriteAllText(#"D:\TestHarnessServiceLogs\Command.txt", runTestCmd);
//Launch hidden CLI
using (Process p = new Process())
{
p.StartInfo.FileName = #"C:\Windows\System32\cmd.exe";
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.Arguments = _nodeVarsBatPath;
p.Start();
//Execute commands
using (StreamWriter sw = p.StandardInput)
{
if (sw.BaseStream.CanWrite)
{
sw.WriteLine(runTestCmd);
}
}
//Parse the various outputs
output = p.StandardOutput.ReadToEnd();
error = p.StandardError.ReadToEnd();
exitCode = p.ExitCode.ToString(); //Always returns 0, think this is because it evaluates success of creating the process, not what happens inside it
File.WriteAllText(#"D:\TestHarnessServiceLogs\output.txt", output);
File.WriteAllText(#"D:\TestHarnessServiceLogs\error.txt", error);
File.WriteAllText(#"D:\TestHarnessServiceLogs\exitCode.txt", exitCode);
}
Newman is installed globally in both environments, and some relevant AppSettings below (names modified slightly for brevity):
"_newmanDotJsFile": "C:\\Users\\MyName\\AppData\\Roaming\\npm\\node_modules\\newman\\bin\\newman.js",
"_nodeVarsBatPath": "\"C:\\Program Files\\NodeJS\\nodevars.bat\"",
"_nodeExecutablePath": "\"C:\\Program Files\\NodeJS\\node.exe\"",
How can an identical command find the newman module and run fine from the CLI but not from the service?
EDIT: The user the service is running under couldn't access the file, having done that I now get the following (obviously permissions based) error instead, think I know where this is going...:
fs.js:994
binding.lstat(pathModule._makeLong(path), statValues);
^
Error: EPERM: operation not permitted, lstat 'C:\Users\MyName'
at Error (native)
at Object.fs.lstatSync (fs.js:994:11)
at Object.realpathSync (fs.js:1676:21)
at toRealPath (module.js:133:13)
at Function.Module._findPath (module.js:181:22)
at Function.Module._resolveFilename (module.js:467:25)
at Function.Module._load (module.js:417:25)
at Module.runMain (module.js:604:10)
at run (bootstrap_node.js:393:7)
at startup (bootstrap_node.js:150:9)
EDIT 2: Created a new user for the service to run under, installed newman for that user and gave it the right permissions (didn't seem clever to give Network Service access to my profile) - all is now working!

It sounds like the service doesn't run as your user? Perhaps that's why it doesn't find the file in that location you specified.

Related

Can we run node application in net core 3.1

I am having a .Net Core 3.1 console application (which is work as a azure consumer for a message queue)
When executing the Consumer, based on a flag value of message property, Its need to run separate application which is written in node.js.
I decided use separate run.sh (shell script) file to call node application and run.sh file will call through c#.
Here is the code snippet I used.
var command = "bash";
var myBatchFile = #"C:\Temp\spiderease_v1\run.sh"; //Path to shell script file
var argss = #"C:\Temp\spiderease_v1\run.sh CA--STATCAN--REG--ADMIN-DATA {url} {OUTPUT_PATH} {SPIDER_EASE_HOME} {SPIDER_TEMPLATE_HOME} {TYPE}"; //this would become "/home/ubuntu/psa/PdfGeneration/ApacheFolder/ApacheFOP/transform.sh /home/ubuntu/psa/PdfGeneration/ApacheFolder/XMLFolder/test.xml /home/ubuntu/psa/PdfGeneration/ApacheFolder/XSLTFolder/Certificate.xsl /home/ubuntu/psa/PdfGeneration/ApacheFolder/PDFFolder/test.pdf"
var processInfo = new ProcessStartInfo();
processInfo.UseShellExecute = false;
processInfo.FileName = command; // 'sh' for bash
processInfo.Arguments = argss; // The Script name
processInfo.RedirectStandardOutput = true;
var process = Process.Start(processInfo); // Start that process.
var outPut = process.StandardOutput.ReadToEnd();
process.WaitForExit();
But This won't work as expected.
Update:
This code snipt didn't give any error, but I am unable to ensure that file getting executed or not. because when I run this bash file directly, it produced some files in given path. here it didn't give any output.
Can someone help me out whether do I using correct implementation for this task or do I have any alternatives?
If this is an good solution, what would be the wrong in code?
(I am willing push this into docker Linux environment as well)
Can someone help me out on this?

Aspera Error :- ascp.exe: Failed to open TCP connection for SSH, exiting

I am working on Aspera file upload functionality and I am getting one error as per below scenario.
I downloaded Aspera CLI from below URL.
https://downloads.asperasoft.com/en/downloads/62
and then with the help of command prompt ran below statement and it worked fine.
cmd Statement : ascp -P33001 -QT -l500m --file-manifest=text -k 0 -o
Overwrite=always {Source File Path} {username}#{domain}:{destination
Folder}
It worked perfectly fine.
Then I tried the same thing from console app with below code.
Process process = new Process();
process.StartInfo.FileName = #"E:\Projects\Research\AsperaFileUpload\AsperaFileUpload\AsperaLibrary\bin\ascp.exe";
process.StartInfo.Arguments = #"ascp -P33001 -QT -l500m --file-manifest=text -k 0 -o Overwrite=always {Source File Path} {username}#{domain}:{destination Folder}"; // Note the /c command (*)
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.Start();
//* Read the output (or the error)
string output = process.StandardOutput.ReadToEnd();
Console.WriteLine(output);
string err = process.StandardError.ReadToEnd();
Console.WriteLine(err);
Console.ReadLine();
process.WaitForExit();
But this code always give error like "ascp.exe: Failed to open TCP connection for SSH, exiting"
I am wondering if same command working from command line why it is not working from console app.
Can anyone please help me on this.
Thanks in advance.
This error message tells that "ascp" cannot connect to TCP port 33001 (arg "-P") of the server "{domain}"
I suggest the following:
use the more modern syntax:
ascp -P33001 -QT -l500m --file-manifest=text -k 0 -o Overwrite=always --host={domain} --user={username} --mode=send {Source File Path} {destination Folder}
add argument -L /path/to/log/folder and look at log error in file: aspera-scp-transfer.log
instead of using bare "ascp", which you will find limited, prefer to use the "TransferSDK" here:
https://developer.ibm.com/aspera

MVC executing a LibreOffice conversion

Hi I'm trying to convert either a doc or docx to a pdf in a c# MVC application. I know I can do this using libreOffice. So I created a simple batch file to take 2 variables and then run them into the libreoffice 'soffice' headless to convert to pdf.
So that gave me this code.
echo on
SET var1=%2
IF "%var1:~-1%"=="\" SET var1=%var1:~0,-1%
cd "C:\Program Files\LibreOffice 5\program\"
soffice --headless --convert-to pdf %1 --outdir %var1%
Originally I thought the problem was within my MVC application and the way I called this batch script. But I commented (REM) the soffice and outputted out the command in the bash using the standard output.
var psi = new ProcessStartInfo("cmd.exe", "/k " + command);
//psi.CreateNoWindow = true;
psi.FileName = command;
psi.UseShellExecute = false;
psi.RedirectStandardError = true;
psi.RedirectStandardOutput = true;
psi.Arguments = string.Format("{0} {1}", fullPath2, tempPath);
var process = Process.Start(psi);
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
Trace.WriteLine(output);
Trace.WriteLine(error);
process.WaitForExit();
When I commented the soffice line - it hit the WaitForExit and worked no problems (ok with no pdf conversions, but the script exited).
If I don't do that it seems to execute the cmd and even the soffice commands because I can see them in the task manager - but obvisouly nothing happens.
Additionally the code above works when I did a c# command line program (I've hard coded the file/command lines in both instances). The executable also works when I run as the user that is running the app pool in my MVC application.
The bash file also works file 'standalone' no matter if me or my appPool user run it.
So what gives - why won't this run.
This is the code that comes out of that trace - so what the bash script does.
c:\windows\system32\inetsrv>echo on
c:\windows\system32\inetsrv>SET var1=C:\inetpub\xxxxxxxxx\Temp\
c:\windows\system32\inetsrv>IF "\" == "\" SET var1=C:\inetpub\xxxxxxxxx\Temp
c:\windows\system32\inetsrv>cd "C:\Program Files\LibreOffice 5\program\"
C:\Program Files\LibreOffice 5\program>soffice --headless --convert-to pdf C:\inetpub\xxxxxxxxx\Temp\636295920370843147.doc --outdir C:\inetpub\xxxxxxxxx\Temp
I've got a feeling that this has something to do with the amount of characters or something because the soffice does fireup (can see it in the task manager).
FYI there are no spaces or special characters anywhere.
Any ideas?
Update
This looks to be an issue with the wait command. So any help with that helpful, I'm starting to think perhaps this is an issue with c# and libreoffice 5 - I've seen examples that supposedly work with libreoffice 4.
I guess my challenge continues....

Shell Script File(.sh) does not run from c# core on linux

I am trying to run ".sh" file from c# core application.But it doesn't seem to be running properly.Here is my scenario.
I am working on .Net core project which is hosted on Linux environment.We are trying to create "PDF" in our project for which we have used "Apache FOP".
Here i have created one "shell script" file "transform.sh" which internally calls "fop" with required parameters.Since developement is being done on windows machine we tested the same usinf "batch" file i.e. "transform.bat",but since we cannot use the "batch" file on linux enviornment we have created shell script file "transform.sh"
Following is the code from"transform.sh"
./fop -xml $1 -xsl $2 -pdf $3
Following is C# code from which i am calling the "shell script file
var process = new Process
{
StartInfo = new ProcessStartInfo
{
UseShellExecute = false,
RedirectStandardOutput = true,
Arguments = string.Format("{0} {1} {2}", XML_filename, XSL_filename, output)
}
};
process.StartInfo.FileName = "Path to shell script file";
process.Start();
process.WaitForExit();
Above code doesnot give any error but it also does not create the pdf file.If i directly run the shell script file from "Terminal" it works fine and create pdf file.
./transform.sh "/home/ubuntu/psa//PdfGeneration/ApacheFolder/XMLFolder/test.xml" "/home/ubuntu/psa/PdfGeneration/ApacheFolder/XSLTFolder/Certificate.xsl" "/home/ubuntu/psa/PdfGeneration/ApacheFolder/PDFFolder/t444t.pdf"
Please let me know if there is something wrong i am doing?How can i make the sheel script run on linux through C# core application.
Thanks.
I was able to solve the issue,just thought that i should put my solution here so that it may help others in future...
As mentioned in Question i was not able to generate the PDF file through shell script on linux machine.After debugging as suggested by "#JNevill" I came to understand that the shell script file was not getting called from .net process itself.
So my first task was to make the shell script file called through .Net Process.
After lots of searching through Net and trying out different solutions i got solution at How to perform command in terminal using C#(Mono).
So changed my code of calling the process as follow,
var command = "sh";
var myBatchFile = //Path to shell script file
var argss = $"{myBatchFile} {xmlPath} {xsltPath} {pdfPath}"; //this would become "/home/ubuntu/psa/PdfGeneration/ApacheFolder/ApacheFOP/transform.sh /home/ubuntu/psa/PdfGeneration/ApacheFolder/XMLFolder/test.xml /home/ubuntu/psa/PdfGeneration/ApacheFolder/XSLTFolder/Certificate.xsl /home/ubuntu/psa/PdfGeneration/ApacheFolder/PDFFolder/test.pdf"
var processInfo = new ProcessStartInfo();
processInfo.UseShellExecute = false;
processInfo.FileName = command; // 'sh' for bash
processInfo.Arguments = argss; // The Script name
process = Process.Start(processInfo); // Start that process.
var outPut = process.StandardOutput.ReadToEnd();
process.WaitForExit();
After changing the code ,the ".sh" file got executed and i was able to generate the PDF file.
Also script of the ".sh" file i.e. (transform.sh) which was calling Apache FOP file i.e. "FOP.sh" also needed to be changed.
Initially code was
./fop -xml $1 -xsl $2 -pdf $3
Which i changed as follow,(Change was to give full path of the FOP file)
/home/ubuntu/psa/PdfGeneration/ApacheFolder/ApacheFOP/fop -xml $1 -xsl $2 -pdf $3
Late answer, but for me, it worked just by setting the RedirectStandardOutput to true and changing the FileName property like this:
processInfo.FileName = #"C:\Program Files\Git\git-bash.exe";
processInfo.RedirectStandardOutput = true;

Script stops on specific command without go into catch block

I have a powershell script with PowerCLI commands to install and configure virtual machines.
These are the settings in the environment
Windows Server 2008 R2
ESX 4.1
PowerShell v2
PowerCLI 5.1
The script will be triggered from a user on a website. Following code start the script.
PathToScript is a UNC path
const string Path32BitPowerShell = #"C:\Windows\SysWOW64\Windowspowershell\v1.0\powershell.exe";
public static void Run32BitPowerShell(String PathToScript, Boolean WaitForExit, String Arguments = "")
{
Process PowerShellProcess = new Process();
PowerShellProcess.StartInfo.CreateNoWindow = true;
PowerShellProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
PowerShellProcess.StartInfo.FileName = Path32BitPowerShell;
PowerShellProcess.StartInfo.WorkingDirectory = #"C:\";
PowerShellProcess.StartInfo.Arguments = PathToScript + " " + Arguments;
PowerShellProcess.Start();
if (WaitForExit)
{
PowerShellProcess.WaitForExit();
}
}
The script has this two global settings:
$ErrorActionPreference = "Stop"
$ConfirmPreference = "None"
The whole code is inside a try block with catch/finally
But the code never goes into the catch block. I know it because I wrote one time as first line in the catch block Stop-Computer -Force -Confirm:$false and the webserver was still running after 5 minutes after the script was finished.
The code stops on the command Invoke-VMScript:
Invoke-VMScript -VM $VM -ScriptType Bat -ScriptText "powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -Command Set-ExecutionPolicy Unrestricted -Scope CurrentUser" -GuestUser "***" -GuestPassword "****"
The exit code from the C# process is 1
Important:
The script runs perfectly, wenn I start it interactive (from the ISE) !
The issue only occurs when the webserver starts it (non-interactive).
Someone has any idea, where the problem could be ?
/Update
It works also directly from the powershell command line, but also interactive
Maybe try
$Global:ErrorActionPreference = 'Stop'
$Global:ConfirmPreference = 'None'
Worked for me when I had very similar problem.

Categories