Executing a batch file from .net application fails in a certain circumstance - c#

This ticket is not a duplicate of this popular question since the solution there does not fix the problem. Rather I think it has to do with calling a file that's residing in the %WINDIR%\System32 directory, because calling a batch file with anything else seems to work.
I have a batch file with the the following contents:
telnet 10.147.36.20 11211
pause
I kick it off by executing the following code:
var psi = new ProcessStartInfo(entry.ExecutablePath);
Process.Start(psi);
I get the following:
'telnet' is not recognized as an internal or external command,
operable program or batch file.
even though if I execute telnet 10.147.36.20 11211 from the command line, it works perfectly fine.
I've tried telnet.exe, c:\windows\system32\telnet.exe, start telnet.exe and other variations, but nothing seems to work.
What am I missing?

When you are calling:
ProcessStartInfo(entry.ExecutablePath);
it looks wrong. You're passing in a path without the executable name.
Try:
FileInfo oFileInfo = new FileInfo(entry);
ProcessStartInfo psi = new ProcessStartInfo(oFileInfo.FullName);

Related

c# opens the batch file but doesn't execute the VBScript in the .bat

I'm developing an application in C#. The main idea is:
Press button
Open .bat file
The .bat file opens Telnet [IP] [Port]
.bat file executes the VBScript
VBScript writes some commands to the telnet window
When I run this batch file by double-clicking on it, it works fine. However, wen I try to run it from a C# app, it doesn't work.
I already tried many methods.
Here is a few examples about what I tried:
Is it possible to use a batch file to establish a telnet session, send a command and have the output written to a file?
C# Winforms and command line batch files
batch works fine but "windows cannot find devcon.exe" in c# program
When I tried this:
string cmd = #"path";
var m_command = new System.Diagnostics.Process();
m_command.StartInfo.FileName = #"file.bat";
m_command.StartInfo.Arguments = cmd;
m_command.Start();
I got the error:
windows cannot find .exe make sure you typed the name correctly and then try again
And when I tried this:
string cmd = #"path";
var m_command = new System.Diagnostics.Process();
m_command.StartInfo.FileName = #"file.bat";
m_command.StartInfo.Arguments = cmd;
m_command.Start();
It works, but just opens telnet, the VBScript doesn't works.
This is the code in the .bat file:
:: Open a Telnet window
start C:\Windows\System32\telnet.exe 192.168.0.198 49211
:: Run the script
cscript SendKeys.vbs
This is the code in the .svs file:
set OBJECT=WScript.CreateObject("WScript.Shell")
WScript.sleep 500
OBJECT.SendKeys "T{ENTER}"
WScript.sleep 1000
OBJECT.SendKeys "T{ENTER}"
OBJECT.SendKeys " "
I expect the .VBS to write the command to the telnet window, however when I click the button in c# form, it just opens telnet, the VBScript doesn't works.
What you could do is find the cscript.exe file and execute it directly,like this:
for /f "tokens=*" %%C in ('where csscript.exe') do (%%C Sendkeys.vbs&goto Next)
:Next
rem This is only necessary because we want to run the script once
This migth work, but as the commenters said,using sendkeys is really not recommended,because it can cause major problems, once the windows are set incorrectly, or some of the progresses get delayed.

Using LibreOffice(soffice.exe) as Process.Start() from Code behind not working on IIS server

I am using LibreOffice as command line for conversion of docx to pdf. I am using below code snippet.
using (Process pdfprocess = new Process())
{
pdfprocess.StartInfo.UseShellExecute = true;
pdfprocess.StartInfo.LoadUserProfile = true;
pdfprocess.StartInfo.FileName = "soffice.exe";
pdfprocess.StartInfo.Arguments = "-norestore -nofirststartwizard -headless -convert-to pdf C:\\test.docx";
pdfprocess.StartInfo.WorkingDirectory = #"C:\Program Files\LibreOffice\program\";
pdfprocess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
pdfprocess.Start();
if (!pdfprocess.WaitForExit(1000 * 60 * 1)) {
pdfprocess.Kill();
}
pdfprocess.Close();
}
Everything works fine under IISExpress or Console application. When I try to run under IIS server, it doesn't work.
I am running under DefaultAppPool and I have given permission to DefaultAppPool to access LibreOffice directory but I am not able to get result.
I don't want to change Identity to LocalSystem as security concerns.
How can I able to run soffice.exe using Process.Start() under default ApplicationPoolIndentity?
I had the same problem and I just found solution that worked for me. When I was executing conversion under CMD console everything was working fine. But soffice.exe executed under iis app didn't work.
Although, application pool has it's own user profile directory it looks like libreoffice cannot create its files there. What I did is I created temp folder under iis www directory and gave it apppool permisions. Then I passed this location with other parameters like that: "-env:UserInstallation=file:///C:/www/temp/libreoffice"
Had same issue. The problem was that process started, but didn't exit and give no results, any StandardError output. It was definitely a problem of permissions. So I've started procmon and it showed me, it needs access to this path:
C:\Windows\SysWOW64\config\systemprofile\AppData\Roaming\LibreOffice
Looks like similar problem here:
Why does systemprofile need Desktop folder to open excel file
So not sure what to do next from security point of view, but solution is to give access to that folder for ApplicationPoolUser.
UPDATED:
Looks like it works not for all documents, and even after I eliminated all ACCESS DENIED issues from Procmon for other docx file, "soffice" still stuck, and I cannot kill process from Task Manager, it gives "Access Denied" dialog. Looks like it depends on some fonts, it opens something, and because it hold it, process cannot be closed, and no more files proceed.

Invoking a program from command shell from SQL CLR

I'm invoking a CLR from SQL to prepare data for ingestion via BULK INSERT. One of the things I need to be able to do is unzip a file. First, I'm just trying simple stuff ... copying a file. Can't even get that to work.
For example:
string command = "/C COPY /Y err.txt y.txt";
System.Diagnostics.Process.Start("cmd.exe", command);
returns error "System.Security.SecurityException: Request failed."
So that's a little too complicated, I guess. So I try this:
System.Diagnostics.Process process = new System.Diagnostics.Process();
I get the same error message, even though I haven't done anything yet, except create a process that I'm even invoking. I have the assembly set to EXTERNAL_ACCESS on the SQL side.
What am I missing?

Process.Start() does nothing

I have to start a VPN connection (Fortinet) by code.
I have a cmd file that establish the connection.
If I call the cmd file on the shell it works pretty fine.
When I call it via Process.Start it does nothing.
It doesn't throw any exception, it seems to execute but VPN does not connect.
On the standard output I can read the echo I put on the cmd file (so it is executing the right file).
I launched a ping -d to see when the vpn goes up, when I call it via shell it goes up in a few seconds, via C# it is not.
I also tried a sleep(30000) but nothing.
My cmd (ConnectFile.cmd):
#echo off
#echo Connecting to VPN
"C:\Program Files (x86)\Fortinet\SslvpnClient\FortiSSLVPNclient.exe" connect -s "vpn myvpn"
My code (connectFile and disconnectFile are strings that contain the full path of the cmd files):
try
{
var startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.FileName = connectFile;
startInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(connectFile) ?? "";
System.Diagnostics.Process process = System.Diagnostics.Process.Start(startInfo);
System.Threading.Thread.Sleep(30000);
base.GetFiles(folder);
}
finally
{
System.Diagnostics.Process.Start(disconnectFile);
}
You have to separate the parameters. FileName is for the exe file, not the whole shell command (you're explicitly saying not to use the shell). So put the parameters to the Arguments property in ProcessStartInfo.
In your case, the parameters should be:
FileName - C:\Program Files (x86)\Fortinet\SslvpnClient\FortiSSLVPNclient.exe (no quotes)
Arguments - connect -s "vpn myvpn" (again, no quoting)
Second, you have to read the standard output if you capture it. If the output buffer gets full before you read it, the called process will stop working - it has to wait for the buffer to be emptied. If you're sure the application will actually finish at some point, simply remove the Thread.Sleep and call ReadToEnd right away. Otherwise, use eg. asynchronous reading to get the data.
Also, it's usually a good idea to set WorkingDirectory. Even if the application doesn't need any data from the working directory, it's safer, since only admins can change Program Files - this helps against DLL inject hacks.

execute an EXE on the server

I have an exe which I call from the command line. Is it possible to execute that file on the server? On the computer if the file is located in the folder abc, I go to folder abc and than I execute the batch. Hw do I do this in C#
Code example below, make sure you have your permissions setup correctly:
System.Diagnostics.Process yourProcess = new System.Diagnostics.Process();
// Set the directory
yourProcess.StartInfo.WorkingDirectory = Request.MapPath("~/"); //or wherever your file is
// Set the filename
yourProcess.StartInfo.FileName = Request.MapPath("bla.exe");
// Start the process
yourProcess.Start();
ASP Net - Run Application (EXE) from ASP.Net C#
In server side code certainly, Process.Start(MyExeFile) will do that but, as long as the user account you are running your stuff on can execute it.

Categories

Resources