File: Installer.cs

package info (click to toggle)
mysql-connector-net 6.4.3-4
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 6,160 kB
  • ctags: 8,552
  • sloc: cs: 63,689; xml: 7,505; sql: 345; makefile: 50; ansic: 40
file content (209 lines) | stat: -rw-r--r-- 8,473 bytes parent folder | download | duplicates (2)
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// MySQL Connector/NET is licensed under the terms of the GPLv2
// <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most 
// MySQL Connectors. There are special exceptions to the terms and 
// conditions of the GPLv2 as it is applied to this software, see the 
// FLOSS License Exception
// <http://www.mysql.com/about/legal/licensing/foss-exception.html>.
//
// This program is free software; you can redistribute it and/or modify 
// it under the terms of the GNU General Public License as published 
// by the Free Software Foundation; version 2 of the License.
//
// This program is distributed in the hope that it will be useful, but 
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
// for more details.
//
// You should have received a copy of the GNU General Public License along 
// with this program; if not, write to the Free Software Foundation, Inc., 
// 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA

#if !MONO && !PocketPC

using System.Configuration.Install;
using System.ComponentModel;
using System.Reflection;
using System;
using Microsoft.Win32;
using System.Xml;
using System.IO;
using System.Diagnostics;
using System.Security;
using System.Security.Permissions;

namespace MySql.Data.MySqlClient
{
	/// <summary>
	/// We are adding a custom installer class to our assembly so our installer
	/// can make proper changes to the machine.config file.
	/// </summary>
    [RunInstaller(true)]
    [PermissionSetAttribute(SecurityAction.InheritanceDemand, Name = "FullTrust")]
    [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
    public class CustomInstaller : Installer
	{
        /// <summary>
        /// We override Install so we can add our assembly to the proper
        /// machine.config files.
        /// </summary>
        /// <param name="stateSaver"></param>
        public override void Install(System.Collections.IDictionary stateSaver)
        {
            base.Install(stateSaver);
            AddProviderToMachineConfig();
        }

        private static void AddProviderToMachineConfig()
        {
            object installRoot = Registry.GetValue(
                @"HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\",
                "InstallRoot", null);
            if (installRoot == null)
                throw new Exception("Unable to retrieve install root for .NET framework");
            UpdateMachineConfigs(installRoot.ToString(), true);

            string installRoot64 = installRoot.ToString();
            installRoot64 = installRoot64.Substring(0, installRoot64.Length - 1);
            installRoot64 = string.Format("{0}64{1}", installRoot64,
                Path.DirectorySeparatorChar);
            if (Directory.Exists(installRoot64))
                UpdateMachineConfigs(installRoot64, true);
        }

        private static void UpdateMachineConfigs(string rootPath, bool add)
        {
            string[] dirs = new string[2] { "v2.0.50727", "v4.0.30319" };
            foreach (string frameworkDir in dirs)
            {
                string path = rootPath + frameworkDir;

                string configPath = String.Format(@"{0}\CONFIG", path);
                if (Directory.Exists(configPath))
                {
                    if (add)
                        AddProviderToMachineConfigInDir(configPath);
                    else
                        RemoveProviderFromMachineConfigInDir(configPath);
                }
            }
        }

        private static void AddProviderToMachineConfigInDir(string path)
        {
            string configFile = String.Format(@"{0}\machine.config", path);
            if (!File.Exists(configFile)) return;

            // now read the config file into memory
            StreamReader sr = new StreamReader(configFile);
            string configXML = sr.ReadToEnd();
            sr.Close();

            // load the XML into the XmlDocument
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(configXML);

            // create our new node
            XmlElement newNode = (XmlElement)doc.CreateNode(XmlNodeType.Element, "add", "");

            // add the proper attributes
            newNode.SetAttribute("name", "MySQL Data Provider");
            newNode.SetAttribute("invariant", "MySql.Data.MySqlClient");
            newNode.SetAttribute("description", ".Net Framework Data Provider for MySQL");

            // add the type attribute by reflecting on the executing assembly
            Assembly a = Assembly.GetExecutingAssembly();
            string type = String.Format("MySql.Data.MySqlClient.MySqlClientFactory, {0}", a.FullName.Replace("Installers", "Data"));
            newNode.SetAttribute("type", type);

            XmlNodeList nodes = doc.GetElementsByTagName("DbProviderFactories");

            foreach (XmlNode node in nodes[0].ChildNodes)
            {
                if (node.Attributes == null) continue;
                foreach (XmlAttribute attr in node.Attributes)
                {
                    if (attr.Name == "invariant" && attr.Value == "MySql.Data.MySqlClient")
                    {
                        nodes[0].RemoveChild(node);
                        break;
                    }
                }
            }

            nodes[0].AppendChild(newNode);

            // Save the document to a file and auto-indent the output.
            XmlTextWriter writer = new XmlTextWriter(configFile, null);
            writer.Formatting = Formatting.Indented;
            doc.Save(writer);
            writer.Flush();
            writer.Close();
        }

        /// <summary>
        /// We override Uninstall so we can remove out assembly from the
        /// machine.config files.
        /// </summary>
        /// <param name="savedState"></param>
        public override void Uninstall(System.Collections.IDictionary savedState)
        {
            base.Uninstall(savedState);
            RemoveProviderFromMachineConfig();
        }

        private static void RemoveProviderFromMachineConfig()
        {
            object installRoot = Registry.GetValue(
                @"HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\",
                "InstallRoot", null);
            if (installRoot == null)
                throw new Exception("Unable to retrieve install root for .NET framework");
            UpdateMachineConfigs(installRoot.ToString(), false);

            string installRoot64 = installRoot.ToString();
            installRoot64 = installRoot64.Substring(0, installRoot64.Length - 1);
            installRoot64 = string.Format("{0}64{1}", installRoot64,
                Path.DirectorySeparatorChar);
            if (Directory.Exists(installRoot64))
                UpdateMachineConfigs(installRoot64, false);
        }

        private static void RemoveProviderFromMachineConfigInDir(string path)
        {
            string configFile = String.Format(@"{0}\machine.config", path);
            if (!File.Exists(configFile)) return;

            // now read the config file into memory
            StreamReader sr = new StreamReader(configFile);
            string configXML = sr.ReadToEnd();
            sr.Close();

            // load the XML into the XmlDocument
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(configXML);

            XmlNodeList nodes = doc.GetElementsByTagName("DbProviderFactories");
            foreach (XmlNode node in nodes[0].ChildNodes)
            {
                if (node.Attributes == null) continue;
                string name = node.Attributes["name"].Value;
                if (name == "MySQL Data Provider")
                {
                    nodes[0].RemoveChild(node);
                    break;
                }
            }

            // Save the document to a file and auto-indent the output.
            XmlTextWriter writer = new XmlTextWriter(configFile, null);
            writer.Formatting = Formatting.Indented;
            doc.Save(writer);
            writer.Flush();
            writer.Close();
        }
    }
}

#endif