I want to change the physical path of an application running on my IIS 7 from another application that runs on my IIS . I tried to do this via appcmd.exe. However, this seems to be impossible due to lack of authorization from the asp.net application.
That is basically what I'm trying to do
private static string Execute(string IISAppName, string NewIISPath)
{
var winPath = Environment.GetFolderPath(Environment.SpecialFolder.Windows);
var appcmdPath = Path.Combine(winPath, "system32", "inetsrv/appcmd.exe");
var arg = "set app /app.name:\"" + IISAppName + "\" /[path='/'].physicalPath:" + NewIISPath;
ProcessStartInfo startInfo = new ProcessStartInfo(appcmdPath, arg)
{
WindowStyle = ProcessWindowStyle.Hidden,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
};
Process process = Process.Start(startInfo);
var textResult = process.StandardOutput.ReadToEnd();
process.WaitForExit();
return textResult;
}
textResult is an empty string.
Any ideas?
The AppPool for the ASP.NET site would have to be configured to run as a user with admin privilege on the box to execute that script. In almost all cases, this is a bad idea for security reasons.
Related
I am writing a software update process on Linux. Application is .NET 5 RC1 (Sept 15 2020 release). When a certain packet is received by my application, it downloads the software update to a sub-folder then spawns off the executable to perform the software update.
Unfortunately, using Process.Start and ProcessStartInfo seems to create a process that is attached to the main process. Since the software update must stop the process in order to update it, it also gets stopped because it is a child of the process, having been spawned via Process.Start.
How do I create a detached process on Linux? On Windows I am using PInvoke and the CreateProcess API with the DETACHED_PROCESS flag, see the following:
var processInformation = new ProcessUtility.PROCESS_INFORMATION();
var startupInfo = new ProcessUtility.STARTUPINFO();
var sa = new ProcessUtility.SECURITY_ATTRIBUTES();
sa.Length = Marshal.SizeOf(sa);
CreateProcess(null, "\"" + fileName + "\" " + arguments, ref sa, ref sa, false, DETACHED_PROCESS, IntPtr.Zero, Path.GetDirectoryName(fileName), ref startupInfo, out processInformation);
Here is my code for Linux. I had read that appending & to a process on Linux creates it detached, but that does not appear to be the case.
ProcessStartInfo info = new ProcessStartInfo
{
// Linux uses " &" to detach the process
Arguments = arguments + " &",
CreateNoWindow = true,
FileName = fileName,
UseShellExecute = false,
WindowStyle = ProcessWindowStyle.Hidden,
WorkingDirectory = Path.GetDirectoryName(fileName)
};
Process.Start(info);
I was unable to get nohup or disown to work from C#. Killing the parent process always resulted in the child process being terminated as well.
I ended up using at, which can be installed via sudo apt install at. The atd service is installed and will stay running even when rebooted.
Here is the C# code that I used:
// the following assumes `sudo apt install at` has been run.
string fileName = "[your process to execute]";
string arguments = "[your command line arguments for fileName]";
string argumentsEscaped = arguments.Replace("\"", "\\\"");
string fullArgs = $"-c \"echo sudo \\\"{fileName}\\\" {argumentsEscaped} | at now\"";
ProcessStartInfo info = new()
{
Arguments = fullArgs,
CreateNoWindow = true,
FileName = "/bin/bash",
UseShellExecute = false,
WindowStyle = ProcessWindowStyle.Hidden,
WorkingDirectory = Path.GetDirectoryName(fileName)
};
using var process = Process.Start(info);
process.WaitForExit();
// make sure to check process.ExitCode == 0
For me, setsid in combination with & makes a spawned child process out-living its parent process when invoked via sh -c.
Example:
var command = $"dotnet \"PathToDll\" param1 param2";
process.StartInfo = new ProcessStartInfo
{
Arguments = $"-c \"setsid {command.Replace("\"", "\\\"")} &\"",
CreateNoWindow = true,
FileName = "/bin/sh",
};
process.Start();
This was tested on Debian and Ubuntu.
Slightly refactored version of #jjxtra solution, so it's easier to understand what's going on in the arguments.
Btw, the echo is not an example, but the way of executing at command.
string command = $"actual command to run";
string atdCommand = $#"echo \""{command}\"" | at now";
string bashCommand = $#"-c ""{atdCommand}"" ";
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = "/bin/bash",
Arguments = bashCommand,
...
};
I'd like to set up a Visual C++ toolchain to be used inside my C# application. For the toolchain it's recommended to call vcvarsall (or some subvariant). My problem is that the calling process - my application - will not get to keep the environment set up by vcvarsall. Can this somehow be achieved?
// First set up the toolchain with vcvarsall
var vcvarsallProc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = vcvarsallPath,
Arguments = "x86",
UseShellExecute = false,
}
};
vcvarsallProc.Start();
vcvarsallProc.WaitForExit();
// Invoke the linker for example
var linkerProc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "LINK.exe",
Arguments = " foo.obj /OUT:a.exe",
UseShellExecute = false,
}
};
linkerProc.Start();
linkerProc.WaitForExit();
// ERROR: 'LINK' is not recognized as an internal or external command
Turns out, this is pretty much impossible without a hassle.
The best one can do is chain multiple commands, which will run in the same environment. It can be done like so:
var linkerProc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = $"/C ({vcvarsallPath} {vcvarsallArgs}) && (LINK.exe {linkArgs})",
UseShellExecute = false,
}
};
Hiding this behind a function like InvokeWithEnvironment, and it's pretty painless to use.
I want to allow users to create their own Python scripts that run on the server and give output to the users. Likely I'll be allowing users to use Selenium in their scripts, and to write to files in a specific folder. I'm new to Python however assume there are security risks. How would you suggest I protect the server from malicious user code? Below is the C# code I'm using at present to run Python.
public static string Run()
{
string fileName = #"C:\temp\text.py";
Process p = new Process();
p.StartInfo = new ProcessStartInfo(#"python", fileName)
{
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
};
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
return output;
}
I am currently trying to setup some UI tests on a Core web app, however I am not able to get the web app started. Using the command line directly with "dotnet run" from the web app directory works. The problem comes when I try to use Process to run it before executing my tests nothing happens.
var process = new Process
{
StartInfo =
{
FileName = "dotnet",
Arguments = "run",
WorkingDirectory = applicationPath
}
};
process.Start();
Has anyone been confronted to a similar issue before and/or managed to solve it? I may be misusing Process.
Turns that adding UseShellExecute to my StartInfo and setting it to false made it work:
var process = new Process
{
StartInfo =
{
FileName = "dotnet",
Arguments = "run",
UseShellExecute = false,
WorkingDirectory = applicationPath
}
};
process.Start();
The default for UseShellExecute is true but it would be similar to running cmd dotnet run instead of dotnet run which is what I needed.
Try this
ProcessStartInfo Startinfo = new ProcessStartInfo();
Startinfo.FileName = "D:\\TFS\\QA\\SH_LoadTest\\SH_LoadTest\\bin\\Debug\\SH_LoadTest.exe";
StartInfo.Arguments = "Your Arguments";
Process pro = Process.Start(Startinfo);
I'm trying to automate some operations in Mainframe. For that I made a C# program that connects to Mainframe using terminal emulator wc3270 and send keys to it.
This part works fine.
My problem is that I need to read the content displayed in terminal emulator screen so I can take better decisions about which keys I'll send to it.
How could I do it? I didn't find out any API that would let me do it.
Thanks.
I suggest using IBM personal communication tools:
http://www-03.ibm.com/software/products/en/pcomm
Together with the C# EHLLAPI wrapper, URL to example:
https://www.codeproject.com/Articles/9615/Using-EHLLAPI-in-C
To find out the session key for the emulator, you can use handle.exe from Windows Sysinternals
Code that im using for handle:
public String getSessionKey(String pid)
{
Process p = new Process();
p.StartInfo = new ProcessStartInfo()
{
UseShellExecute = false,
CreateNoWindow = true,
WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden,
FileName = "cmd.exe",
Arguments = "/C C:\\handle.exe -a -p " + pid,
RedirectStandardError = true,
RedirectStandardOutput = true
};
p.Start();
String str = (p.StandardOutput.ReadToEnd());
String[] arr = str.Split('\n');
foreach (String s in arr)
{
if (s.Contains("Owned"))
{
return s.Substring(s.Length - 3, 1);
}
}
return "";
}