using System.IO;
using System.Diagnostics;
using System.Text;
-using System.Reflection;
using System.Collections;
using System.Globalization;
using System.Runtime.InteropServices;
using Mono.Security;
using Mono.Security.Cryptography;
+using IKVM.Reflection;
+
namespace Mono.Tools {
public class Driver {
private static bool silent;
static bool in_bootstrap;
+ private static Universe _universe;
public static int Main (string [] args)
{
AssemblyName an = null;
try {
- assembly = Assembly.LoadFrom (name);
+ assembly = ReflectionOnlyLoadFrom (name);
} catch {
WriteLine (string.Format (failure_msg, name) + "The file specified is not a valid assembly.");
return false;
Copy (name, asmb_path, true);
+ var name_pdb = Path.ChangeExtension (name, ".pdb");
+ if (File.Exists (name_pdb)) {
+ Copy (name_pdb, Path.ChangeExtension (asmb_path, ".pdb"), true);
+ }
+
foreach (string ext in siblings) {
string sibling = String.Concat (name, ext);
if (File.Exists (sibling))
Environment.Exit (1);
}
if (Path.DirectorySeparatorChar == '/') {
- string pkg_path = "../gac/" + an.Name + "/" + version_token + "/" + asmb_file;
+ string pkg_path_abs = Path.Combine (gacdir, Path.Combine (an.Name, Path.Combine (version_token, asmb_file)));
+ string pkg_path = AbsoluteToRelativePath (ref_dir, pkg_path_abs);
symlink (pkg_path, ref_path);
+ var pdb_pkg_path = Path.ChangeExtension (pkg_path, ".pdb");
+ var pdb_ref_path = Path.ChangeExtension (ref_path, ".pdb");
+
+ if (File.Exists (pdb_pkg_path)) {
+ symlink (pdb_pkg_path, pdb_ref_path);
+ } else {
+ try {
+ File.Delete (pdb_ref_path);
+ } catch {
+ // Ignore error, just delete files that should not be there.
+ }
+ }
+
foreach (string ext in siblings) {
string sibling = String.Concat (pkg_path, ext);
string sref = String.Concat (ref_path, ext);
+
if (File.Exists (sibling))
symlink (sibling, sref);
else {
return true;
}
+ //from MonoDevelop.Core.FileService
+ unsafe static string AbsoluteToRelativePath (string baseDirectoryPath, string absPath)
+ {
+ if (!Path.IsPathRooted (absPath) || string.IsNullOrEmpty (baseDirectoryPath))
+ return absPath;
+
+ absPath = Path.GetFullPath (absPath);
+ baseDirectoryPath = Path.GetFullPath (baseDirectoryPath).TrimEnd (Path.DirectorySeparatorChar);
+
+ fixed (char* bPtr = baseDirectoryPath, aPtr = absPath) {
+ var bEnd = bPtr + baseDirectoryPath.Length;
+ var aEnd = aPtr + absPath.Length;
+ char* lastStartA = aEnd;
+ char* lastStartB = bEnd;
+
+ int indx = 0;
+ // search common base path
+ var a = aPtr;
+ var b = bPtr;
+ while (a < aEnd) {
+ if (*a != *b)
+ break;
+ if (IsSeparator (*a)) {
+ indx++;
+ lastStartA = a + 1;
+ lastStartB = b;
+ }
+ a++;
+ b++;
+ if (b >= bEnd) {
+ if (a >= aEnd || IsSeparator (*a)) {
+ indx++;
+ lastStartA = a + 1;
+ lastStartB = b;
+ }
+ break;
+ }
+ }
+ if (indx == 0)
+ return absPath;
+
+ if (lastStartA >= aEnd)
+ return ".";
+
+ // handle case a: some/path b: some/path/deeper...
+ if (a >= aEnd) {
+ if (IsSeparator (*b)) {
+ lastStartA = a + 1;
+ lastStartB = b;
+ }
+ }
+
+ // look how many levels to go up into the base path
+ int goUpCount = 0;
+ while (lastStartB < bEnd) {
+ if (IsSeparator (*lastStartB))
+ goUpCount++;
+ lastStartB++;
+ }
+ var size = goUpCount * 2 + goUpCount + aEnd - lastStartA;
+ var result = new char [size];
+ fixed (char* rPtr = result) {
+ // go paths up
+ var r = rPtr;
+ for (int i = 0; i < goUpCount; i++) {
+ *(r++) = '.';
+ *(r++) = '.';
+ *(r++) = Path.DirectorySeparatorChar;
+ }
+ // copy the remaining absulute path
+ while (lastStartA < aEnd)
+ *(r++) = *(lastStartA++);
+ }
+ return new string (result);
+ }
+ }
+
+ static bool IsSeparator (char ch)
+ {
+ return ch == Path.DirectorySeparatorChar || ch == Path.AltDirectorySeparatorChar || ch == Path.VolumeSeparatorChar;
+ }
+
private static void Uninstall (string name, string package, string gacdir, string libdir, bool listMode, ref int uninstalled, ref int failures)
{
string [] assembly_pieces = name.Split (new char[] { ',' });
if (File.Exists (Path.Combine (dir, assembly_name + ".dll"))) {
extension = ".dll";
- } else if (File.Exists (Path.Combine (dir, assembly_name + ".DLL"))) {
- extension = ".DLL";
} else if (File.Exists (Path.Combine (dir, assembly_name + ".exe"))) {
extension = ".exe";
- } else if (File.Exists (Path.Combine (dir, assembly_name + ".EXE"))) {
- extension = ".EXE";
} else {
failures++;
WriteLine("Cannot find the assembly: " + assembly_name);
}
}
+ private static Universe GetUniverse () {
+ if (_universe == null) {
+ _universe = new Universe (UniverseOptions.MetadataOnly);
+ }
+ return _universe;
+ }
+
+ private static Assembly ReflectionOnlyLoadFrom (string fileName)
+ {
+ return GetUniverse ().LoadFile (fileName);
+ }
+ private static AssemblyName GetCorlibName ()
+ {
+ return GetUniverse ().Mscorlib.GetName ();
+ }
+
private static bool CheckReferencedAssemblies (AssemblyName an)
{
- AppDomain d = null;
try {
- Assembly a = Assembly.LoadFrom (an.CodeBase);
- AssemblyName corlib = typeof (object).Assembly.GetName ();
+ Assembly a = ReflectionOnlyLoadFrom (an.CodeBase);
+ AssemblyName corlib = GetCorlibName ();
foreach (AssemblyName ref_an in a.GetReferencedAssemblies ()) {
if (ref_an.Name == corlib.Name) // Just do a string compare so we can install on diff versions
} catch (Exception e) {
WriteLine (e.ToString ()); // This should be removed pre beta3
return false;
- } finally {
- if (d != null) {
- try {
- AppDomain.Unload (d);
- } catch { }
- }
}
return true;
static bool LoadConfig (bool quiet)
{
- MethodInfo config = typeof (System.Environment).GetMethod ("GetMachineConfigPath",
- BindingFlags.Static | BindingFlags.NonPublic);
+ System.Reflection.MethodInfo config = typeof (System.Environment).GetMethod ("GetMachineConfigPath",
+ System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
if (config != null) {
string path = (string) config.Invoke (null, null);
// Note: MustVerify is based on the original token (by design). Public key
// remapping won't affect if the assembly is verified or not.
- if (StrongNameManager.MustVerify (an)) {
+ if (StrongNameManager.MustVerify (new System.Reflection.AssemblyName (an.FullName))) {
RSA rsa = CryptoConvert.FromCapiPublicKeyBlob (publicKey, 12);
StrongName sn = new StrongName (rsa);
if (sn.Verify (assemblyFile)) {
private static bool IsSwitch (string arg)
{
- return (arg [0] == '-' || (arg [0] == '/' && !arg.EndsWith (".dll") && arg.IndexOf ('/', 1) < 0 ) );
+ return (arg [0] == '-' || (arg [0] == '/' && !arg.EndsWith (".dll") && !arg.EndsWith (".exe") && arg.IndexOf ('/', 1) < 0 ) );
}
private static Command GetCommand (string arg)
public static extern int symlink (string oldpath, string newpath);
private static string GetGacDir () {
- PropertyInfo gac = typeof (System.Environment).GetProperty ("GacPath",
- BindingFlags.Static|BindingFlags.NonPublic);
+ System.Reflection.PropertyInfo gac = typeof (System.Environment).GetProperty ("GacPath",
+ System.Reflection.BindingFlags.Static|System.Reflection.BindingFlags.NonPublic);
if (gac == null) {
WriteLine ("ERROR: Mono runtime not detected, please use " +
"the mono runtime for gacutil.exe");
Environment.Exit (1);
}
- MethodInfo get_gac = gac.GetGetMethod (true);
+ System.Reflection.MethodInfo get_gac = gac.GetGetMethod (true);
return (string) get_gac.Invoke (null, null);
}
private static string GetLibDir () {
- MethodInfo libdir = typeof (System.Environment).GetMethod ("internalGetGacPath",
- BindingFlags.Static|BindingFlags.NonPublic);
+ System.Reflection.MethodInfo libdir = typeof (System.Environment).GetMethod ("internalGetGacPath",
+ System.Reflection.BindingFlags.Static|System.Reflection.BindingFlags.NonPublic);
if (libdir == null) {
WriteLine ("ERROR: Mono runtime not detected, please use " +
"the mono runtime for gacutil.exe");