У меня есть Pengwin (Linux дистрибутив, оптимизированный для работы с WSL - наверняка, все знают) с установленным github-лингвистом, настроенным в руководстве по https://github.com/github/linguist/blob/master/README.md. Даже я использовал свой экземпляр Windows Insider, изменил версию WSL на предстоящие 2, но все осталось как прежде.
В Pengwin и Powershell cmd все в порядке:
wsl bash -c "github-linguist '/mnt/d/Documents/Visual Studio 2017/Projects/LearnCss/LearnCss/Program.cs'"
Но при вызове в C # выводится пустой (любая другая команда, например, dir работает):
static PowershellBuilder builder = new PowershellBuilder();
/// <summary>
/// Tested, working
/// For every command return at least one entry in result
/// </summary>
/// <param name="commands"></param>
/// <returns></returns>
public async static Task<List< List<string>>> InvokeAsync(IEnumerable<string> commands)
{
List<List<string>> returnList = new List<List<string>>();
PowerShell ps = null;
// After leaving using is closed pipeline, must watch for complete or
using (ps = PowerShell.Create())
{
foreach (var item in commands)
{
ps.AddScript(item);
var async = ps.BeginInvoke();
// Return for SleepWithRandomOutputConsole zero outputs
var psObjects = ps.EndInvoke(async);
returnList.Add(ProcessPSObjects(psObjects));
}
}
return returnList;
}
/// <summary>
/// Tested, working
/// For every command return at least one entry in result
/// </summary>
/// <param name="commands"></param>
/// <returns></returns>
public static List<List<string>> Invoke(IEnumerable<string> commands)
{
var result = InvokeAsync(commands);
result.Wait();
return result.Result;
}
private static List<string> ProcessPSObjects(ICollection<PSObject> pso)
{
List<string> output = new List<string>();
foreach (var item in pso)
{
if (item != null)
{
output.Add(item.ToString());
}
}
return output;
}
public static List<string> InvokeSingle(string command)
{
return Invoke(CA.ToListString(command))[0];
}
Но при звонке с Process.Start
все работает как шарм:
/// <summary>
/// If in A1 will be full path specified = 'The system cannot find the file specified'
/// A1 if dont contains extension, append exe
/// </summary>
/// <param name="exeFileNameWithoutPath"></param>
/// <param name="arguments"></param>
/// <returns></returns>
public static List<string> InvokeProcess(string exeFileNameWithoutPath, string arguments)
{
FS.AddExtensionIfDontHave(exeFileNameWithoutPath, AllExtensions.exe);
//Create process
System.Diagnostics.Process pProcess = new System.Diagnostics.Process();
// Must contains only filename, not full path
pProcess.StartInfo.FileName = exeFileNameWithoutPath;
//strCommandParameters are parameters to pass to program
pProcess.StartInfo.Arguments = arguments;
pProcess.StartInfo.UseShellExecute = false;
//Set output of program to be written to process output stream
pProcess.StartInfo.RedirectStandardOutput = true;
//Optional, recommended do not enter, then old value is not deleted and both paths is combined
//pProcess.StartInfo.WorkingDirectory = ;
//Start the process
pProcess.Start();
W32.EnableWow64FSRedirection(true);
//Get program output
string strOutput = pProcess.StandardOutput.ReadToEnd();
//Wait for process to finish
pProcess.WaitForExit();
var result = SH.GetLines(strOutput);
return result;
}
Телефонный код:
const string lang = "language:";
public static string DetectLanguageForFileGithubLinguist(string windowsPath)
{
string command = null;
string arguments = null;
// With WSL or WSL 2 not working. In both cases Powershell returns right values but in c# everything empty. Asked on StackOverflow
StringBuilder linuxPath = new StringBuilder();
linuxPath.Append("/mnt/");
linuxPath.Append(windowsPath[0].ToString().ToLower());
var parts = SH.Split(windowsPath, AllStrings.bs);
for (int i = 1; i < parts.Count; i++)
{
linuxPath.Append("/" + parts[i]);
}
command = "wsl";
arguments = " bash -c \"github-linguist '" + linuxPath + "'\"";
W32.EnableWow64FSRedirection(false);
// empty
var pc = PowershellRunner.InvokeSingle("cmd /c bash -c 'ruby -v'");
// empty
var pc2 = PowershellRunner.InvokeSingle("wsl bash -c whoami");
// with content
var pc3 = PowershellRunner.InvokeSingle("dir");
//command = @"c:\Windows\System32\wsl.exe";
//arguments = " -- github-linguist \"/mnt/d/Documents/Visual Studio 2017/Projects/LearnCss/LearnCss/Program.cs\"";
// empty
var pc4 = PowershellRunner.InvokeSingle(command + arguments);
PowershellRunner.InvokeProcess(command + ".exe", arguments);
var lines = PowershellRunner.InvokeSingle(command);
var line = CA.ReturnWhichContains(lines, lang).FirstOrNull();
if (line == null)
{
return null;
}
var result = line.ToString().Replace(lang, string.Empty).Trim();
return result;
}
Почему вызов с PowerShell
классом не работает?