Giter Site home page Giter Site logo

medallionshell's People

Contributors

madelson avatar nsdfxela avatar stephanvs avatar xjfnet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

medallionshell's Issues

Timeout reached as part of the CommandResult

Hello,

it would be nice to have the information if the timeout was reached and the process had to be killed. For example a bool called TimeoutReached as part of the CommandResult.

Make Command awaitable

Today you can await Command.Task, but it would be nice if you could just await Command

Consider API for running a Command such that it will re-start on failure

This can be useful when managing long-running processes.

See #26 as an example use-case.

Likely this would be implemented via a new option (RestartOnFailure(bool)). In such a case the ProcessId of the Command could change so we'd have to make sure that downstream IO and Pipe commands also pick up this change.

One weird thing is data being written to StdIn which could get split across process instances if the process crashes half-way through a write. Perhaps we could try to ensure that we'd always break on newline?

RunToEndAsync API

A common point of confusion with the library is that Run() does not wait for the process to exit. RunToEnd() would both help in cases where you just want to one-off run something without piping. Also, its presence in the API would hopefully help clue users into the true nature of Run().

Need to think about the best name here. RunToCompletionAsync()? RunAndWaitForExitAsync()?

Operator overloading

This library looks very useful, but I am extremely leery of the operator overloading. C# operators are defined to have specific meanings, and changing their meaning solely in the context of this library makes the code much less readable (even for someone who knows shell scripting). I would recommend using a fluent syntax instead (x.Pipe(), x.Redirect(), etc.). Clearly only my two cents.

Support for process restart

Hi,

Is there any graceful way to restart a process that has for example been interrupted with Command.Kill (or by outside circumstances)?

Currently we're setting DisposeOnExit to false, and calling Command.Process.Start again. This works, but stdout/stderror redirection no longer works.

My question is, is there a better way, or is there a way to re-attach the output buffering internals if our Process.Start() hack is the recommended way forward?

netstandard 2.0, net46 builds

We'll want net46 to take advantage of SafeHandle as much as possible, and with netstandard 2.0 .NET Core consumers can start leveraging environment variables.

Interacting with long running processes

Hi,

We're considering using MedallionShell to interact with what is essentially a daemon process that will never really "finish."

We'd like to keep the handle open and interact with it as needed, however, the methods in the documentation seem mostly suited towards one off commands that will eventually finish.

Does MedallionShell support what we're trying to do? If yes, are there any examples available anywhere?

I apologize for opening this as an issue on the repo , but I couldn't really find documentation for this.

Thank you.

Can't figure out what I am doin wrong

I posted a question to codeducky asking what I am doing wrong. The response suggested I post my code here. I am trying to open pianobar, read the prompts in as strings and respond with commands. Ultimately I would like to use this on a embedded version. I apologize in advance, I am most comfortable
in vb.net.

Here is what is supposed to happen:

image

Here is what happens

image

As you can see I can read the output, but the write stream never seems to deliver it's it line.

I am missing some key step that is obvious to everyone but me.

Imports System
Imports System.IO
Imports System.Diagnostics
Imports System.Threading
Imports Medallion
Imports Medallion.Shell

Module Module1

Private PianoStart As ProcessStartInfo
Private Piano As Medallion.Shell.Command
Private PianoTask As Task

Private LastMsg As String = ""
Private WaitForInput As Boolean = False

Private ReadStream As Medallion.Shell.Streams.ProcessStreamReader
Private WriteStream As Medallion.Shell.Streams.ProcessStreamWriter

Private processthrd As Thread
Private ReadThread As Thread
Private WriteThread As Thread

Sub Main()
    processthrd = New Thread(AddressOf StartPiano)
    processthrd.Start()
End Sub

Private Sub StartPiano()
    Try

        Piano = Command.Run("""C:\Program Files (x86)\pianobar\pianobar.exe""")

        ReadStream = Piano.StandardOutput
        WriteStream = Piano.StandardInput

        WriteStream.AutoFlush = True

        ReadThread = New Thread(AddressOf ReadOutPut)
        ReadThread.Start()
        Piano.Wait()
    Catch ex As Exception
        Console.WriteLine(ex.Message)
        Console.ReadLine()
    Finally
        Piano.Kill()
    End Try

End Sub

Private Sub ReadOutPut()
    Dim msg As String
    While Not IsNothing(Piano)
        msg = ReadStream.ReadLine()
        If msg <> "" Then
            LastMsg = msg
            Console.WriteLine(msg)
            WriteThread = New Thread(AddressOf RespondToOutput)
            WriteThread.Start(msg)
        End If
    End While
End Sub

Private Sub RespondToOutput(msg As String)
    msg = Trim(msg)
    Select Case msg
        Case "[?] Email:"
            MsgBox("Address Called")
            WriteStream.Flush()
            WriteStream.WriteLine("[email protected]" & vbCrLf)
            WriteStream.Flush()
        Case "[?] Password:"
            MsgBox("Password Called")
            WriteStream.WriteLine("password" & vbCrLf)
        Case Else
            WriteStream.WriteLine("?")
    End Select
End Sub

End Module

Command.StandardOutput.ReadLine() is unreadable

var line = cmd.StandardOuput.ReadLine();

line is unreadable : "?????????????"

using(var sr = new StreamReader(cmd.StandardOutput.BaseStream, Encoding.Default))
{
    var line = sr.ReadLine();
}

line is readable : "some unicode char"

MemoryStream trouble on Mono

Terrific library.

Potentially obscure question... I was just testing input redirection similar to this example:
var cmd = Command.Run("path_to_grep", "some REGEX") < new FileInfo("some path") > lines;
but from a memory stream.

On Windows, when the executable I'm running fails, it fails beautifully -- the expected exit code is returned, and stderr gets stored in cmd.StandardError.

However, on Ubuntu using mono, I get a FileStream.Write exception instead. Any idea what might be causing this, and whether there's a workaround?

Thanks! Exception details below.

Jon

System.IO.IOException: Write fault on path /opt/myfolder/[Unknown]
at System.IO.FileStream.WriteInternal (System.Byte[] src, Int32 offset, Int32 count) [0x00000] in :0
at System.IO.FileStream.Write (System.Byte[] array, Int32 offset, Int32 count) [0x00000] in :0
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in :0
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00000] in :0
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00000] in :0
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00000] in :0
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult () [0x00000] in :0
at Medallion.Shell.Streams.ProcessStreamWriter+<>c__DisplayClass2+<b__0>d__4.MoveNext () [0x00000] in :0
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in :0
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00000] in :0
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00000] in :0
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00000] in :0
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult () [0x00000] in :0
at Medallion.Shell.Streams.PipeHelpers+d__a.MoveNext () [0x00000] in :0
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in :0
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00000] in :0
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00000] in :0
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00000] in :0
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult () [0x00000] in :0
at Medallion.Shell.IoCommand+d__0.MoveNext () [0x00000] in :0
Void ThrowIfExceptional(Boolean)

Overriding ToString to output exact process and arguments on Command

Hi, first of thanks for the great library, already saved me a lot of time for automating lots of small tasks.

I'm however finding for debugging purposes wanting to output the started process including the given arguments when I do a Command.Run()..

I could obviously do it myself, but I think it would make sense if the ToString on Command is overridden to return the actual command that'll be executed. What do you think about this idea, or is there already another way to achieve the same result?

So if I do;

var cmd = Command.Run("path_to_grep", "some REGEX");
cmd.ToString(); // --> This would equal "path_to_grep some REGEX"

It should obviously use the CommandLineSyntax if one is configured in the options.

Thanks again.
Stephan

NuGet package adds many unnecessary dependencies on .NET Core

Hi, I'm using the 1.6.0 version of this lib from NuGet, in a netcore22 app. On this platform the NuGet package adds a dependency to System.Diagnostics.Process 4.3.0, which in turns adds many netfx dependencies. That seem a bit unnecessary to me, since Process and its dependencies are already in the core framework. The extra DLLs about quadrupled the size of my final package.
Is the dependency to System.Diagnostics.Process 4.3.0 necessary?

Readme : add Linux command line example?

Hi!

This works great for me in windows dotnet core apps but I cannot get the syntax right for running bash commands, I keep getting 'file not found errors'.

Could we have one or two bash command examples, maybe running apt-get or ifconfig or something?

Reduce thread usage in pipelining

The following test runs very quickly with the min thread count elevated (e. g. 32) and very slowly without (e. g. 16). I believe that this is because the underlying streams open in a non-async way which means that our piping consumes thread, possibly more threads than it needs to due to how async is implemented:

        [Test]
        public void TestPipeline()
        {
            ThreadPool.SetMinThreads(100, 100);
            const int ProcessCount = 10;

            var pipeline = Enumerable.Range(0, ProcessCount)
                .Select(_ => TestShell.Run(SampleCommand, "pipebytes"))
                .Aggregate((first, second) => first | second);
            try
            {
                for (var i = 0; i < 10; ++i)
                {
                    char @char = (char)('a' + i);

                    pipeline.StandardInput.AutoFlush.ShouldEqual(true);
                    var writeTask = pipeline.StandardInput.WriteAsync(@char);
                    writeTask.Wait(TimeSpan.FromSeconds(30)).ShouldEqual(true, $"write {i} should complete");

                    var buffer = new char[10];
                    var readTask = pipeline.StandardOutput.ReadAsync(buffer, 0, buffer.Length);
                    readTask.Wait(TimeSpan.FromSeconds(30)).ShouldEqual(true, $"read {i} should complete");
                    readTask.Result.ShouldEqual(1);
                    buffer[0].ShouldEqual(@char);
                }

                pipeline.StandardInput.Dispose();
                pipeline.Task.Wait(TimeSpan.FromSeconds(30)).ShouldEqual(true, "pipeline should exit");
            }
            finally
            {
                pipeline.Kill();
            }
        }

// in program.cs

                case "pipebytes":
                    using (var standardInput = Console.OpenStandardInput())
                    using (var standardOutput = Console.OpenStandardOutput())
                    {
                        var buffer = new byte[10];
                        while (true)
                        {
                            var bytesRead = standardInput.Read(buffer, 0, buffer.Length);
                            if (bytesRead == 0) { break; }
                            standardOutput.Write(buffer, 0, bytesRead);
                            standardOutput.Flush();
                        }
                    }
                    break;

Ways to fix could be trying to get the pipes to switch over to async, or even just using non-async reads/flushes to avoid extra thread use.

Command.StandardOutput.ReadToEnd() hangs every time

    Process.GetProcessesByName("adb").ToList().ForEach(x => x.Kill());
    var arguments = new List<string> { "connect", "127.0.0.1:21503" };
    var command = Command.Run("adb.exe", arguments,
        options => options.Timeout(TimeSpan.FromMinitues(1)));
    var output = command.StandardOutput.ReadToEnd();
    var error = command.StandardError.ReadToEnd();

adb.exe is is Android Debug Bridge

  1. the code snippet hangs every time with adb.exe version 1.0.31
  2. options.Timeout does not work, the underline process still running after 1 minute
  3. the code snippet works well with adb.exe version 1.0.39

Does not throw on error for when process returns with exit code 1

Hello Again!

While continuing to work on the same project as my previous, I experienced a problem with iptables where due to incorrect syntax of that program's flags, medallion did not throw on error.

We wrote a simple test case to test this out with basic system commands that would respectively throw exit 1 for windows' powershell and linux's top.

        [Test]
        public void TestThrowOnError()
        {
            try
            {
                var cmd = Command.Run(AppConfig.isUnix ? "top" : "powershell", new[] {"--testing"}, options: o => o.ThrowOnError());
                Assert.Fail();
            }
            catch (Exception exception)
            {
                // Error means that the command execution broke. 
                Assert.Pass();
            }
        }

Is there a correct way to throw to the specification of ThrowOnError, or an suggestion you can provide?

Thanks,
Andrew.

Strong-name MedallionShell 2.0

See #65 for context.

In 1.x we maintain MedallionShell.StrongName separately for backwards compat. In 2.x we can strong-name the main release.

System.IO.IOException: The directory is not empty from TemporaryExeFile.Dispose()

Hi there!
We catch a lot of exceptions on a machine with slow HDD(Azure).
It's very simple to reproduce on the machine like we have in Azure, but impossible on local machine.
I assume the reason is OS can not free resources so fast.

System.IO.IOException: The directory is not empty.

   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.Directory.DeleteHelper(String fullPath, String userPath, Boolean recursive, Boolean throwOnTopLevelDirectoryNotFound, WIN32_FIND_DATA& data)
   at System.IO.Directory.Delete(String fullPath, String userPath, Boolean recursive, Boolean checkHost)
   at Medallion.Shell.Signals.WindowsProcessSignaler.**TemporaryExeFile.Dispose()**
   at Medallion.Shell.Signals.WindowsProcessSignaler.<TrySignalAsync>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Medallion.Shell.Command.<>c__DisplayClass16_0.<<TrySignalAsync>g__TrySignalHelperAsync|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

I suggest using "try catch" and two attempts

            public void Dispose()
            {
                var toDelete = Interlocked.Exchange(ref this._path, null);
                if (toDelete != null)
                {
                   this.Cleanup(toDelete);
                }
            }

            private void Cleanup(string toDelete, bool firstAttempt = true)
            {
                try
                {
                    File.Delete(toDelete);
                    Directory.Delete(System.IO.Path.GetDirectoryName(toDelete));
                }
                catch (IOException)
                {
                    if (firstAttempt)
                    {
                        Task.Delay(0).GetAwaiter().GetResult();
                        this.Cleanup(toDelete, false);
                    }
                }
            }

Thx!

Provide support for CTRL+C / CTRL+BREAK

Create a helper method for preventing inheritance of the current process's standard IO handles

This is useful prior to launching a process that will outlast the current process. The problem is that if the current process is using standard IO, then the child process will inherit those handles such that even if the current process exits the standard IO pipes will not finish. This leads to hangs.

One fix for this is to be able to launch processes with a fixed set of inheritable handles (#54). However, this would require re-implementing much of Process.

A less extreme version is to simply modify our own standard IO handles to prevent further inheritance.

Here's example code for Windows:

void Main()
{
       var handle = GetStdHandle(-10);
       GetStdHandle(-10).Dump("handle again");
       int info = 0;
       if (!GetHandleInformation(handle, ref info))
       {
              Marshal.GetLastWin32Error().Dump("err");
       }
       info.Dump("orig info");
       if (!SetHandleInformation(handle, 1, 0))
       {
              Marshal.GetLastWin32Error().Dump("err set");
       }
       if (!GetHandleInformation(handle, ref info))
       {
              Marshal.GetLastWin32Error().Dump("err");
       }
       info.Dump("new info");
       handle.Dump("handle");
}

[DllImport("kernel32.dll")]
static extern IntPtr GetStdHandle(int nStdHandle);

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool GetHandleInformation(IntPtr hObject, ref int lpdwFlags);

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool SetHandleInformation(IntPtr hObject, int dwMask, int dwFlags);

On Linux, we can approximate this by preventing inheritance past exec. See https://stackoverflow.com/questions/6599420/linux-how-to-mark-a-file-descriptor-as-not-inheritable-on-fork

Passing arugments in the form of --argument="output"

What passing arguments to medallion shell I can only seem to be able to get parse "--command=output", rather than the common form --command="output".

Is this a possibility in medallion shell, or this way of passing arguments not supported?

Cannot read from closed reader on result

I am spawning a command and forwarding streams to text readers. I thought I could additionally retrieve the standard output, even though it has been forwarder, from the command result. However doing so raises an ObjectDisposedException.

Medallion.Shell.Command shellCommand = Medallion.Shell.Command.Run(
	executable: command.Program,
	arguments: command.ArgumentValues,
	options: opt =>
	{
		opt.Syntax(new NullSyntax());
	});
	
shellCommand = shellCommand.RedirectStandardErrorTo(Console.Error);
shellCommand = shellCommand.RedirectTo(outputWriter);

shellCommand.Wait();

Medallion.Shell.CommandResult result = shellCommand.Result;

// ObjectDisposedException - cannot read from a closed text reader.
var r = result.StandardOutput;

The work around I found was to forward the standard output to another StringWriter and build the output from there.

Strong naming MedallionShell assembly

I've been using MedallionShell to run commands from a new application I'm developing at work, and it's been awesome! However, I'm migrating my project out of its own repo and into my org's main codebase, which means I need all dependencies to be strong-name signed. Would it be possible to do a strong-name signed release of the MedallionShell binaries?

I'm more than happy to contribute this change if that's preferable. Please let me know if this is how you'd like to proceed.

How to start new Shell as administrator/root?

Hi There,
This issue may be specific to my use case, but I'm looking for some assistance.

I scoped through a bit of the code to see if I can find anything related to executing a process with either runas or sudo depending on the operating system, however was unable to find anything and cannot use the StartInfo.Verb property as it seems to not exist in my scope.

Do you have any suggestions for how I should go about accomplishing this?

Thanks.

System.IO.IOException: Write fault on path /[Unknown]

In the case of providing an invalid option to a cmd-line tool, I would except to receive the cmd's exit code of 1 (in this case, running ffmpeg via Xamarin.Android), instead an IOException thrown.

FYI: When ffmpeg is provided the correct option(s) and/or a media file that it can transcode, MedallionShell works great on Xamarin.Android (thanks ๐Ÿ˜€ )

Example code:

var cmd = Command.Run(ffmpegPath, (new string[]
{
"-hide_banner",
"-some_invalid_option",
}), ((options) =>
{
	options.WorkingDirectory(workingDir);
}));
var tasks = new List<Task>
{
	cmd.Task,
	cmd.StandardOutput.PipeToAsync(stdOutCollection),
	cmd.StandardError.PipeToAsync(stdErrCollection)
};
Task.WaitAll(tasks.ToArray());
exitCode = cmd.Result.ExitCode;

Note: stdOutCollection/stdErrCollection are ObservableCollections

Exception/Stacktrace:

[MonoDroid] System.IO.IOException: Write fault on path /[Unknown]
[MonoDroid]   at System.IO.FileStream.WriteInternal (System.Byte[] src, System.Int32 offset, System.Int32 count) [0x00077] in <fa70666c4440451cb5ca34569f933bb4>:0 
[MonoDroid]   at System.IO.FileStream.Write (System.Byte[] array, System.Int32 offset, System.Int32 count) [0x00090] in <fa70666c4440451cb5ca34569f933bb4>:0 
[MonoDroid]   at System.IO.StreamWriter.Flush (System.Boolean flushStream, System.Boolean flushEncoder) [0x00042] in <fa70666c4440451cb5ca34569f933bb4>:0 
[MonoDroid]   at System.IO.StreamWriter.set_AutoFlush (System.Boolean value) [0x00010] in <fa70666c4440451cb5ca34569f933bb4>:0 
[MonoDroid]   at System.Diagnostics.Process.StartWithCreateProcess (System.Diagnostics.ProcessStartInfo startInfo) [0x00353] in <5a97d41d36694fb19855c17429527b10>:0 
[MonoDroid]   at System.Diagnostics.Process.Start () [0x0003a] in <5a97d41d36694fb19855c17429527b10>:0 
[MonoDroid]   at (wrapper remoting-invoke-with-check) System.Diagnostics.Process.Start()
[MonoDroid]   at Medallion.Shell.ProcessCommand..ctor (System.Diagnostics.ProcessStartInfo startInfo, System.Boolean throwOnError, System.Boolean disposeOnExit, System.TimeSpan timeout, System.Threading.CancellationToken cancellationToken, System.Text.Encoding standardInputEncoding) [0x0004a] in <dcb0641c39fd4991a9750bcbbb6f72ce>:0 
[MonoDroid]   at Medallion.Shell.Shell.Run (System.String executable, System.Collections.Generic.IEnumerable`1[T] arguments, System.Action`1[T] options) [0x000f6] in <dcb0641c39fd4991a9750bcbbb6f72ce>:0 
[MonoDroid]   at Medallion.Shell.Command.Run (System.String executable, System.Collections.Generic.IEnumerable`1[T] arguments, System.Action`1[T] options) [0x00005] in <dcb0641c39fd4991a9750bcbbb6f72ce>:0 
[MonoDroid]   at GifVideo.MainActivity+<>c__DisplayClass2_0.<OnCreate>b__4 () [0x00088] in /Volumes/Code/code/Projects/GifVideo/GifVideo/MainActivity.cs:72 
[MonoDroid]   at System.Threading.Tasks.Task.InnerInvoke () [0x0000f] in <fa70666c4440451cb5ca34569f933bb4>:0 
[MonoDroid]   at System.Threading.Tasks.Task.Execute () [0x00010] in <fa70666c4440451cb5ca34569f933bb4>:0 
[MonoDroid] --- End of stack trace from previous location where exception was thrown ---
[MonoDroid]   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <fa70666c4440451cb5ca34569f933bb4>:0 
[MonoDroid]   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <fa70666c4440451cb5ca34569f933bb4>:0 
[MonoDroid]   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <fa70666c4440451cb5ca34569f933bb4>:0 
[MonoDroid]   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <fa70666c4440451cb5ca34569f933bb4>:0 
[MonoDroid]   at System.Runtime.CompilerServices.TaskAwaiter.GetResult () [0x00000] in <fa70666c4440451cb5ca34569f933bb4>:0 
[MonoDroid]   at GifVideo.MainActivity+<>c__DisplayClass2_0+<<OnCreate>b__2>d.MoveNext () [0x00048] in /Volumes/Code/code/Projects/GifVideo/GifVideo/MainActivity.cs:47 
[MonoDroid] --- End of stack trace from previous location where exception was thrown ---
[MonoDroid]   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <fa70666c4440451cb5ca34569f933bb4>:0 
[MonoDroid]   at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state) [0x00000] in <fa70666c4440451cb5ca34569f933bb4>:0 
[MonoDroid]   at Android.App.SyncContext+<>c__DisplayClass2_0.<Post>b__0 () [0x00000] in <f7bb669be1a3453caf7f53a12b803ea2>:0 
[MonoDroid]   at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in <f7bb669be1a3453caf7f53a12b803ea2>:0 
[MonoDroid]   at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in <f7bb669be1a3453caf7f53a12b803ea2>:0 
[MonoDroid]   at (wrapper dynamic-method) System.Object.c7921d6c-67df-4e70-810d-9325c40be88e(intptr,intptr)

Failing to run sudo in shell

Hello again,
This issue follows after #24 and I am seeking more help.

I've created a class to handle attributes that I can later specify to medallion shell in a task-manager like fashion called comamndHolder, and processOptions.
I have a condition where if the current operating system is Linux, and the ProcessOptions has a parameter called InvokeAsSuperuser is true, it makes the application run as the superuser.

Unfortunately an exception is thrown explicitly stating that the command or file cannot be found with the following code and output:

// Code
var commandHolder = new CommandHolder
    {
        Options = processOptions,
        Caller = caller,
        // MEDALLION STARTS HERE.
        Command = new Shell(
            e => e.ThrowOnError()
        ).Run("/usr/bin/sudo",
            arguments: argumentArray,
            options: o => o
                .DisposeOnExit(processOptions.DisposeOnExit)
                .WorkingDirectory(processOptions.WorkingDirectory)
        )
    };
# Output
dbug: Project.Libraries.Services.ServiceManager[0]
      OpenVPN was found: /usr/sbin/openvpn
dbug: Project.Libraries.Core.ProcessRunner.ProcessRunner[0]
      Built arugment array: /usr/sbin/openvpn /tmp/74197e20-71a9-4e70-a2b9-b5f92ac36feb.ovpn
fail: Project.Libraries.Services.ServiceManager[0]
      ACTION_FAILED
System.ComponentModel.Win32Exception (2): No such file or directory

If this were to be expressed in a console, I would expect

$ /usr/bin/sudo /usr/sbin/openvpn /tmp/74197e20-71a9-4e70-a2b9-b5f92ac36feb.ovpn

And for my own sanity I have checked that these paths are valid.


By any chance would you have any idea or suggestions to test? This issue seems specific to the sudo command and passing arguments, and works inside of a normal Process.Start() call from my standpoint.

Regards,
Andrew H.

Default syntax adds unexpected quotes

Hello. I ran into an issue where I'm trying to execute a command with quotes:

Running: sudo -H -u root -s bash -c "apt-get update -y"

but the default syntax added quotes in the inner command, making it fail on Ubuntu:

Ran: sudo -H -u root -s bash -c "\"apt-get" update "-y\""

fortunately the options let me set up my own implementation of syntax (I am managing escaping myself) but the method is deprecated. Maybe it would be nice to un-deprecate it? :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.