private void CompileWithMidl(DllFileParameters parameters, string batchPath)
        {
            var targetPath = Path.Combine(Path.GetTempPath(), "RubberduckMidl");

            if (Directory.Exists(targetPath))
            {
                Directory.Delete(targetPath, true);
            }
            Directory.CreateDirectory(targetPath);

            targetPath = targetPath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);

            var command = $"call \"{batchPath}\"{Environment.NewLine}" +
                          $"midl.exe /win32 /tlb \"{parameters.Tlb32File}\" \"{parameters.IdlFile}\" /out \"{targetPath}\"{Environment.NewLine}" +
                          $"midl.exe /amd64 /tlb \"{parameters.Tlb64File}\" \"{parameters.IdlFile}\" /out \"{targetPath}\"";

            ExecuteTask(command, SourceDir);

            MoveFileWithOverwrite(Path.Combine(targetPath, parameters.Tlb32File), Path.Combine(TargetDir, parameters.Tlb32File));
            MoveFileWithOverwrite(Path.Combine(targetPath, parameters.Tlb64File), Path.Combine(TargetDir, parameters.Tlb64File));

            try
            {
                Directory.Delete(targetPath, true);
            }
            catch (Exception ex)
            {
                this.LogMessage($"Unable to delete temporary working directory: {targetPath}. Exception: {ex}");
            }
        }
        private void CreateIdlFile(DllFileParameters parameters)
        {
            var generator = new IdlGenerator();
            var idl       = generator.GenerateIdl(parameters.SourceDll);

            File.WriteAllText(Path.Combine(TargetDir, parameters.IdlFile), idl, new UTF8Encoding(true));
        }
        private void ProcessDll(string file, string batchPath)
        {
            this.LogMessage($"Processing {file}...");

            var parameters = new DllFileParameters(file, SourceDir, TargetDir);

            if (string.IsNullOrWhiteSpace(batchPath))
            {
                this.LogMessage("Compiling with tlbexp...");
                CompileWithTlbExp(parameters);
            }
            else
            {
                this.LogMessage("Compiling with midl...");
                CreateIdlFile(parameters);
                CompileWithMidl(parameters, batchPath);
            }

            this.LogMessage("Extracting metadata using WiX...");
            HarvestMetadataWithWixToFile(parameters);

            this.LogMessage("Building registry entries...");
            var entries = BuildRegistryEntriesFromMetadata(parameters);

            this.LogMessage("Creating InnoSetup registry entries...");
            CreateInnoSetupRegistryFile(entries, parameters);

            if (Config != "Debug")
            {
                return;
            }

            RemovePreviousDebugRegistration();
            UpdateDebugRegistration(entries, parameters);
        }
        private void HarvestMetadataWithWixToFile(DllFileParameters parameters)
        {
            var command = $"\"{WixToolsDir}heat.exe\" file \"{parameters.SourceDll}\" -out \"{parameters.DllXml}\"";

            ExecuteTask(command);

            command = $"\"{WixToolsDir}heat.exe\" file \"{parameters.SourceTlb32}\" -out \"{parameters.TlbXml}\"";
            ExecuteTask(command);
        }
        private void CompileWithTlbExp(DllFileParameters parameters)
        {
            var command = $"\"{NetToolsDir}tlbexp.exe\" \"{parameters.SourceDll}\" /win32 /out:\"{parameters.SourceTlb32}\"";

            ExecuteTask(command);

            command = $"\"{NetToolsDir}tlbexp.exe\" \"{parameters.SourceDll}\" /win64 /out:\"{parameters.SourceTlb64}\"";
            ExecuteTask(command);
        }
        private void UpdateDebugRegistration(IOrderedEnumerable <RegistryEntry> entries, DllFileParameters parameters)
        {
            this.LogMessage($"Updating debug build reigstration for {parameters.DllFile}");

            // NOTE: The local writer will perform the actual registry changes; the return
            // is a registry script with deletion instructions for the keys to be deleted
            // in the next build.
            var writer = new LocalDebugRegistryWriter();

            writer.CurrentPath = TargetDir;
            var content = writer.Write(entries, parameters.DllFile, parameters.Tlb32File, parameters.Tlb64File);

            File.AppendAllText(RegFilePath, content, Encoding.ASCII);
        }
        private void CreateInnoSetupRegistryFile(IOrderedEnumerable <RegistryEntry> entries, DllFileParameters parameters)
        {
            var writer  = new InnoSetupRegistryWriter();
            var content = writer.Write(entries, parameters.DllFile, parameters.Tlb32File, parameters.Tlb64File);
            var regFile = Path.Combine(IncludeDir, parameters.DllFile.Replace(".dll", ".reg.iss"));

            // To use unicode with InnoSetup, encoding must be UTF8 BOM
            File.WriteAllText(regFile, content, new UTF8Encoding(true));
        }
        private IOrderedEnumerable <RegistryEntry> BuildRegistryEntriesFromMetadata(DllFileParameters parameters)
        {
            var builder = new RegistryEntryBuilder();

            return(builder.Parse(parameters.TlbXml, parameters.DllXml));
        }