예제 #1
0
        public static int Main(string[] args)
        {
            var env = new RewriterEnvironment();

            try
            {
                // Collect command line args
                var cl = new RewriterCommandLine(env.Log, env);
                cl.MergeFromArgs(args);

                if (string.IsNullOrEmpty(env.RewriteFileName))
                {
                    env.Log(new UsageMessage("-rewrite"));
                    throw new ExitException();
                }

                if (string.IsNullOrEmpty(env.OutputFileName))
                {
                    env.Log(new UsageMessage("-out"));
                    throw new ExitException();
                }

                var inFileName  = Path.GetFullPath(Path.Combine(env.InputDirectory, env.RewriteFileName));
                var outFileName = Path.GetFullPath(env.OutputFileName);

                var parentFolder = Path.GetDirectoryName(outFileName);
                if (!string.IsNullOrEmpty(parentFolder) && !Directory.Exists(parentFolder))
                {
                    Directory.CreateDirectory(parentFolder);
                }


                var writeFileName = outFileName;
                if (writeFileName.Equals(inFileName, StringComparison.OrdinalIgnoreCase))
                {
                    writeFileName = Path.Combine(parentFolder, outFileName + ".rewritten");
                }

                // Load all assemblies
                var allFileNames = env.ReferenceFileNames.ToSeq();
                allFileNames.Add(inFileName);
                var loader   = new AssemblyLoader(env);
                var mscorlib = default(Cci.AssemblyNode);
                var jsTypes  = default(Cci.AssemblyNode);

                // Find the assembly to rewrite
                loader.Load(allFileNames, out mscorlib, out jsTypes);
                var rewriteAssembly = loader.Find(env.RewriteFileName);

                env.Setup(mscorlib, jsTypes, rewriteAssembly);
                try
                {
                    // Rewrite
                    var rewriter          = new Rewriter(env);
                    var rewrittenAssembly = rewriter.RewriteAssembly(rewriteAssembly);
                    if (rewrittenAssembly != null)
                    {
                        // Save
                        if (env.DelaySign && env.KeyFile == null && rewrittenAssembly.PublicKeyOrToken != null)
                        {
                            if (
                                !rewrittenAssembly.Attributes.Where
                                    (a => a.Type.IsAssignableTo(env.AssemblyDelaySignAttributeType)).Any())
                            {
                                var attribute = env.InteropTypes.InstantiateAttribute
                                                    (env.AssemblyDelaySignAttributeType, Literal.True);
                                rewrittenAssembly.Attributes.Add(attribute);
                            }
                        }
                        else if (env.KeyFile != null)
                        {
                            if (!TrySignAssembly(env, rewrittenAssembly, env.KeyFile, env.DelaySign))
                            {
                                rewrittenAssembly.PublicKeyOrToken = null;
                                if ((rewrittenAssembly.Flags & AssemblyFlags.PublicKey) != 0)
                                {
                                    rewrittenAssembly.Flags = rewrittenAssembly.Flags & ~AssemblyFlags.PublicKey;
                                }
                            }
                        }

                        try
                        {
                            rewrittenAssembly.WriteModule(writeFileName, true);
                            env.Log(new SavedAssemblyMessage(rewriteAssembly.StrongName, writeFileName));
                        }
                        catch (IOException e)
                        {
                            env.Log
                                (new IOFailureMessage
                                    (outFileName,
                                    String.Format("save assembly '{0}'", rewrittenAssembly.StrongName),
                                    e));
                            throw new ExitException();
                        }
                        catch (UnauthorizedAccessException e)
                        {
                            env.Log
                                (new IOFailureMessage
                                    (outFileName,
                                    String.Format("save assembly '{0}'", rewrittenAssembly.StrongName),
                                    e));
                            throw new ExitException();
                        }
                    }
                }
                finally
                {
                    env.Teardown();
                }

                rewriteAssembly.Dispose();
                Cci.SystemTypes.Clear();

                if (!writeFileName.Equals(outFileName, StringComparison.OrdinalIgnoreCase))
                {
                    try
                    {
                        File.Copy(writeFileName, outFileName, true);
                        File.Delete(writeFileName);
                        env.Log(new CopiedFileMessage(writeFileName, outFileName));
                    }
                    catch (IOException e)
                    {
                        env.Log
                            (new IOFailureMessage
                                (outFileName,
                                String.Format("copy from '{0}'", writeFileName),
                                e));
                        throw new ExitException();
                    }
                    catch (UnauthorizedAccessException e)
                    {
                        env.Log
                            (new IOFailureMessage
                                (outFileName,
                                String.Format("copy from '{0}'", writeFileName),
                                e));
                        throw new ExitException();
                    }
                }
            }
            catch (ExitException)
            {
                // No-op
            }
            catch (Exception e)
            {
                Console.WriteLine("Internal error: {0}", e.Message);
                Console.WriteLine("Please report this error to the developers");
                env.NumErrors++;
            }
            finally
            {
                Console.WriteLine("{0} errors, {1} warnings", env.NumErrors, env.NumWarnings);
            }
            return(env.NumErrors == 0 ? 0 : 1);
        }