Tyrrrz / CliWrap

Library for running command-line processes
MIT License
4.32k stars 264 forks source link

Windows 11 throws exception for some arguments passed to SqlPackage #205

Closed argentini closed 1 year ago

argentini commented 1 year ago

Version

Latest

Details

Using CliWrap to execute Microsoft SqlPackage in a .NET 7 console application for this project: https://github.com/argentini/Argentini.SqlPkg. Working great on macOS but on Windows 11 (x64) I get an exception depending on the arguments used.

It seems to work with most arguments but specifically passing no arguments, or passing the help argument, seem to trigger the exception. Getting the version using that argument works, as do all others. This is very odd. When these are run in PowerShell it all works fine.

One more note: This occurs when installing and using the SqlPackage via the dotnet tool install. If I put the fully qualified path to an instance of SqlPackage.exe already on my drive in the Visual Studio path, that one works fine.

code

exception

The following alternative code works:

Process p;
p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.FileName = "sqlpackage.exe";
p.Start();
p.WaitForExit();

Steps to reproduce

Install SqlPackage as below then try calling it from CliWrap with no arguments using a Windows 11 x64 machine.

dotnet tool install -g microsoft.sqlpackage
Tyrrrz commented 1 year ago

Does that program consume stdin for anything? I think this happens because CliWrap always redirects all standard streams, and some programs may infer that if stdin is redirected, then the user intends to write something to it.

I'm not familiar with SqlPackage but maybe there's an argument you can pass to explicitly disable that behavior. Otherwise, you can try passing PipeSource.FromStream(Stream.Null) for the standard input pipe, but it will probably just result in a different error.

Also see #190, which might be a similar issue.

argentini commented 1 year ago

Hey @Tyrrrz thanks for the quick response! I did try handling the standard input in that way but I got the same result. I don't believe that SqlPackage bothers with standard input anyway; none of the docs indicate that you can pipe to it.

Attached here is a simple project that shows the failure. Just use the dotnet command below to install SqlPackage, and then run this project. You can easily uninstall SqlPackage with the same command and the word "uninstall" instead of "install".

dotnet tool install -g microsoft.sqlpackage

ConsoleApp1.zip

Tyrrrz commented 1 year ago

I was able to reproduce the error with the following minimal code:

using var process = new Process
{
    StartInfo = new ProcessStartInfo
    {
        FileName = "sqlpackage",
        RedirectStandardOutput = true,
        RedirectStandardError = true
    }
};

process.OutputDataReceived += (sender, args) =>
{
    if (args.Data is not null)
    {
        Console.WriteLine(args.Data);
    }
};

process.ErrorDataReceived += (sender, args) =>
{
    if (args.Data is not null)
    {
        Console.WriteLine(args.Data);
    }
};

process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();

process.WaitForExit();

Note that the error appears to only happen when both the output and error streams are redirected, but not when only one of them is.

All in all, this looks like either a bug within the Process class or inside the implementation of SqlPackage (which is more likely). I would recommend raising an issue with them, using the code snippet above. Since this issue is not specific to CliWrap (seeing as it's reproducible with raw Process), I'm going to close it.

argentini commented 1 year ago

Hey @Tyrrrz thanks for digging into this. I did place an issue with Microsoft about this, so we'll see what they say.

argentini commented 1 year ago

Hey @Tyrrrz I just got this update from Microsoft:

"This is fixed and will be in the August release. Let me know if you want to try it out earlier and we can release a preview version of Microsoft.SqlPackage."

Just thought you would want to know.

Tyrrrz commented 1 year ago

Great! @argentini