add .exe shims for programs that only look for .exes (e.g. tar calling gzip)

This commit is contained in:
Luke Sampson
2014-01-05 16:25:16 +10:00
parent e728188909
commit 5c52166fcd
5 changed files with 94 additions and 2 deletions

1
.gitattributes vendored
View File

@@ -1,2 +1,3 @@
# retain windows line-endings in case checked out on mac or linux
* text eol=crlf
*.exe -text

View File

@@ -80,8 +80,12 @@ function shim($path, $global) {
echo "`$path = '$path'" >> $shim
echo 'if($myinvocation.expectingInput) { $input | & $path @args } else { & $path @args }' >> $shim
if($path -match '\.((exe)|(bat)|(cmd))$') {
# shim .exe, .bat, .cmd so they can be used by programs with no awareness of PSH
if($path -match '\.exe$') {
# for programs with no awareness of any shell
cp "$(versiondir 'scoop' 'current')\supporting\shimexe\shim.exe" "$(strip_ext($shim)).exe" -force
echo "path = $(resolve-path $path)" | out-file "$(strip_ext($shim)).shim" -encoding oem
} elseif($path -match '\.((bat)|(cmd))$') {
# shim .bat, .cmd so they can be used by programs with no awareness of PSH
$shim_cmd = "$(strip_ext($shim)).cmd"
':: ensure $HOME is set for MSYS programs' | out-file $shim_cmd -encoding oem
'@if "%home%"=="" set home=%homedrive%%homepath%\' | out-file $shim_cmd -encoding oem -append

View File

@@ -0,0 +1,3 @@
$fwdir = gci C:\Windows\Microsoft.NET\Framework\ -dir | sort -desc | select -first 1
& "$($fwdir.fullname)\csc.exe" /nologo shim.cs

View File

@@ -0,0 +1,84 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace shim {
class Program {
static int Main(string[] args) {
var exe = Assembly.GetExecutingAssembly().Location;
var dir = Path.GetDirectoryName(exe);
var name = Path.GetFileNameWithoutExtension(exe);
var configPath = Path.Combine(dir, name + ".shim");
if(!File.Exists(configPath)) {
Console.Error.WriteLine("Couldn't find " + Path.GetFileName(configPath) + " in " + dir);
return 1;
}
var config = Config(configPath);
var path = Get(config, "path");
var p = new Process();
p.StartInfo.FileName = path;
p.StartInfo.Arguments = Serialize(args);
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardOutput = true;
p.Start();
ReadChars(p.StandardOutput, Console.Out);
ReadChars(p.StandardError, Console.Error);
p.WaitForExit();
return p.ExitCode;
}
// Once stdout or stderr starts sending, keep forwarding the stream to the console
// until it stops sending. Otherwise the output from both streams is mixed up.
static object sync = new object();
static async void ReadChars(StreamReader r, TextWriter sendTo) {
var buffer = new char[100];
while(true) {
var read = await r.ReadAsync(buffer, 0, buffer.Length);
lock(sync) { // prevent other streams from writing
while(true) {
sendTo.Write(buffer, 0, read);
if(read < buffer.Length) break; // release lock
read = r.Read(buffer, 0, buffer.Length);
}
if(read == 0) return; // EOF
}
}
}
static string Serialize(string[] args) {
return string.Join(" ", args.Select(a => a.Contains(' ') ? '"' + a + '"' : a));
}
static string Get(Dictionary<string, string> dic, string key) {
string value = null;
dic.TryGetValue(key, out value);
return value;
}
static Dictionary<string, string> Config(string path) {
var config = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
foreach(var line in File.ReadAllLines(path)) {
var m = Regex.Match(line, @"([^=]+)=(.*)");
if(m.Success) {
config[m.Groups[1].Value.Trim()] = m.Groups[2].Value.Trim();
}
}
return config;
}
}
}

BIN
supporting/shimexe/shim.exe Normal file

Binary file not shown.