Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Process.Start() doesn't work in netcoreapp2.1 but good in 2.0 #1857

Closed
LincolnYang1 opened this issue Aug 14, 2018 · 5 comments
Closed

Process.Start() doesn't work in netcoreapp2.1 but good in 2.0 #1857

LincolnYang1 opened this issue Aug 14, 2018 · 5 comments

Comments

@LincolnYang1
Copy link

LincolnYang1 commented Aug 14, 2018

Process.Start() doesn't work in netcoreapp2.1 but good in 2.0

i have below simple code to demo the issue, it works well in netcoreapp2.0 but not in netcoreapp2.1
system is aws cloud,
Linux version 4.9.81-35.56.amzn1.x86_64 (mockbuild@gobi-build-64010) (gcc version 7.2.1 20170915 (Red Hat 7.2.1-2) (GCC) ) #1 SMP Fri Feb 16 00:18:48 UTC 2018

        static void Main(string[] args)
        {
            var fileName = args[0];
            Console.WriteLine($"{fileName} : exists: {File.Exists(fileName)}");
            
            var processStartInfo = new ProcessStartInfo(fileName)
            {
                Arguments = "--info",
                UseShellExecute = true
            };
            var process = Process.Start(processStartInfo) ?? throw new Exception("failed to start process");
            process.WaitForExit();
        }

run-time parameter is, /opt/dotnet/dotnet is the dotnet executable path
dotnet testapp.dll /opt/dotnet/dotnet

project file is

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.0</TargetFramework>
    <RuntimeIdentifiers>rhel.7.4-x64</RuntimeIdentifiers>
  </PropertyGroup>
</Project>

Build and Publish

if change project to 2.0, build and publish with dotnet core 2.0, it works fine.

dotnet build --runtime rhel.7.4-x64
dotnet publish --runtime rhel.7.4-x64 -c Release --framework netcoreapp2.0

but if change to 2.1
dotnet build --runtime rhel.7.4-x64
dotnet publish --runtime rhel.7.4-x64 -c Release --framework netcoreapp2.1

it throw error, there is Win32Exception throw out.

Unhandled Exception: System.ComponentModel.Win32Exception: No such file or directory
at System.Diagnostics.Process.StartCore(ProcessStartInfo startInfo)
at System.Diagnostics.Process.Start()
at System.Diagnostics.Process.Start(ProcessStartInfo startInfo)
at testapp.Program.Main(String[] args) in source\repos\testapp\testapp\Program.cs:line 14

@LincolnYang1
Copy link
Author

find some clue,
in 2.0, it use "/bin/sh" as shell, source: https://github.com/dotnet/corefx/blob/release/2.0.0/src/System.Diagnostics.Process/src/System/Diagnostics/Process.Unix.cs

private bool StartCore(ProcessStartInfo startInfo)
        {
            string filename;
            string[] argv;

            if (startInfo.UseShellExecute)
            {
                if (startInfo.RedirectStandardInput || startInfo.RedirectStandardOutput || startInfo.RedirectStandardError)
                {
                    throw new InvalidOperationException(SR.CantRedirectStreams);
                }

                const string ShellPath = "/bin/sh";

                filename = ShellPath;
                argv = new string[3] { ShellPath, "-c", startInfo.FileName + " " + startInfo.Arguments};

but in 2.1, it uses one of "xdg-open", "gnome-open", "kfmclient" to open file, this make "UseShellExecute" behave totally not same as 2.0
src: https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.Process/src/System/Diagnostics/Process.Linux.cs

        private string GetPathToOpenFile()
        {
            string[] allowedProgramsToRun = { "xdg-open", "gnome-open", "kfmclient" };
            foreach (var program in allowedProgramsToRun)
            {
                string pathToProgram = FindProgramInPath(program);
                if (!string.IsNullOrEmpty(pathToProgram))
                {
                    return pathToProgram;
                }
            }
            return null;
        }

@omajid
Copy link
Member

omajid commented Aug 14, 2018

For your case, you probably want to set UseShellExecute to false to run dotnet --info, or pretty much any other program. Unless you actually care about /bin/bash being used to invoke it? I can't see how that would be useful in your example.

@LincolnYang1
Copy link
Author

thanks for reply,
sample code just to demo inconsistency of UseShellExecute between 2.0 and 2.1, the actual code is more complicate and need UseShellExecute 2.0 feature,
after migrate to 2.1 it suddenly doesn't work, since "xdg-open", "gnome-open", "kfmclient" are not really shell, like /bin/sh and /bin/bash , does it make sense to obey its original definition?

@omajid
Copy link
Member

omajid commented Aug 14, 2018

@LincolnYang1 I suggest bringing it up here: https://github.com/dotnet/corefx/issues/24704. That's an ongoing discussion about this exact same issue.

In the meantime, can you invoke /bin/bash explicitly?

@Petermarcu
Copy link
Member

Yes, lets move this discussion to dotnet/corefx#24704. I'll close this one here.

rpetrusha pushed a commit to dotnet/dotnet-api-docs that referenced this issue Sep 26, 2018
* Clarify that ProcessStartInfo.UseShellExecute does not mean bash

The property name is very confusing on unix-like platforms. Anyone
familiar with unix-like platforms will probably assume it means
/bin/bash or /bin/sh. Clarify that it does not mean that shell and that
it refers to the conecpt of shell on Windows, which is closer in meaning
to "desktop".

For an example of this tripping up users, see:
dotnet/core#1857. For more on the
cross-platform inconsistencies of UseShellExecute, see
https://github.com/dotnet/corefx/issues/24704

* Update ProcessStartInfo.xml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants