aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core/Unbinder.cs
blob: 2ff5199758318ebb7bb672898acf9e32d85c0efb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.

namespace WixToolset.Core
{
    using System.Collections;
    using System.IO;
    using WixToolset.Data;
    using WixToolset.Extensibility;
    using System.Collections.Generic;

    /// <summary>
    /// Unbinder core of the WiX toolset.
    /// </summary>
    public sealed class Unbinder
    {
        private TableDefinitionCollection tableDefinitions;
        private ArrayList unbinderExtensions;
        // private TempFileCollection tempFiles;

        /// <summary>
        /// Creates a new unbinder object with a default set of table definitions.
        /// </summary>
        public Unbinder()
        {
            this.tableDefinitions = new TableDefinitionCollection(WindowsInstallerStandard.GetTableDefinitions());
            this.unbinderExtensions = new ArrayList();
        }

        public IEnumerable<IBackendFactory> BackendFactories { get; }

        /// <summary>
        /// Gets or sets whether the input msi is an admin image.
        /// </summary>
        /// <value>Set to true if the input msi is part of an admin image.</value>
        public bool IsAdminImage { get; set; }

        /// <summary>
        /// Gets or sets the option to suppress demodularizing values.
        /// </summary>
        /// <value>The option to suppress demodularizing values.</value>
        public bool SuppressDemodularization { get; set; }

        /// <summary>
        /// Gets or sets the option to suppress extracting cabinets.
        /// </summary>
        /// <value>The option to suppress extracting cabinets.</value>
        public bool SuppressExtractCabinets { get; set; }

        /// <summary>
        /// Gets or sets the temporary path for the Binder.  If left null, the binder
        /// will use %TEMP% environment variable.
        /// </summary>
        /// <value>Path to temp files.</value>
        public string TempFilesLocation => Path.GetTempPath();

        /// <summary>
        /// Adds extension data.
        /// </summary>
        /// <param name="data">The extension data to add.</param>
        public void AddExtensionData(IExtensionData data)
        {
            if (null != data.TableDefinitions)
            {
                foreach (TableDefinition tableDefinition in data.TableDefinitions)
                {
                    if (!this.tableDefinitions.Contains(tableDefinition.Name))
                    {
                        this.tableDefinitions.Add(tableDefinition);
                    }
                    else
                    {
                        Messaging.Instance.OnMessage(WixErrors.DuplicateExtensionTable(data.GetType().ToString(), tableDefinition.Name));
                    }
                }
            }
        }

        /// <summary>
        /// Adds an extension.
        /// </summary>
        /// <param name="extension">The extension to add.</param>
        public void AddExtension(IUnbinderExtension extension)
        {
            this.unbinderExtensions.Add(extension);
        }

        /// <summary>
        /// Unbind a Windows Installer file.
        /// </summary>
        /// <param name="file">The Windows Installer file.</param>
        /// <param name="outputType">The type of output to create.</param>
        /// <param name="exportBasePath">The path where files should be exported.</param>
        /// <returns>The output representing the database.</returns>
        public Output Unbind(string file, OutputType outputType, string exportBasePath)
        {
            if (!File.Exists(file))
            {
                if (OutputType.Transform == outputType)
                {
                    throw new WixException(WixErrors.FileNotFound(null, file, "Transform"));
                }
                else
                {
                    throw new WixException(WixErrors.FileNotFound(null, file, "Database"));
                }
            }

            // if we don't have the temporary files object yet, get one
            Directory.CreateDirectory(this.TempFilesLocation); // ensure the base path is there

            var context = new UnbindContext();
            context.InputFilePath = file;
            context.ExportBasePath = exportBasePath;
            context.IntermediateFolder = this.TempFilesLocation;
            context.IsAdminImage = this.IsAdminImage;
            context.SuppressDemodularization = this.SuppressDemodularization;
            context.SuppressExtractCabinets = this.SuppressExtractCabinets;

            foreach (var factory in this.BackendFactories)
            {
                if (factory.TryCreateBackend(outputType.ToString(), file, null, out var backend))
                {
                    return backend.Unbind(context);
                }
            }

            // TODO: Display message that could not find a unbinder for output type?

            return null;
        }
    }
}