Skip to content

Commit 5697c29

Browse files
authored
Sources for System.Configuration.Install' (#145)
1 parent b80fa34 commit 5697c29

17 files changed

+3016
-0
lines changed

System.Configuration.Install/AssemblyInstaller.cs

Lines changed: 499 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//------------------------------------------------------------------------------
2+
// <copyright file="ComponentInstaller.cs" company="Microsoft">
3+
// Copyright (c) Microsoft Corporation. All rights reserved.
4+
// </copyright>
5+
//------------------------------------------------------------------------------
6+
7+
/*
8+
*/
9+
namespace System.Configuration.Install {
10+
using System.ComponentModel;
11+
using System.Diagnostics;
12+
using System;
13+
using System.Windows.Forms;
14+
15+
/// <include file='doc\ComponentInstaller.uex' path='docs/doc[@for="ComponentInstaller"]/*' />
16+
/// <devdoc>
17+
/// <para>[To be supplied.]</para>
18+
/// </devdoc>
19+
public abstract class ComponentInstaller : Installer {
20+
21+
/// <include file='doc\ComponentInstaller.uex' path='docs/doc[@for="ComponentInstaller.CopyFromComponent"]/*' />
22+
/// <devdoc>
23+
/// Copies properties from the given component to this installer. This method
24+
/// will be called at design-time when the user clicks 'Add Installer' on a
25+
/// component that has specified this class as its installer. The installer
26+
/// should take all information it can from the live component and store it
27+
/// to be used at install time.
28+
/// </devdoc>
29+
public abstract void CopyFromComponent(IComponent component);
30+
31+
/// <include file='doc\ComponentInstaller.uex' path='docs/doc[@for="ComponentInstaller.IsEquivalentInstaller"]/*' />
32+
/// <devdoc>
33+
/// <para>[To be supplied.]</para>
34+
/// </devdoc>
35+
public virtual bool IsEquivalentInstaller(ComponentInstaller otherInstaller) {
36+
return false;
37+
}
38+
}
39+
40+
}
Lines changed: 295 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
//------------------------------------------------------------------------------
2+
// <copyright file="EventLogInstaller.cs" company="Microsoft">
3+
// Copyright (c) Microsoft Corporation. All rights reserved.
4+
// </copyright>
5+
//------------------------------------------------------------------------------
6+
7+
/*
8+
*/
9+
namespace System.Diagnostics {
10+
using System.ComponentModel;
11+
using System.Diagnostics;
12+
using System;
13+
using System.Collections;
14+
using Microsoft.Win32;
15+
using System.Configuration.Install;
16+
using System.Globalization;
17+
using System.Security.Permissions;
18+
using System.Runtime.InteropServices;
19+
20+
/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller"]/*' />
21+
/// <devdoc>
22+
/// This class acts as an installer for the EventLog component. Essentially, it calls
23+
/// EventLog.CreateEventSource.
24+
/// </devdoc>
25+
public class EventLogInstaller : ComponentInstaller {
26+
27+
private EventSourceCreationData sourceData = new EventSourceCreationData(null, null);
28+
private UninstallAction uninstallAction = System.Configuration.Install.UninstallAction.Remove;
29+
30+
/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller.CategoryResourceFile"]/*' />
31+
[
32+
TypeConverter("System.Diagnostics.Design.StringValueConverter, " + AssemblyRef.SystemDesign),
33+
Editor("System.Windows.Forms.Design.FileNameEditor, " + AssemblyRef.SystemDesign, "System.Drawing.Design.UITypeEditor, " + AssemblyRef.SystemDrawing),
34+
ComVisible(false),
35+
ResDescription(Res.Desc_CategoryResourceFile)
36+
]
37+
public string CategoryResourceFile {
38+
get {
39+
return sourceData.CategoryResourceFile;
40+
}
41+
set {
42+
sourceData.CategoryResourceFile = value;
43+
}
44+
}
45+
46+
/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller.CategoryCount"]/*' />
47+
[
48+
ComVisible(false),
49+
ResDescription(Res.Desc_CategoryCount)
50+
]
51+
public int CategoryCount {
52+
get {
53+
return sourceData.CategoryCount;
54+
}
55+
set {
56+
sourceData.CategoryCount = value;
57+
}
58+
}
59+
60+
61+
/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller.Log"]/*' />
62+
/// <devdoc>
63+
/// The log in which the source will be created
64+
/// </devdoc>
65+
[
66+
TypeConverter("System.Diagnostics.Design.StringValueConverter, " + AssemblyRef.SystemDesign),
67+
ResDescription(Res.Desc_Log)
68+
]
69+
public string Log {
70+
get {
71+
if (sourceData.LogName == null && sourceData.Source != null)
72+
// they've told us a source, but they haven't told us a log name.
73+
// try to deduce the log name from the source name.
74+
sourceData.LogName = EventLog.LogNameFromSourceName(sourceData.Source, ".");
75+
return sourceData.LogName;
76+
}
77+
set {
78+
sourceData.LogName = value;
79+
}
80+
}
81+
82+
/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller.MessageResourceFile"]/*' />
83+
[
84+
TypeConverter("System.Diagnostics.Design.StringValueConverter, " + AssemblyRef.SystemDesign),
85+
Editor("System.Windows.Forms.Design.FileNameEditor, " + AssemblyRef.SystemDesign, "System.Drawing.Design.UITypeEditor, " + AssemblyRef.SystemDrawing),
86+
ComVisible(false),
87+
ResDescription(Res.Desc_MessageResourceFile)
88+
]
89+
public string MessageResourceFile {
90+
get {
91+
return sourceData.MessageResourceFile;
92+
}
93+
set {
94+
sourceData.MessageResourceFile = value;
95+
}
96+
}
97+
98+
/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller.ParameterResourceFile"]/*' />
99+
[
100+
TypeConverter("System.Diagnostics.Design.StringValueConverter, " + AssemblyRef.SystemDesign),
101+
Editor("System.Windows.Forms.Design.FileNameEditor, " + AssemblyRef.SystemDesign, "System.Drawing.Design.UITypeEditor, " + AssemblyRef.SystemDrawing),
102+
ComVisible(false),
103+
ResDescription(Res.Desc_ParameterResourceFile)
104+
]
105+
public string ParameterResourceFile {
106+
get {
107+
return sourceData.ParameterResourceFile;
108+
}
109+
set {
110+
sourceData.ParameterResourceFile = value;
111+
}
112+
}
113+
114+
115+
/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller.Source"]/*' />
116+
/// <devdoc>
117+
/// The source to be created
118+
/// </devdoc>
119+
[
120+
TypeConverter("System.Diagnostics.Design.StringValueConverter, " + AssemblyRef.SystemDesign),
121+
ResDescription(Res.Desc_Source)
122+
]
123+
public string Source {
124+
get {
125+
return sourceData.Source;
126+
}
127+
set {
128+
sourceData.Source = value;
129+
}
130+
}
131+
132+
/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller.UninstallAction"]/*' />
133+
/// <devdoc>
134+
/// Determines whether the event log is removed at uninstall time.
135+
/// </devdoc>
136+
[DefaultValue(UninstallAction.Remove),
137+
ResDescription(Res.Desc_UninstallAction)
138+
]
139+
public UninstallAction UninstallAction {
140+
get {
141+
return uninstallAction;
142+
}
143+
set {
144+
if (!Enum.IsDefined(typeof(UninstallAction), value))
145+
throw new InvalidEnumArgumentException("value", (int)value, typeof(UninstallAction));
146+
147+
uninstallAction = value;
148+
}
149+
}
150+
151+
/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller.CopyFromComponent"]/*' />
152+
/// <devdoc>
153+
/// A method on ComponentInstaller that lets us copy properties.
154+
/// </devdoc>
155+
public override void CopyFromComponent(IComponent component) {
156+
EventLog log = component as EventLog;
157+
158+
if (log == null)
159+
throw new ArgumentException(Res.GetString(Res.NotAnEventLog));
160+
161+
if (log.Log == null || log.Log == string.Empty || log.Source == null || log.Source == string.Empty) {
162+
throw new ArgumentException(Res.GetString(Res.IncompleteEventLog));
163+
}
164+
165+
Log = log.Log;
166+
Source = log.Source;
167+
}
168+
169+
/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller.Install"]/*' />
170+
/// <devdoc>
171+
/// Called when we should perform the install. Inherited from Installer.
172+
/// </devdoc>
173+
public override void Install(IDictionary stateSaver) {
174+
base.Install(stateSaver);
175+
176+
Context.LogMessage(Res.GetString(Res.CreatingEventLog, Source, Log));
177+
178+
if (Environment.OSVersion.Platform != PlatformID.Win32NT) {
179+
throw new PlatformNotSupportedException(Res.GetString(Res.WinNTRequired));
180+
}
181+
182+
stateSaver["baseInstalledAndPlatformOK"] = true;
183+
184+
// remember whether the log was already there and if the source was already registered
185+
bool logExists = EventLog.Exists(Log, ".");
186+
stateSaver["logExists"] = logExists;
187+
188+
189+
bool alreadyRegistered = EventLog.SourceExists(Source, ".");
190+
stateSaver["alreadyRegistered"] = alreadyRegistered;
191+
192+
if (alreadyRegistered) {
193+
string oldLog = EventLog.LogNameFromSourceName(Source, ".");
194+
if (oldLog == Log) {
195+
// The source exists, and it's on the right log, so we do nothing
196+
// here. If oldLog != Log, we'll try to create the source below
197+
// and it will fail, because the source already exists on another
198+
// log.
199+
return;
200+
}
201+
}
202+
203+
// do the installation.
204+
EventLog.CreateEventSource(sourceData);
205+
}
206+
207+
/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller.IsEquivalentInstaller"]/*' />
208+
/// <devdoc>
209+
/// <para>[To be supplied.]</para>
210+
/// </devdoc>
211+
public override bool IsEquivalentInstaller(ComponentInstaller otherInstaller) {
212+
EventLogInstaller other = otherInstaller as EventLogInstaller;
213+
if (other == null)
214+
return false;
215+
216+
return other.Source == Source;
217+
}
218+
219+
/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller.Rollback"]/*' />
220+
/// <devdoc>
221+
/// Called when this or another component in the installation has failed.
222+
/// </devdoc>
223+
public override void Rollback(IDictionary savedState) {
224+
base.Rollback(savedState);
225+
226+
Context.LogMessage(Res.GetString(Res.RestoringEventLog, Source));
227+
228+
if (savedState["baseInstalledAndPlatformOK"] != null) {
229+
bool logExists = (bool) savedState["logExists"];
230+
if (!logExists)
231+
EventLog.Delete(Log, ".");
232+
else {
233+
bool alreadyRegistered;
234+
object alreadyRegisteredObj = savedState["alreadyRegistered"];
235+
if (alreadyRegisteredObj == null)
236+
alreadyRegistered = false;
237+
else
238+
alreadyRegistered = (bool) alreadyRegisteredObj;
239+
240+
if (!alreadyRegistered) {
241+
// delete the source we installed, assuming it succeeded. Then put back whatever used to be there.
242+
if (EventLog.SourceExists(Source, "."))
243+
EventLog.DeleteEventSource(Source, ".");
244+
}
245+
}
246+
}
247+
}
248+
249+
/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller.Uninstall"]/*' />
250+
/// <devdoc>
251+
/// Called to remove the event log source from the machine.
252+
/// </devdoc>
253+
public override void Uninstall(IDictionary savedState) {
254+
base.Uninstall(savedState);
255+
if (UninstallAction == UninstallAction.Remove) {
256+
Context.LogMessage(Res.GetString(Res.RemovingEventLog, Source));
257+
if (EventLog.SourceExists(Source, ".")) {
258+
if ( string.Compare(Log, Source, StringComparison.OrdinalIgnoreCase) != 0 ) // If log has the same name, don't delete the source.
259+
EventLog.DeleteEventSource(Source, ".");
260+
}
261+
else
262+
Context.LogMessage(Res.GetString(Res.LocalSourceNotRegisteredWarning, Source));
263+
264+
// now test to see if the log has any more sources in it. If not, we
265+
// should remove the log entirely.
266+
// we have to do this by inspecting the registry.
267+
RegistryKey key = Registry.LocalMachine;
268+
RegistryKey logKey = null;
269+
try {
270+
key = key.OpenSubKey("SYSTEM\\CurrentControlSet\\Services\\EventLog", false);
271+
if (key != null)
272+
logKey = key.OpenSubKey(Log, false);
273+
if (logKey != null) {
274+
string[] keyNames = logKey.GetSubKeyNames();
275+
if ( keyNames == null || keyNames.Length == 0 ||
276+
(keyNames.Length == 1 && string.Compare(keyNames[0], Log, StringComparison.OrdinalIgnoreCase) ==0) // the only key has the same name as log
277+
) {
278+
Context.LogMessage(Res.GetString(Res.DeletingEventLog, Log));
279+
// there are no sources in this log. Delete the log.
280+
EventLog.Delete(Log, ".");
281+
}
282+
}
283+
}
284+
finally {
285+
if (key != null)
286+
key.Close();
287+
if (logKey != null)
288+
logKey.Close();
289+
}
290+
}
291+
// otherwise it's UninstallAction.NoAction, so we shouldn't do anything.
292+
}
293+
294+
}
295+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//------------------------------------------------------------------------------
2+
// <copyright file="IManagedInstaller.cs" company="Microsoft">
3+
// Copyright (c) Microsoft Corporation. All rights reserved.
4+
// </copyright>
5+
//------------------------------------------------------------------------------
6+
7+
namespace System.Configuration.Install {
8+
using System.Runtime.InteropServices;
9+
using System.Diagnostics;
10+
using System;
11+
12+
/// <include file='doc\IManagedInstaller.uex' path='docs/doc[@for="IManagedInstaller"]/*' />
13+
/// <internalonly/>
14+
/// <devdoc>
15+
/// <para>[To be supplied.]</para>
16+
/// </devdoc>
17+
[ComImport, Guid("1E233FE7-C16D-4512-8C3B-2E9988F08D38"), System.Runtime.InteropServices.InterfaceTypeAttribute(System.Runtime.InteropServices.ComInterfaceType.InterfaceIsIUnknown)]
18+
public interface IManagedInstaller {
19+
20+
/// <include file='doc\IManagedInstaller.uex' path='docs/doc[@for="IManagedInstaller.ManagedInstall"]/*' />
21+
/// <devdoc>
22+
/// <para>[To be supplied.]</para>
23+
/// </devdoc>
24+
[return: MarshalAs(UnmanagedType.I4)]
25+
int ManagedInstall(
26+
[In, MarshalAs(UnmanagedType.BStr)]
27+
string commandLine,
28+
29+
[In, MarshalAs(UnmanagedType.I4)]
30+
int hInstall); // this handle is alway 32 bits (even on a 64 bit machine)
31+
}
32+
}

0 commit comments

Comments
 (0)