Skip to content

Commit 7886994

Browse files
committed
Added code to dump what classes are available if the one you specify isn't valid for the assembly.
1 parent ce3b01c commit 7886994

1 file changed

Lines changed: 79 additions & 7 deletions

File tree

DotNetToJScript/Program.cs

Lines changed: 79 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
using NDesk.Options;
1919
using System;
20+
using System.Collections.Generic;
2021
using System.IO;
2122
using System.Linq;
2223
using System.Reflection;
@@ -70,11 +71,11 @@ class Program
7071
</package>
7172
";
7273

73-
static object BuildLoaderDelegate(string dll_path)
74+
static object BuildLoaderDelegate(byte[] assembly)
7475
{
7576
// Create a bound delegate which will load our assembly from a byte array.
7677
Delegate res = Delegate.CreateDelegate(typeof(XmlValueGetter),
77-
File.ReadAllBytes(dll_path),
78+
assembly,
7879
typeof(Assembly).GetMethod("Load", new Type[] { typeof(byte[]) }));
7980

8081
// Create a COM invokable delegate to call the loader. Abuses contra-variance
@@ -83,10 +84,10 @@ static object BuildLoaderDelegate(string dll_path)
8384
return new HeaderHandler(res.DynamicInvoke);
8485
}
8586

86-
static object BuildLoaderDelegateMscorlib(string dll_path)
87+
static object BuildLoaderDelegateMscorlib(byte[] assembly)
8788
{
8889
Delegate res = Delegate.CreateDelegate(typeof(Converter<byte[], Assembly>),
89-
File.ReadAllBytes(dll_path),
90+
assembly,
9091
typeof(Assembly).GetMethod("Load", new Type[] { typeof(byte[]), typeof(byte[]) }));
9192

9293
HeaderHandler d = new HeaderHandler(Convert.ToString);
@@ -131,14 +132,44 @@ static string CreateScriptlet(string script, bool register_script)
131132
return Encoding.UTF8.GetString(stm.ToArray());
132133
}
133134
}
135+
136+
static HashSet<string> GetValidClasses(byte[] assembly)
137+
{
138+
Assembly asm = Assembly.Load(assembly);
139+
return new HashSet<string>(asm.GetTypes().Where(t => t.IsPublic && t.GetConstructor(new Type[0]) != null).Select(t => t.FullName));
140+
}
141+
142+
static void WriteColor(string str, ConsoleColor color)
143+
{
144+
ConsoleColor old_color = Console.ForegroundColor;
145+
Console.ForegroundColor = color;
146+
try
147+
{
148+
Console.Error.WriteLine(str);
149+
}
150+
finally
151+
{
152+
Console.ForegroundColor = old_color;
153+
}
154+
}
155+
156+
static void WriteError(string str)
157+
{
158+
WriteColor(str, ConsoleColor.Red);
159+
}
160+
161+
static void WriteError(string format, params object[] args)
162+
{
163+
WriteError(String.Format(format, args));
164+
}
134165

135166
static void Main(string[] args)
136167
{
137168
try
138169
{
139170
if (Environment.Version.Major != 2)
140171
{
141-
Console.Error.WriteLine("This tool only works on v2 of the CLR");
172+
WriteError("This tool only works on v2 of the CLR");
142173
Environment.Exit(1);
143174
}
144175

@@ -165,14 +196,43 @@ static void Main(string[] args)
165196
if (!File.Exists(assembly_path) || show_help)
166197
{
167198
Console.Error.WriteLine(@"Usage: DotNetToJScript [options] path\to\asm");
199+
Console.Error.WriteLine("Copyright (C) James Forshaw 2017. Licensed under GPLv3.");
168200
Console.Error.WriteLine("Options");
169201
opts.WriteOptionDescriptions(Console.Error);
170202
Environment.Exit(1);
171203
}
172204

205+
byte[] assembly = File.ReadAllBytes(assembly_path);
206+
try
207+
{
208+
HashSet<string> valid_classes = GetValidClasses(assembly);
209+
if (!valid_classes.Contains(entry_class_name))
210+
{
211+
WriteError("Error: Class '{0}' not found is assembly.", entry_class_name);
212+
if (valid_classes.Count == 0)
213+
{
214+
WriteError("Error: Assembly doesn't contain any public, default constructable classes");
215+
}
216+
else
217+
{
218+
WriteError("Use one of the follow options to specify a valid classes");
219+
foreach (string name in valid_classes)
220+
{
221+
WriteError("-c {0}", name);
222+
}
223+
}
224+
Environment.Exit(1);
225+
}
226+
}
227+
catch (Exception)
228+
{
229+
WriteError("Error: loading assembly information.");
230+
WriteError("The generated script might not work correctly");
231+
}
232+
173233
BinaryFormatter fmt = new BinaryFormatter();
174234
MemoryStream stm = new MemoryStream();
175-
fmt.Serialize(stm, mscorlib_only ? BuildLoaderDelegateMscorlib(assembly_path) : BuildLoaderDelegate(assembly_path));
235+
fmt.Serialize(stm, mscorlib_only ? BuildLoaderDelegateMscorlib(assembly) : BuildLoaderDelegate(assembly));
176236

177237
byte[] ba = stm.ToArray();
178238
StringBuilder builder = new StringBuilder();
@@ -205,7 +265,19 @@ static void Main(string[] args)
205265
}
206266
catch (Exception ex)
207267
{
208-
Console.Error.WriteLine(ex.Message);
268+
ReflectionTypeLoadException tex = ex as ReflectionTypeLoadException;
269+
if (tex != null)
270+
{
271+
WriteError("Couldn't load assembly file");
272+
foreach (var e in tex.LoaderExceptions)
273+
{
274+
WriteError(e.Message);
275+
}
276+
}
277+
else
278+
{
279+
WriteError(ex.Message);
280+
}
209281
}
210282
}
211283
}

0 commit comments

Comments
 (0)