Skip to content

Commit

Permalink
Sources for System.Configuration.Install' (#145)
Browse files Browse the repository at this point in the history
  • Loading branch information
danmoseley authored Nov 19, 2020
1 parent b80fa34 commit 5697c29
Show file tree
Hide file tree
Showing 17 changed files with 3,016 additions and 0 deletions.
499 changes: 499 additions & 0 deletions System.Configuration.Install/AssemblyInstaller.cs

Large diffs are not rendered by default.

40 changes: 40 additions & 0 deletions System.Configuration.Install/ComponentInstaller.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//------------------------------------------------------------------------------
// <copyright file="ComponentInstaller.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------

/*
*/
namespace System.Configuration.Install {
using System.ComponentModel;
using System.Diagnostics;
using System;
using System.Windows.Forms;

/// <include file='doc\ComponentInstaller.uex' path='docs/doc[@for="ComponentInstaller"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public abstract class ComponentInstaller : Installer {

/// <include file='doc\ComponentInstaller.uex' path='docs/doc[@for="ComponentInstaller.CopyFromComponent"]/*' />
/// <devdoc>
/// Copies properties from the given component to this installer. This method
/// will be called at design-time when the user clicks 'Add Installer' on a
/// component that has specified this class as its installer. The installer
/// should take all information it can from the live component and store it
/// to be used at install time.
/// </devdoc>
public abstract void CopyFromComponent(IComponent component);

/// <include file='doc\ComponentInstaller.uex' path='docs/doc[@for="ComponentInstaller.IsEquivalentInstaller"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public virtual bool IsEquivalentInstaller(ComponentInstaller otherInstaller) {
return false;
}
}

}
295 changes: 295 additions & 0 deletions System.Configuration.Install/EventLogInstaller.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,295 @@
//------------------------------------------------------------------------------
// <copyright file="EventLogInstaller.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------

/*
*/
namespace System.Diagnostics {
using System.ComponentModel;
using System.Diagnostics;
using System;
using System.Collections;
using Microsoft.Win32;
using System.Configuration.Install;
using System.Globalization;
using System.Security.Permissions;
using System.Runtime.InteropServices;

/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller"]/*' />
/// <devdoc>
/// This class acts as an installer for the EventLog component. Essentially, it calls
/// EventLog.CreateEventSource.
/// </devdoc>
public class EventLogInstaller : ComponentInstaller {

private EventSourceCreationData sourceData = new EventSourceCreationData(null, null);
private UninstallAction uninstallAction = System.Configuration.Install.UninstallAction.Remove;

/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller.CategoryResourceFile"]/*' />
[
TypeConverter("System.Diagnostics.Design.StringValueConverter, " + AssemblyRef.SystemDesign),
Editor("System.Windows.Forms.Design.FileNameEditor, " + AssemblyRef.SystemDesign, "System.Drawing.Design.UITypeEditor, " + AssemblyRef.SystemDrawing),
ComVisible(false),
ResDescription(Res.Desc_CategoryResourceFile)
]
public string CategoryResourceFile {
get {
return sourceData.CategoryResourceFile;
}
set {
sourceData.CategoryResourceFile = value;
}
}

/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller.CategoryCount"]/*' />
[
ComVisible(false),
ResDescription(Res.Desc_CategoryCount)
]
public int CategoryCount {
get {
return sourceData.CategoryCount;
}
set {
sourceData.CategoryCount = value;
}
}


/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller.Log"]/*' />
/// <devdoc>
/// The log in which the source will be created
/// </devdoc>
[
TypeConverter("System.Diagnostics.Design.StringValueConverter, " + AssemblyRef.SystemDesign),
ResDescription(Res.Desc_Log)
]
public string Log {
get {
if (sourceData.LogName == null && sourceData.Source != null)
// they've told us a source, but they haven't told us a log name.
// try to deduce the log name from the source name.
sourceData.LogName = EventLog.LogNameFromSourceName(sourceData.Source, ".");
return sourceData.LogName;
}
set {
sourceData.LogName = value;
}
}

/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller.MessageResourceFile"]/*' />
[
TypeConverter("System.Diagnostics.Design.StringValueConverter, " + AssemblyRef.SystemDesign),
Editor("System.Windows.Forms.Design.FileNameEditor, " + AssemblyRef.SystemDesign, "System.Drawing.Design.UITypeEditor, " + AssemblyRef.SystemDrawing),
ComVisible(false),
ResDescription(Res.Desc_MessageResourceFile)
]
public string MessageResourceFile {
get {
return sourceData.MessageResourceFile;
}
set {
sourceData.MessageResourceFile = value;
}
}

/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller.ParameterResourceFile"]/*' />
[
TypeConverter("System.Diagnostics.Design.StringValueConverter, " + AssemblyRef.SystemDesign),
Editor("System.Windows.Forms.Design.FileNameEditor, " + AssemblyRef.SystemDesign, "System.Drawing.Design.UITypeEditor, " + AssemblyRef.SystemDrawing),
ComVisible(false),
ResDescription(Res.Desc_ParameterResourceFile)
]
public string ParameterResourceFile {
get {
return sourceData.ParameterResourceFile;
}
set {
sourceData.ParameterResourceFile = value;
}
}


/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller.Source"]/*' />
/// <devdoc>
/// The source to be created
/// </devdoc>
[
TypeConverter("System.Diagnostics.Design.StringValueConverter, " + AssemblyRef.SystemDesign),
ResDescription(Res.Desc_Source)
]
public string Source {
get {
return sourceData.Source;
}
set {
sourceData.Source = value;
}
}

/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller.UninstallAction"]/*' />
/// <devdoc>
/// Determines whether the event log is removed at uninstall time.
/// </devdoc>
[DefaultValue(UninstallAction.Remove),
ResDescription(Res.Desc_UninstallAction)
]
public UninstallAction UninstallAction {
get {
return uninstallAction;
}
set {
if (!Enum.IsDefined(typeof(UninstallAction), value))
throw new InvalidEnumArgumentException("value", (int)value, typeof(UninstallAction));

uninstallAction = value;
}
}

/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller.CopyFromComponent"]/*' />
/// <devdoc>
/// A method on ComponentInstaller that lets us copy properties.
/// </devdoc>
public override void CopyFromComponent(IComponent component) {
EventLog log = component as EventLog;

if (log == null)
throw new ArgumentException(Res.GetString(Res.NotAnEventLog));

if (log.Log == null || log.Log == string.Empty || log.Source == null || log.Source == string.Empty) {
throw new ArgumentException(Res.GetString(Res.IncompleteEventLog));
}

Log = log.Log;
Source = log.Source;
}

/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller.Install"]/*' />
/// <devdoc>
/// Called when we should perform the install. Inherited from Installer.
/// </devdoc>
public override void Install(IDictionary stateSaver) {
base.Install(stateSaver);

Context.LogMessage(Res.GetString(Res.CreatingEventLog, Source, Log));

if (Environment.OSVersion.Platform != PlatformID.Win32NT) {
throw new PlatformNotSupportedException(Res.GetString(Res.WinNTRequired));
}

stateSaver["baseInstalledAndPlatformOK"] = true;

// remember whether the log was already there and if the source was already registered
bool logExists = EventLog.Exists(Log, ".");
stateSaver["logExists"] = logExists;


bool alreadyRegistered = EventLog.SourceExists(Source, ".");
stateSaver["alreadyRegistered"] = alreadyRegistered;

if (alreadyRegistered) {
string oldLog = EventLog.LogNameFromSourceName(Source, ".");
if (oldLog == Log) {
// The source exists, and it's on the right log, so we do nothing
// here. If oldLog != Log, we'll try to create the source below
// and it will fail, because the source already exists on another
// log.
return;
}
}

// do the installation.
EventLog.CreateEventSource(sourceData);
}

/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller.IsEquivalentInstaller"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public override bool IsEquivalentInstaller(ComponentInstaller otherInstaller) {
EventLogInstaller other = otherInstaller as EventLogInstaller;
if (other == null)
return false;

return other.Source == Source;
}

/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller.Rollback"]/*' />
/// <devdoc>
/// Called when this or another component in the installation has failed.
/// </devdoc>
public override void Rollback(IDictionary savedState) {
base.Rollback(savedState);

Context.LogMessage(Res.GetString(Res.RestoringEventLog, Source));

if (savedState["baseInstalledAndPlatformOK"] != null) {
bool logExists = (bool) savedState["logExists"];
if (!logExists)
EventLog.Delete(Log, ".");
else {
bool alreadyRegistered;
object alreadyRegisteredObj = savedState["alreadyRegistered"];
if (alreadyRegisteredObj == null)
alreadyRegistered = false;
else
alreadyRegistered = (bool) alreadyRegisteredObj;

if (!alreadyRegistered) {
// delete the source we installed, assuming it succeeded. Then put back whatever used to be there.
if (EventLog.SourceExists(Source, "."))
EventLog.DeleteEventSource(Source, ".");
}
}
}
}

/// <include file='doc\EventLogInstaller.uex' path='docs/doc[@for="EventLogInstaller.Uninstall"]/*' />
/// <devdoc>
/// Called to remove the event log source from the machine.
/// </devdoc>
public override void Uninstall(IDictionary savedState) {
base.Uninstall(savedState);
if (UninstallAction == UninstallAction.Remove) {
Context.LogMessage(Res.GetString(Res.RemovingEventLog, Source));
if (EventLog.SourceExists(Source, ".")) {
if ( string.Compare(Log, Source, StringComparison.OrdinalIgnoreCase) != 0 ) // If log has the same name, don't delete the source.
EventLog.DeleteEventSource(Source, ".");
}
else
Context.LogMessage(Res.GetString(Res.LocalSourceNotRegisteredWarning, Source));

// now test to see if the log has any more sources in it. If not, we
// should remove the log entirely.
// we have to do this by inspecting the registry.
RegistryKey key = Registry.LocalMachine;
RegistryKey logKey = null;
try {
key = key.OpenSubKey("SYSTEM\\CurrentControlSet\\Services\\EventLog", false);
if (key != null)
logKey = key.OpenSubKey(Log, false);
if (logKey != null) {
string[] keyNames = logKey.GetSubKeyNames();
if ( keyNames == null || keyNames.Length == 0 ||
(keyNames.Length == 1 && string.Compare(keyNames[0], Log, StringComparison.OrdinalIgnoreCase) ==0) // the only key has the same name as log
) {
Context.LogMessage(Res.GetString(Res.DeletingEventLog, Log));
// there are no sources in this log. Delete the log.
EventLog.Delete(Log, ".");
}
}
}
finally {
if (key != null)
key.Close();
if (logKey != null)
logKey.Close();
}
}
// otherwise it's UninstallAction.NoAction, so we shouldn't do anything.
}

}
}
32 changes: 32 additions & 0 deletions System.Configuration.Install/IManagedInstaller.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//------------------------------------------------------------------------------
// <copyright file="IManagedInstaller.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------

namespace System.Configuration.Install {
using System.Runtime.InteropServices;
using System.Diagnostics;
using System;

/// <include file='doc\IManagedInstaller.uex' path='docs/doc[@for="IManagedInstaller"]/*' />
/// <internalonly/>
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
[ComImport, Guid("1E233FE7-C16D-4512-8C3B-2E9988F08D38"), System.Runtime.InteropServices.InterfaceTypeAttribute(System.Runtime.InteropServices.ComInterfaceType.InterfaceIsIUnknown)]
public interface IManagedInstaller {

/// <include file='doc\IManagedInstaller.uex' path='docs/doc[@for="IManagedInstaller.ManagedInstall"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
[return: MarshalAs(UnmanagedType.I4)]
int ManagedInstall(
[In, MarshalAs(UnmanagedType.BStr)]
string commandLine,

[In, MarshalAs(UnmanagedType.I4)]
int hInstall); // this handle is alway 32 bits (even on a 64 bit machine)
}
}
Loading

0 comments on commit 5697c29

Please sign in to comment.