1717
1818using NDesk . Options ;
1919using System ;
20+ using System . Collections . Generic ;
2021using System . IO ;
2122using System . Linq ;
2223using 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