docker-machine commands from C# - c#

Is there another way to execute docker-machine commands from C#. Currently the way I'm doing it is:
Starting a Process
The Process starts "C:\Program Files\Git\bin\bash.exe"
Pass the docker-machine inspect default command as a ProcessStartInfo argument
This is the code that I'm currently using and at the moment still don't have no idea how to retrieve the return JSON from the docker-machine inspect default command but I'm guessing that I it can be retrieved from the process.StandardOutput stream.
ProcessStartInfo psi = new ProcessStartInfo();
psi.WindowStyle = ProcessWindowStyle.Normal;
psi.FileName = #"C:\Program Files\Git\bin\bash.exe";
psi.WorkingDirectory = #"C:\Program Files\Docker Toolbox";
psi.Arguments = #"--login -i ""C:\Program Files\Docker Toolbox\start.sh"" docker-machine inspect default";
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
Process process = Process.Start(psi);
As you can see this is quite tedious to do, for instance if I have to do another couple of docker-machine commands.
I'm also looking at the Docker Remote API but I don't seem to see an endpoint that interacts with the Docker Machine.
UPDATE:
One problem that I have with executing commands this way is that sometimes the commands are not evaluated properly. For instance eval $(docker-machine env default) works if executed on the Docker Toolbox but not on the code.

Related

C# Windows Service with Registry Access and rundll32.exe

I have a C# Windows Service running under the LocalSystem account.
I need access to the Windows registry in this service. I assume that this is only possible when running as LocalSystem? Or can I install the service as User context and have access to HKEY_CURRENT_USER?
The systems where the service is used is normally just used by one user. So there will be just "one" HKEY_CURRENT_USER. Another option is, to setup Remote Apps not for one user, but for all users. But I have no idea how to do that. Currently I know only the way listed below by running rundll32.exe.
As a second requirement I need to execute rundll32.exe to create RemoteApp Connection.
The following Code is not working properly:
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.FileName = "cmd.exe";
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = "/C rundll32.exe tsworkspace,WorkspaceSilentSetup C:\\RemoteConfig.wcx";
using (Process process = Process.Start(startInfo))
{
process.WaitForExit();
}
What must the Service be like to access HKEY_CURRENT_USER?
How can I run rundll32.exe? just running it directly caused some trouble when testing it in a console application. But with help of cmd.exe it worked.

interfering with mongo.exe with console

ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "cmd.exe";
psi.Arguments = #"/C cd C:\Program Files\MongoDB\Server\4.2\bin & dir & pause";
using (Process p = Process.Start(psi))
{
p.WaitForExit();
}
With this code, I first open cmd and then run mongo.exe. But after switching to mongo shell, I can't send any commands (with Code).
My goal is to automate Mongo ReplicaSet. For this, I need to get input and output by interfering with mongoshell.
Thank you in advance for your help.
There is an easier way of doing this.
Start the MongoDB instance and put it in background.
Open a new mongo shell and run your commands.
When you like to use the mongo shell then you should use native JavaScript commands, i.e. start shell with javascript file name (see Core Options)
If you prefer to do all in C# then you should use the MongoDB C#/.NET Driver
As last command in your shell script put db.getSiblingDB("admin").shutdownServer() - by this the first window will terminate and you don't need any WaitForExit()

need help: "The requested operation requires elevation" [duplicate]

I'm working on a WPF application targeting .NET 3.0. I need to call an exe which requires administrative privileges. I can get the UAC to prompt for permission by using something like:
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.Verb = "runas";
startInfo.UseShellExecute = true;
startInfo.FileName = "target.exe";
Process p = new Process();
p.StartInfo = startInfo;
p.Start();
My problem is I need to redirect standard output, and doing so with UseShellExecute = true results in an exception stating that:
The Process object must have the UseShellExecute property set to false
in order to redirect IO streams
However, setting it to false results in the UAC not prompting for permission and I get an exception stating:
The requested operation requires elevation
How can I redirect standard output and prompt for UAC?
I have seen this similar question, however the solution is to use the app.manifest to give my application administrative privileges. This is something I cannot do due to requirements.
UseShellExecute must be set to false to redirect IO, and to true to use the Verb property. So you can't.
But this article seems do the magic, although I haven't tested it.
It's written in C++, but a wrapper API can easily be created to be called from C# by using DllImport.
Note: If you want to pass data between the two programs and have access to the target program's source code, you can easily re-design you application to use Named Pipes instead of redirecting standard I/O.
There is another pretty simple solution:
If you want to run a child-executable elevated AND redirect the output (optionally including window hiding), then your main code must be running elevated too. This is a security requirement.
To accomplish this:
Manually edit your app.manifest in your project folder.
Find the comment regarding UAC Manifest Options, you will see the 3 examples of requestedExecutionLevel.
Under the comment, locate the tricky asInvoker which is currently enabled, and replace it with requireAdministrator.
Restart Visual Studio in order to take into effect, and after re-building your app it should have the typical UAC shield icon.
Now your code will run elevated, everything that it launches will be elevated too, and you can also capture output streams. Here is an example in VB.NET:
Dim startInfo As New ProcessStartInfo
startInfo.Verb = "runas"
startInfo.FileName = "subprocess-elevated.exe"
startInfo.Arguments = "arg1 arg2 arg3"
startInfo.WorkingDirectory = Environment.CurrentDirectory
startInfo.WindowStyle = ProcessWindowStyle.Hidden
startInfo.CreateNoWindow = True
Dim p As Process = New Process()
p.StartInfo = startInfo
p.StartInfo.UseShellExecute = False
p.StartInfo.RedirectStandardOutput = True
p.StartInfo.RedirectStandardError = True
p.Start()
Console.WriteLine(p.StandardOutput.ReadToEnd)
Console.WriteLine(p.StandardError.ReadToEnd)
p.WaitForExit()

Redirect standard output and prompt for UAC with ProcessStartInfo

I'm working on a WPF application targeting .NET 3.0. I need to call an exe which requires administrative privileges. I can get the UAC to prompt for permission by using something like:
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.Verb = "runas";
startInfo.UseShellExecute = true;
startInfo.FileName = "target.exe";
Process p = new Process();
p.StartInfo = startInfo;
p.Start();
My problem is I need to redirect standard output, and doing so with UseShellExecute = true results in an exception stating that:
The Process object must have the UseShellExecute property set to false
in order to redirect IO streams
However, setting it to false results in the UAC not prompting for permission and I get an exception stating:
The requested operation requires elevation
How can I redirect standard output and prompt for UAC?
I have seen this similar question, however the solution is to use the app.manifest to give my application administrative privileges. This is something I cannot do due to requirements.
UseShellExecute must be set to false to redirect IO, and to true to use the Verb property. So you can't.
But this article seems do the magic, although I haven't tested it.
It's written in C++, but a wrapper API can easily be created to be called from C# by using DllImport.
Note: If you want to pass data between the two programs and have access to the target program's source code, you can easily re-design you application to use Named Pipes instead of redirecting standard I/O.
There is another pretty simple solution:
If you want to run a child-executable elevated AND redirect the output (optionally including window hiding), then your main code must be running elevated too. This is a security requirement.
To accomplish this:
Manually edit your app.manifest in your project folder.
Find the comment regarding UAC Manifest Options, you will see the 3 examples of requestedExecutionLevel.
Under the comment, locate the tricky asInvoker which is currently enabled, and replace it with requireAdministrator.
Restart Visual Studio in order to take into effect, and after re-building your app it should have the typical UAC shield icon.
Now your code will run elevated, everything that it launches will be elevated too, and you can also capture output streams. Here is an example in VB.NET:
Dim startInfo As New ProcessStartInfo
startInfo.Verb = "runas"
startInfo.FileName = "subprocess-elevated.exe"
startInfo.Arguments = "arg1 arg2 arg3"
startInfo.WorkingDirectory = Environment.CurrentDirectory
startInfo.WindowStyle = ProcessWindowStyle.Hidden
startInfo.CreateNoWindow = True
Dim p As Process = New Process()
p.StartInfo = startInfo
p.StartInfo.UseShellExecute = False
p.StartInfo.RedirectStandardOutput = True
p.StartInfo.RedirectStandardError = True
p.Start()
Console.WriteLine(p.StandardOutput.ReadToEnd)
Console.WriteLine(p.StandardError.ReadToEnd)
p.WaitForExit()

Write code for execution time on C# Command Line Application

I want to have my program execute a bunch of commands on load-time and this is in C# btw, but it's a console program, how can I do that?
If you are trying to execute external applications from within your C# console application, see the ProcessStartInfo and Process class.
Example:
Process.Start("IExplore.exe", "www.google.com");
// -- OR --
ProcessStartInfo startInfo = new ProcessStartInfo("IExplore.exe");
startInfo.WindowStyle = ProcessWindowStyle.Maximized;
startInfo.Arguments = "www.google.com";
Process.Start(startInfo);

Categories

Resources