diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/CommonUtils.cs b/src/Microsoft.PowerShell.Commands.Diagnostics/CommonUtils.cs
index 4ee258575f..182cf59d99 100644
--- a/src/Microsoft.PowerShell.Commands.Diagnostics/CommonUtils.cs
+++ b/src/Microsoft.PowerShell.Commands.Diagnostics/CommonUtils.cs
@@ -1,16 +1,22 @@
using System;
using System.Collections;
using System.Diagnostics;
+using System.Globalization;
using System.Runtime.InteropServices;
using System.Text;
using System.Resources;
using System.Reflection;
+#if CORECLR
+using System.ComponentModel;
+#else
+using System.Threading;
+#endif
+
namespace Microsoft.PowerShell.Commands.Diagnostics.Common
{
internal static class CommonUtilities
{
-#if !CORECLR
//
// StringArrayToString helper converts a string array into a comma-separated string.
// Note this has only limited use, individual strings cannot have commas.
@@ -29,6 +35,34 @@ namespace Microsoft.PowerShell.Commands.Diagnostics.Common
return ret;
}
+#if CORECLR
+ private const string LibraryLoadDllName = "api-ms-win-core-libraryloader-l1-2-0.dll";
+ private const string LocalizationDllName = "api-ms-win-core-localization-l1-2-1.dll";
+ private const string SysInfoDllName = "api-ms-win-core-sysinfo-l1-2-1.dll";
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ internal struct OSVERSIONINFOEX
+ {
+ public int OSVersionInfoSize;
+ public int MajorVersion;
+ public int MinorVersion;
+ public int BuildNumber;
+ public int PlatformId;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
+ public string CSDVersion;
+ public ushort ServicePackMajor;
+ public ushort ServicePackMinor;
+ public short SuiteMask;
+ public byte ProductType;
+ public byte Reserved;
+ }
+
+ [DllImport(SysInfoDllName, CharSet = CharSet.Unicode, SetLastError = true)]
+ internal static extern bool GetVersionEx(ref OSVERSIONINFOEX osVerEx);
+#else
+ private const string LibraryLoadDllName = "kernel32.dll";
+ private const string LocalizationDllName = "kernel32.dll";
+#endif
private const uint FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
private const uint FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
@@ -36,25 +70,25 @@ namespace Microsoft.PowerShell.Commands.Diagnostics.Common
private const uint LOAD_LIBRARY_AS_DATAFILE = 0x00000002;
private const uint FORMAT_MESSAGE_FROM_HMODULE = 0x00000800;
- [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
+ [DllImport(LocalizationDllName, SetLastError = true, CharSet = CharSet.Unicode)]
private static extern uint FormatMessage(uint dwFlags, IntPtr lpSource,
uint dwMessageId, uint dwLanguageId,
[MarshalAs(UnmanagedType.LPWStr)]
StringBuilder lpBuffer,
uint nSize, IntPtr Arguments);
- [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
+ [DllImport(LibraryLoadDllName, SetLastError = true, CharSet = CharSet.Unicode)]
private static extern IntPtr LoadLibraryEx(
[MarshalAs(UnmanagedType.LPWStr)] string lpFileName,
IntPtr hFile,
uint dwFlags
);
- [DllImport("kernel32.dll")]
+ [DllImport(LibraryLoadDllName)]
private static extern bool FreeLibrary(IntPtr hModule);
- [DllImport("kernel32.dll", EntryPoint = "GetUserDefaultLangID", CallingConvention = CallingConvention.Winapi, SetLastError = true)]
+ [DllImport(LocalizationDllName, EntryPoint = "GetUserDefaultLangID", CallingConvention = CallingConvention.Winapi, SetLastError = true)]
private static extern ushort GetUserDefaultLangID();
@@ -111,7 +145,6 @@ namespace Microsoft.PowerShell.Commands.Diagnostics.Common
}
return formatError;
}
-#endif
public static ResourceManager GetResourceManager()
{
diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/CoreCLR/Stubs.cs b/src/Microsoft.PowerShell.Commands.Diagnostics/CoreCLR/Stubs.cs
new file mode 100644
index 0000000000..858e535cc9
--- /dev/null
+++ b/src/Microsoft.PowerShell.Commands.Diagnostics/CoreCLR/Stubs.cs
@@ -0,0 +1,252 @@
+
+#if CORECLR
+using System.ComponentModel;
+using Microsoft.PowerShell.CoreClr.Stubs;
+
+namespace System.Diagnostics
+{
+ ///
+ /// Indicates whether the performance counter category can have multiple instances.
+ ///
+ /// 1
+ public enum PerformanceCounterCategoryType
+ {
+ ///
+ /// The instance functionality for the performance counter category is unknown.
+ ///
+ Unknown = -1,
+
+ ///
+ /// The performance counter category can have only a single instance.
+ ///
+ SingleInstance,
+
+ ///
+ /// The performance counter category can have multiple instances.
+ ///
+ MultiInstance
+ }
+
+ ///
+ /// Specifies the formula used to calculate the
+ /// method for a instance.
+ ///
+ /// 2
+ public enum PerformanceCounterType
+ {
+ ///
+ /// An instantaneous counter that shows the most recently observed value.
+ /// Used, for example, to maintain a simple count of items or operations.
+ ///
+ NumberOfItems32 = 65536,
+
+ ///
+ /// An instantaneous counter that shows the most recently observed value.
+ /// Used, for example, to maintain a simple count of a very large number
+ /// of items or operations. It is the same as NumberOfItems32 except that
+ /// it uses larger fields to accommodate larger values.
+ ///
+ NumberOfItems64 = 65792,
+
+ ///
+ /// An instantaneous counter that shows the most recently observed value
+ /// in hexadecimal format. Used, for example, to maintain a simple count
+ /// of items or operations.
+ NumberOfItemsHEX32 = 0,
+
+ ///
+ /// An instantaneous counter that shows the most recently observed value.
+ /// Used, for example, to maintain a simple count of a very large number
+ /// of items or operations. It is the same as NumberOfItemsHEX32 except
+ /// that it uses larger fields to accommodate larger values.
+ ///
+ NumberOfItemsHEX64 = 256,
+
+ ///
+ /// A difference counter that shows the average number of operations completed
+ /// during each second of the sample interval. Counters of this type measure
+ /// time in ticks of the system clock.
+ RateOfCountsPerSecond32 = 272696320,
+
+ ///
+ /// A difference counter that shows the average number of operations completed
+ /// during each second of the sample interval. Counters of this type measure
+ /// time in ticks of the system clock. This counter type is the same as the
+ /// RateOfCountsPerSecond32 type, but it uses larger fields to accommodate
+ /// larger values to track a high-volume number of items or operations per
+ /// second, such as a byte-transmission rate.
+ ///
+ RateOfCountsPerSecond64 = 272696576,
+
+ ///
+ /// An average counter designed to monitor the average length of a queue
+ /// to a resource over time. It shows the difference between the queue
+ /// lengths observed during the last two sample intervals divided by the
+ /// duration of the interval. This type of counter is typically used to
+ /// track the number of items that are queued or waiting.
+ ///
+ CountPerTimeInterval32 = 4523008,
+
+ ///
+ /// An average counter that monitors the average length of a queue to a
+ /// resource over time. Counters of this type display the difference
+ /// between the queue lengths observed during the last two sample intervals,
+ /// divided by the duration of the interval. This counter type is the same
+ /// as CountPerTimeInterval32 except that it uses larger fields to
+ /// accommodate larger values. This type of counter is typically used
+ /// to track a high-volume or very large number of items that are queued or waiting.
+ ///
+ CountPerTimeInterval64 = 4523264,
+
+ ///
+ /// An instantaneous percentage counter that shows the ratio of a subset
+ /// to its set as a percentage. For example, it compares the number of bytes
+ /// in use on a disk to the total number of bytes on the disk.
+ /// Counters of this type display the current percentage only, not an average
+ /// over time.
+ ///
+ RawFraction = 537003008,
+
+ ///
+ /// A base counter that stores the denominator of a counter that presents a
+ /// general arithmetic fraction. Check that this value is greater than zero
+ /// before using it as the denominator in a RawFraction value calculation.
+ ///
+ RawBase = 1073939459,
+
+ ///
+ /// An average counter that measures the time it takes, on average, to
+ /// complete a process or operation. Counters of this type display a
+ /// ratio of the total elapsed time of the sample interval to the number
+ /// of processes or operations completed during that time. This counter
+ /// type measures time in ticks of the system clock.
+ ///
+ AverageTimer32 = 805438464,
+
+ ///
+ /// A base counter that is used in the calculation of time or count averages,
+ /// such as AverageTimer32 and AverageCount64. Stores the denominator for
+ /// calculating a counter to present "time per operation" or "count per operation".
+ ///
+ AverageBase = 1073939458,
+
+ ///
+ /// An average counter that shows how many items are processed, on average,
+ /// during an operation. Counters of this type display a ratio of the items
+ /// processed to the number of operations completed. The ratio is calculated
+ /// by comparing the number of items processed during the last interval to
+ /// the number of operations completed during the last interval.
+ ///
+ AverageCount64 = 1073874176,
+
+ ///
+ /// A percentage counter that shows the average ratio of hits to all
+ /// operations during the last two sample intervals.
+ ///
+ SampleFraction = 549585920,
+
+ ///
+ /// An average counter that shows the average number of operations completed
+ /// in one second. When a counter of this type samples the data, each sampling
+ /// interrupt returns one or zero. The counter data is the number of ones that
+ /// were sampled. It measures time in units of ticks of the system performance timer.
+ ///
+ SampleCounter = 4260864,
+
+ ///
+ /// A base counter that stores the number of sampling interrupts taken
+ /// and is used as a denominator in the sampling fraction. The sampling
+ /// fraction is the number of samples that were 1 (or true) for a sample
+ /// interrupt. Check that this value is greater than zero before using
+ /// it as the denominator in a calculation of SampleFraction.
+ ///
+ SampleBase = 1073939457,
+
+ ///
+ /// A percentage counter that shows the average time that a component is
+ /// active as a percentage of the total sample time.
+ ///
+ CounterTimer = 541132032,
+
+ ///
+ /// A percentage counter that displays the average percentage of active
+ /// time observed during sample interval. The value of these counters is
+ /// calculated by monitoring the percentage of time that the service was
+ /// inactive and then subtracting that value from 100 percent.
+ ///
+ CounterTimerInverse = 557909248,
+
+ /// A percentage counter that shows the active time of a component
+ /// as a percentage of the total elapsed time of the sample interval.
+ /// It measures time in units of 100 nanoseconds (ns). Counters of this
+ /// type are designed to measure the activity of one component at a time.
+ ///
+ Timer100Ns = 542180608,
+
+ ///
+ /// A percentage counter that shows the average percentage of active time
+ /// observed during the sample interval.
+ ///
+ Timer100NsInverse = 558957824,
+
+ ///
+ /// A difference timer that shows the total time between when the component
+ /// or process started and the time when this value is calculated.
+ ///
+ ElapsedTime = 807666944,
+
+ ///
+ /// A percentage counter that displays the active time of one or more
+ /// components as a percentage of the total time of the sample interval.
+ /// Because the numerator records the active time of components operating
+ /// simultaneously, the resulting percentage can exceed 100 percent.
+ ///
+ CounterMultiTimer = 574686464,
+
+ ///
+ /// A percentage counter that shows the active time of one or more components
+ /// as a percentage of the total time of the sample interval. It derives
+ /// the active time by measuring the time that the components were not
+ /// active and subtracting the result from 100 percent by the number of
+ /// objects monitored.
+ ///
+ CounterMultiTimerInverse = 591463680,
+
+ ///
+ /// A percentage counter that shows the active time of one or more components
+ /// as a percentage of the total time of the sample interval. It measures
+ /// time in 100 nanosecond (ns) units.
+ CounterMultiTimer100Ns = 575735040,
+
+ ///
+ /// A percentage counter that shows the active time of one or more components
+ /// as a percentage of the total time of the sample interval. Counters of
+ /// this type measure time in 100 nanosecond (ns) units. They derive the
+ /// active time by measuring the time that the components were not active
+ /// and subtracting the result from multiplying 100 percent by the number
+ /// of objects monitored.
+ CounterMultiTimer100NsInverse = 592512256,
+
+ ///
+ /// A base counter that indicates the number of items sampled. It is used
+ /// as the denominator in the calculations to get an average among the
+ /// items sampled when taking timings of multiple, but similar items.
+ /// Used with CounterMultiTimer, CounterMultiTimerInverse, CounterMultiTimer100Ns,
+ /// and CounterMultiTimer100NsInverse.
+ CounterMultiBase = 1107494144,
+
+ ///
+ /// A difference counter that shows the change in the measured attribute
+ /// between the two most recent sample intervals.
+ ///
+ CounterDelta32 = 4195328,
+
+ ///
+ /// A difference counter that shows the change in the measured attribute
+ /// between the two most recent sample intervals. It is the same as the
+ /// CounterDelta32 counter type except that is uses larger fields to
+ /// accomodate larger values.
+ CounterDelta64 = 4195584
+ }
+}
+#endif
diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/ExportCounterCommand.cs b/src/Microsoft.PowerShell.Commands.Diagnostics/ExportCounterCommand.cs
index 6240ef6504..2c03987ab1 100644
--- a/src/Microsoft.PowerShell.Commands.Diagnostics/ExportCounterCommand.cs
+++ b/src/Microsoft.PowerShell.Commands.Diagnostics/ExportCounterCommand.cs
@@ -1,6 +1,6 @@
//
// Copyright (c) 2008 Microsoft Corporation. All rights reserved.
-//
+//
using System;
@@ -30,7 +30,7 @@ using Microsoft.PowerShell.Commands.Diagnostics.Common;
namespace Microsoft.PowerShell.Commands
{
- ///
+ ///
/// Class that implements the Get-Counter cmdlet.
///
[Cmdlet(VerbsData.Export, "Counter", DefaultParameterSetName = "ExportCounterSet", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=138337")]
@@ -38,7 +38,7 @@ namespace Microsoft.PowerShell.Commands
{
//
// Path parameter
- //
+ //
[Parameter(
Mandatory = true,
Position = 0,
@@ -58,7 +58,7 @@ namespace Microsoft.PowerShell.Commands
//
// Format parameter.
// Valid strings are "blg", "csv", "tsv" (case-insensitive).
- //
+ //
[Parameter(
Mandatory = false,
ValueFromPipeline = false,
@@ -77,7 +77,7 @@ namespace Microsoft.PowerShell.Commands
//
// MaxSize parameter
// Maximum output file size, in megabytes.
- //
+ //
[Parameter(
HelpMessageBaseName = "GetEventResources")]
public UInt32 MaxSize
@@ -90,7 +90,7 @@ namespace Microsoft.PowerShell.Commands
//
// InputObject parameter
- //
+ //
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
@@ -152,23 +152,30 @@ namespace Microsoft.PowerShell.Commands
{
_resourceMgr = Microsoft.PowerShell.Commands.Diagnostics.Common.CommonUtilities.GetResourceManager();
+#if CORECLR
+ // PowerShell Core requires at least Windows 7,
+ // so no version test is needed
+ _pdhHelper = new PdhHelper(false);
+#else
//
// Determine the OS version: this cmdlet requires Windows 7
// because it uses new Pdh functionality.
//
- if (System.Environment.OSVersion.Version.Major < 6 ||
- (System.Environment.OSVersion.Version.Major == 6 && System.Environment.OSVersion.Version.Minor < 1))
+ Version osVersion = System.Environment.OSVersion.Version;
+ if (osVersion.Major < 6 ||
+ (osVersion.Major == 6 && osVersion.Minor < 1))
{
string msg = _resourceMgr.GetString("ExportCtrWin7Required");
Exception exc = new Exception(msg);
ThrowTerminatingError(new ErrorRecord(exc, "ExportCtrWin7Required", ErrorCategory.NotImplemented, null));
}
- _pdhHelper = new PdhHelper(System.Environment.OSVersion.Version.Major < 6);
+ _pdhHelper = new PdhHelper(osVersion.Major < 6);
+#endif
//
// Validate the Format and CounterSamples arguments
- //
+ //
ValidateFormat();
if (Circular.IsPresent && _maxSize == 0)
@@ -200,9 +207,9 @@ namespace Microsoft.PowerShell.Commands
}
- ///
+ ///
/// Handle Control-C
- ///
+ ///
protected override void StopProcessing()
{
_stopping = true;
@@ -214,7 +221,7 @@ namespace Microsoft.PowerShell.Commands
// This is the main entry point for the cmdlet.
// When counter data comes from the pipeline, this gets invoked for each pipelined object.
// When it's passed in as an argument, ProcessRecord() is called once for the entire _counterSampleSets array.
- //
+ //
protected override void ProcessRecord()
{
Debug.Assert(_counterSampleSets.Length != 0 && _counterSampleSets[0] != null);
@@ -225,7 +232,7 @@ namespace Microsoft.PowerShell.Commands
if (!_queryInitialized)
{
- if (_format.ToLower(CultureInfo.InvariantCulture).Equals("blg"))
+ if (_format.ToLowerInvariant().Equals("blg"))
{
res = _pdhHelper.AddRelogCounters(_counterSampleSets[0]);
}
@@ -303,7 +310,7 @@ namespace Microsoft.PowerShell.Commands
//
private void ValidateFormat()
{
- switch (_format.ToLower(CultureInfo.InvariantCulture))
+ switch (_format.ToLowerInvariant())
{
case "blg":
_outputFormat = PdhLogFileType.PDH_LOG_TYPE_BINARY;
diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/GetCounterCommand.cs b/src/Microsoft.PowerShell.Commands.Diagnostics/GetCounterCommand.cs
index 827d6407f7..d89bf55fa1 100644
--- a/src/Microsoft.PowerShell.Commands.Diagnostics/GetCounterCommand.cs
+++ b/src/Microsoft.PowerShell.Commands.Diagnostics/GetCounterCommand.cs
@@ -1,6 +1,6 @@
//
// Copyright (c) 2008 Microsoft Corporation. All rights reserved.
-//
+//
using System;
@@ -30,15 +30,15 @@ using Microsoft.PowerShell.Commands.Diagnostics.Common;
namespace Microsoft.PowerShell.Commands
{
- ///
+ ///
/// Class that implements the Get-Counter cmdlet.
- ///
+ ///
[Cmdlet(VerbsCommon.Get, "Counter", DefaultParameterSetName = "GetCounterSet", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=138335")]
public sealed class GetCounterCommand : PSCmdlet
{
//
// ListSet parameter
- //
+ //
[Parameter(
Position = 0,
Mandatory = true,
@@ -62,7 +62,7 @@ namespace Microsoft.PowerShell.Commands
//
// Counter parameter
- //
+ //
[Parameter(
Position = 0,
ParameterSetName = "GetCounterSet",
@@ -175,8 +175,8 @@ namespace Microsoft.PowerShell.Commands
private EventWaitHandle _cancelEventArrived = new EventWaitHandle(false, EventResetMode.ManualReset);
- // Culture identifier(s)
- private const int FrenchCultureId = 0x040C;
+ // Culture identifier(s)
+ private const string FrenchCultureId = "fr-FR";
// The localized Pdh resource strings might use Unicode characters that are different from
// what the user can type with the keyboard to represent a special character.
//
@@ -184,8 +184,8 @@ namespace Microsoft.PowerShell.Commands
// in the resource strings.
//
// With this dictionary, we can add special mapping if we find other special cases in the future.
- private readonly Dictionary>> _cultureAndSpecialCharacterMap =
- new Dictionary>>()
+ private readonly Dictionary>> _cultureAndSpecialCharacterMap =
+ new Dictionary>>()
{
{
FrenchCultureId, new List>()
@@ -207,7 +207,14 @@ namespace Microsoft.PowerShell.Commands
{
_resourceMgr = Microsoft.PowerShell.Commands.Diagnostics.Common.CommonUtilities.GetResourceManager();
+#if CORECLR
+ // PowerShell Core requires at least Windows 7,
+ // so no version test is needed
+ _pdhHelper = new PdhHelper(false);
+#else
_pdhHelper = new PdhHelper(System.Environment.OSVersion.Version.Major < 6);
+#endif
+
uint res = _pdhHelper.ConnectToDataSource();
if (res != 0)
{
@@ -237,9 +244,9 @@ namespace Microsoft.PowerShell.Commands
}
- //
+ //
// Handle Control-C
- //
+ //
protected override void StopProcessing()
{
_cancelEventArrived.Set();
@@ -249,7 +256,7 @@ namespace Microsoft.PowerShell.Commands
//
// ProcessRecord() override.
// This is the main entry point for the cmdlet.
- //
+ //
protected override void ProcessRecord()
{
try
@@ -286,7 +293,7 @@ namespace Microsoft.PowerShell.Commands
//
// ProcessListSet() does the work to process ListSet parameter set.
- //
+ //
private void ProcessListSet()
{
if (_computerName.Length == 0)
@@ -317,11 +324,11 @@ namespace Microsoft.PowerShell.Commands
return;
}
- CultureInfo culture = Thread.CurrentThread.CurrentUICulture;
+ CultureInfo culture = GetCurrentCulture();
List> characterReplacementList = null;
StringCollection validPaths = new StringCollection();
- _cultureAndSpecialCharacterMap.TryGetValue(culture.LCID, out characterReplacementList);
+ _cultureAndSpecialCharacterMap.TryGetValue(culture.Name, out characterReplacementList);
foreach (string pattern in _listSet)
{
@@ -417,23 +424,23 @@ namespace Microsoft.PowerShell.Commands
//
// ProcessGetCounter()
// Does the work to process GetCounterSet parameter set.
- //
+ //
private void ProcessGetCounter()
{
// 1. Combine machine names with paths, if needed, to construct full paths
// 2. Translate default paths into current locale
// 3. Expand wildcards and validate the paths and write errors for any invalid paths
// 4. OpenQuery/ AddCounters
- // 5. Skip the first reading
+ // 5. Skip the first reading
- CultureInfo culture = Thread.CurrentThread.CurrentUICulture;
+ CultureInfo culture = GetCurrentCulture();
List> characterReplacementList = null;
List paths = CombineMachinesAndCounterPaths();
uint res = 0;
if (!_defaultCounters)
{
- _cultureAndSpecialCharacterMap.TryGetValue(culture.LCID, out characterReplacementList);
+ _cultureAndSpecialCharacterMap.TryGetValue(culture.Name, out characterReplacementList);
}
@@ -552,7 +559,12 @@ namespace Microsoft.PowerShell.Commands
break;
}
+#if CORECLR
+ // CoreCLR has no overload of WaitOne with (interval, exitContext)
+ bool cancelled = _cancelEventArrived.WaitOne((int)_sampleInterval * 1000);
+#else
bool cancelled = _cancelEventArrived.WaitOne((int)_sampleInterval * 1000, true);
+#endif
if (cancelled)
{
break;
@@ -584,7 +596,7 @@ namespace Microsoft.PowerShell.Commands
// CombineMachinesAndCounterPaths() helper.
// For paths that do not contain machine names, creates a path for each machine in machineNames.
// Paths already containing a machine name will be preserved.
- //
+ //
private List CombineMachinesAndCounterPaths()
{
List retColl = new List();
@@ -622,9 +634,9 @@ namespace Microsoft.PowerShell.Commands
//
// WriteSampleSetObject() helper.
- // In addition to writing the PerformanceCounterSampleSet object,
+ // In addition to writing the PerformanceCounterSampleSet object,
// it writes a single error if one of the samples has an invalid (non-zero) status.
- //
+ //
private void WriteSampleSetObject(PerformanceCounterSampleSet set)
{
foreach (PerformanceCounterSample sample in set.CounterSamples)
@@ -639,6 +651,15 @@ namespace Microsoft.PowerShell.Commands
}
WriteObject(set);
}
+
+ private static CultureInfo GetCurrentCulture()
+ {
+#if CORECLR
+ return CultureInfo.CurrentCulture;
+#else
+ return Thread.CurrentThread.CurrentUICulture;
+#endif
+ }
}
}
diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/ImportCounterCommand.cs b/src/Microsoft.PowerShell.Commands.Diagnostics/ImportCounterCommand.cs
index 60c6301547..ebecc990e6 100644
--- a/src/Microsoft.PowerShell.Commands.Diagnostics/ImportCounterCommand.cs
+++ b/src/Microsoft.PowerShell.Commands.Diagnostics/ImportCounterCommand.cs
@@ -1,6 +1,6 @@
//
// Copyright (c) 2008 Microsoft Corporation. All rights reserved.
-//
+//
using System;
@@ -30,7 +30,7 @@ using Microsoft.PowerShell.Commands.Diagnostics.Common;
namespace Microsoft.PowerShell.Commands
{
- ///
+ ///
/// Class that implements the Get-Counter cmdlet.
///
[Cmdlet(VerbsData.Import, "Counter", DefaultParameterSetName = "GetCounterSet", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=138338")]
@@ -38,7 +38,7 @@ namespace Microsoft.PowerShell.Commands
{
//
// Path parameter
- //
+ //
[Parameter(
Position = 0,
Mandatory = true,
@@ -65,7 +65,7 @@ namespace Microsoft.PowerShell.Commands
//
// ListSet parameter
- //
+ //
[Parameter(
Mandatory = true,
ParameterSetName = "ListSetSet",
@@ -119,7 +119,7 @@ namespace Microsoft.PowerShell.Commands
//
// Counter parameter
- //
+ //
[Parameter(
Mandatory = false,
ParameterSetName = "GetCounterSet",
@@ -189,7 +189,13 @@ namespace Microsoft.PowerShell.Commands
protected override void BeginProcessing()
{
_resourceMgr = Microsoft.PowerShell.Commands.Diagnostics.Common.CommonUtilities.GetResourceManager();
+#if CORECLR
+ // PowerShell Core requires at least Windows 7,
+ // so no version test is needed
+ _pdhHelper = new PdhHelper(false);
+#else
_pdhHelper = new PdhHelper(System.Environment.OSVersion.Version.Major < 6);
+#endif
}
//
@@ -199,7 +205,7 @@ namespace Microsoft.PowerShell.Commands
{
//
// Resolve and validate the Path argument: present for all parametersets.
- //
+ //
if (!ResolveFilePaths())
{
return;
@@ -229,9 +235,9 @@ namespace Microsoft.PowerShell.Commands
}
- //
+ //
// Handle Control-C
- //
+ //
protected override void StopProcessing()
{
_stopping = true;
@@ -242,7 +248,7 @@ namespace Microsoft.PowerShell.Commands
//
// ProcessRecord() override.
// This is the main entry point for the cmdlet.
- //
+ //
protected override void ProcessRecord()
{
AccumulatePipelineFileNames();
@@ -251,7 +257,7 @@ namespace Microsoft.PowerShell.Commands
//
// ProcessSummary().
// Does the work to process Summary parameter set.
- //
+ //
private void ProcessSummary()
{
uint res = _pdhHelper.ConnectToDataSource(_resolvedPaths);
@@ -276,7 +282,7 @@ namespace Microsoft.PowerShell.Commands
//
// ProcessListSet().
// Does the work to process ListSet parameter set.
- //
+ //
private void ProcessListSet()
{
uint res = _pdhHelper.ConnectToDataSource(_resolvedPaths);
@@ -373,7 +379,7 @@ namespace Microsoft.PowerShell.Commands
//
// ProcessGetCounter()
// Does the work to process GetCounterSet parameter set.
- //
+ //
private void ProcessGetCounter()
{
// Validate StartTime-EndTime, if present
@@ -556,7 +562,7 @@ namespace Microsoft.PowerShell.Commands
// Returns a string collection of resolved file paths.
// Writes non-terminating errors for invalid paths
// and returns an empty collection.
- //
+ //
private bool ResolveFilePaths()
{
StringCollection retColl = new StringCollection();
@@ -607,7 +613,7 @@ namespace Microsoft.PowerShell.Commands
continue;
}
- _resolvedPaths.Add(pi.ProviderPath.ToLower(CultureInfo.InvariantCulture));
+ _resolvedPaths.Add(pi.ProviderPath.ToLowerInvariant());
}
}
@@ -635,9 +641,9 @@ namespace Microsoft.PowerShell.Commands
//
// WriteSampleSetObject() helper.
- // In addition to writing the PerformanceCounterSampleSet object,
+ // In addition to writing the PerformanceCounterSampleSet object,
// it writes a single error if one of the samples has an invalid (non-zero) status.
- // The only exception is the first set, where we allow for the formatted value to be 0 -
+ // The only exception is the first set, where we allow for the formatted value to be 0 -
// this is expected for CSV and TSV files.
private void WriteSampleSetObject(PerformanceCounterSampleSet set, bool firstSet)
diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs b/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs
index 25afd98927..bf22d16a81 100644
--- a/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs
+++ b/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs
@@ -976,7 +976,7 @@ namespace Microsoft.Powershell.Commands.GetCounter.PdhNative
// Marshal.PtrToStructure will allocate managed memory for the object,
// so the unmanaged ptr can be freed safely
//
- pCounterPathElements = (PDH_COUNTER_PATH_ELEMENTS)Marshal.PtrToStructure(structPtr, typeof(PDH_COUNTER_PATH_ELEMENTS));
+ pCounterPathElements = Marshal.PtrToStructure(structPtr);
}
}
finally
@@ -1011,12 +1011,12 @@ namespace Microsoft.Powershell.Commands.GetCounter.PdhNative
}
// Check if the path is local and assert if not:
- string machineNameMassaged = pathElts.MachineName.ToLower(CultureInfo.InvariantCulture);
+ string machineNameMassaged = pathElts.MachineName.ToLowerInvariant();
machineNameMassaged = machineNameMassaged.TrimStart('\\');
- Debug.Assert(machineNameMassaged == System.Environment.MachineName.ToLower(CultureInfo.InvariantCulture));
+ Debug.Assert(machineNameMassaged == System.Environment.MachineName.ToLowerInvariant());
- string lowerEngCtrName = pathElts.CounterName.ToLower(CultureInfo.InvariantCulture);
- string lowerEngObjectName = pathElts.ObjectName.ToLower(CultureInfo.InvariantCulture);
+ string lowerEngCtrName = pathElts.CounterName.ToLowerInvariant();
+ string lowerEngObjectName = pathElts.ObjectName.ToLowerInvariant();
// Get the registry index
RegistryKey rootKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\009");
@@ -1029,7 +1029,7 @@ namespace Microsoft.Powershell.Commands.GetCounter.PdhNative
for (uint enumIndex = 1; enumIndex < regCounters.Length; enumIndex++)
{
string regString = regCounters[enumIndex];
- if (regString.ToLower(CultureInfo.InvariantCulture) == lowerEngCtrName)
+ if (regString.ToLowerInvariant() == lowerEngCtrName)
{
try
{
@@ -1040,7 +1040,7 @@ namespace Microsoft.Powershell.Commands.GetCounter.PdhNative
return (uint)PdhResults.PDH_INVALID_PATH;
}
}
- else if (regString.ToLower(CultureInfo.InvariantCulture) == lowerEngObjectName)
+ else if (regString.ToLowerInvariant() == lowerEngObjectName)
{
try
{
@@ -1195,12 +1195,12 @@ namespace Microsoft.Powershell.Commands.GetCounter.PdhNative
res = ParsePath(counterPath, ref pathElts);
if (res == 0 && pathElts.InstanceName != null)
{
- chi.InstanceName = pathElts.InstanceName.ToLower(CultureInfo.InvariantCulture);
+ chi.InstanceName = pathElts.InstanceName.ToLowerInvariant();
}
- if (!_consumerPathToHandleAndInstanceMap.ContainsKey(counterPath.ToLower(CultureInfo.InvariantCulture)))
+ if (!_consumerPathToHandleAndInstanceMap.ContainsKey(counterPath.ToLowerInvariant()))
{
- _consumerPathToHandleAndInstanceMap.Add(counterPath.ToLower(CultureInfo.InvariantCulture), chi);
+ _consumerPathToHandleAndInstanceMap.Add(counterPath.ToLowerInvariant(), chi);
}
bAtLeastOneAdded = true;
@@ -1236,9 +1236,9 @@ namespace Microsoft.Powershell.Commands.GetCounter.PdhNative
continue;
}
- string lowerCaseMachine = pathElts.MachineName.ToLower(CultureInfo.InvariantCulture);
- string lowerCaseObject = pathElts.ObjectName.ToLower(CultureInfo.InvariantCulture);
- string lowerCaseCounter = pathElts.CounterName.ToLower(CultureInfo.InvariantCulture);
+ string lowerCaseMachine = pathElts.MachineName.ToLowerInvariant();
+ string lowerCaseObject = pathElts.ObjectName.ToLowerInvariant();
+ string lowerCaseCounter = pathElts.CounterName.ToLowerInvariant();
string lcPathMinusInstance = @"\\" + lowerCaseMachine + @"\" + lowerCaseObject + @"\" + lowerCaseCounter;
@@ -1311,12 +1311,12 @@ namespace Microsoft.Powershell.Commands.GetCounter.PdhNative
if (pathElts.InstanceName != null)
{
- chi.InstanceName = pathElts.InstanceName.ToLower(CultureInfo.InvariantCulture);
+ chi.InstanceName = pathElts.InstanceName.ToLowerInvariant();
}
- if (!_reloggerPathToHandleAndInstanceMap.ContainsKey(sample.Path.ToLower(CultureInfo.InvariantCulture)))
+ if (!_reloggerPathToHandleAndInstanceMap.ContainsKey(sample.Path.ToLowerInvariant()))
{
- _reloggerPathToHandleAndInstanceMap.Add(sample.Path.ToLower(CultureInfo.InvariantCulture), chi);
+ _reloggerPathToHandleAndInstanceMap.Add(sample.Path.ToLowerInvariant(), chi);
//Console.WriteLine ("added map path:" + sample.Path );
}
}
@@ -1370,12 +1370,12 @@ namespace Microsoft.Powershell.Commands.GetCounter.PdhNative
chi.hCounter = counterHandle;
if (pathElts.InstanceName != null)
{
- chi.InstanceName = pathElts.InstanceName.ToLower(CultureInfo.InvariantCulture);
+ chi.InstanceName = pathElts.InstanceName.ToLowerInvariant();
}
- if (!_reloggerPathToHandleAndInstanceMap.ContainsKey(sample.Path.ToLower(CultureInfo.InvariantCulture)))
+ if (!_reloggerPathToHandleAndInstanceMap.ContainsKey(sample.Path.ToLowerInvariant()))
{
- _reloggerPathToHandleAndInstanceMap.Add(sample.Path.ToLower(CultureInfo.InvariantCulture), chi);
+ _reloggerPathToHandleAndInstanceMap.Add(sample.Path.ToLowerInvariant(), chi);
}
}
@@ -1756,7 +1756,7 @@ namespace Microsoft.Powershell.Commands.GetCounter.PdhNative
bUnknownPath = false;
- string lcPath = sample.Path.ToLower(CultureInfo.InvariantCulture);
+ string lcPath = sample.Path.ToLowerInvariant();
if (!_reloggerPathToHandleAndInstanceMap.ContainsKey(lcPath))
{
diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/PdhSafeHandle.cs b/src/Microsoft.PowerShell.Commands.Diagnostics/PdhSafeHandle.cs
index 7337d65903..3a122d8cec 100644
--- a/src/Microsoft.PowerShell.Commands.Diagnostics/PdhSafeHandle.cs
+++ b/src/Microsoft.PowerShell.Commands.Diagnostics/PdhSafeHandle.cs
@@ -4,7 +4,10 @@
using System;
using System.Runtime.InteropServices;
+
+#if !CORECLR
using System.Runtime.ConstrainedExecution;
+#endif
namespace Microsoft.Powershell.Commands.GetCounter.PdhNative
{
@@ -21,7 +24,9 @@ namespace Microsoft.Powershell.Commands.GetCounter.PdhNative
}
+#if !CORECLR // ReliabilityContract not supported on CoreCLR
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
+#endif
protected override bool ReleaseHandle()
{
return (PdhHelper.PdhCloseLog(handle, 0) == 0);
@@ -44,7 +49,9 @@ namespace Microsoft.Powershell.Commands.GetCounter.PdhNative
}
+#if !CORECLR // ReliabilityContract not supported on CoreCLR
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
+#endif
protected override bool ReleaseHandle()
{
return (PdhHelper.PdhCloseQuery(handle) == 0);
@@ -64,7 +71,9 @@ namespace Microsoft.Powershell.Commands.GetCounter.PdhNative
}
+#if !CORECLR // ReliabilityContract not supported on CoreCLR
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
+#endif
protected override bool ReleaseHandle()
{
return (PdhHelper.PdhCloseLog(handle, 0) == 0);
diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/project.json b/src/Microsoft.PowerShell.Commands.Diagnostics/project.json
index a772d0d34f..04729e5c9b 100644
--- a/src/Microsoft.PowerShell.Commands.Diagnostics/project.json
+++ b/src/Microsoft.PowerShell.Commands.Diagnostics/project.json
@@ -45,16 +45,7 @@
"define": [ "CORECLR" ],
"compile": {
"excludeFiles": [
- "PdhSafeHandle.cs",
"GetEventSnapin.cs",
- "CounterSample.cs",
- "CounterSet.cs",
- "PdhHelper.cs",
- "ExportCounterCommand.cs",
- "GetCounterCommand.cs",
- "ImportCounterCommand.cs",
- "CounterFileInfo.cs",
-
"gen/GetEventResources.cs"
]
}
@@ -64,7 +55,10 @@
"net451": {
"buildOptions": {
"compile": {
- "excludeFiles": [ "gen/GetEventResources.cs" ]
+ "excludeFiles": [
+ "CoreCLR/Stubs.cs",
+ "gen/GetEventResources.cs"
+ ]
},
"debugType": "full"
}
diff --git a/src/Modules/Windows-Core/Microsoft.PowerShell.Diagnostics/Diagnostics.format.ps1xml b/src/Modules/Windows-Core/Microsoft.PowerShell.Diagnostics/Diagnostics.format.ps1xml
new file mode 100644
index 0000000000..dfac01d1cb
--- /dev/null
+++ b/src/Modules/Windows-Core/Microsoft.PowerShell.Diagnostics/Diagnostics.format.ps1xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+ Counter
+
+ Microsoft.PowerShell.Commands.GetCounter.PerformanceCounterSampleSet
+
+
+
+
+
+ 25
+ left
+
+
+
+ left
+ 100
+
+
+
+
+
+
+
+ Timestamp
+
+
+ Readings
+
+
+
+
+
+
+
+ Counter
+
+ Microsoft.PowerShell.Commands.GetCounter.CounterFileInfo
+
+
+
+
+ 30
+ left
+
+
+ 30
+ left
+
+
+ 30
+ left
+
+
+
+
+
+
+
+ OldestRecord
+
+
+ NewestRecord
+
+
+ SampleCount
+
+
+
+
+
+
+
+
diff --git a/src/Modules/Windows-Core/Microsoft.PowerShell.Diagnostics/Event.format.ps1xml b/src/Modules/Windows-Core/Microsoft.PowerShell.Diagnostics/Event.format.ps1xml
new file mode 100644
index 0000000000..32de7568aa
--- /dev/null
+++ b/src/Modules/Windows-Core/Microsoft.PowerShell.Diagnostics/Event.format.ps1xml
@@ -0,0 +1,121 @@
+
+
+
+
+ Default
+
+ System.Diagnostics.Eventing.Reader.EventLogRecord
+
+
+ ProviderName
+
+
+
+
+
+ 25
+
+
+ 8
+ right
+
+
+ 16
+
+
+
+
+
+
+
+
+ TimeCreated
+
+
+ Id
+
+
+ LevelDisplayName
+
+
+ Message
+
+
+
+
+
+
+
+
+ Default
+
+ System.Diagnostics.Eventing.Reader.EventLogConfiguration
+
+
+
+
+
+
+ 9
+
+
+
+ 18
+ right
+
+
+
+ 11
+ right
+
+
+
+
+
+
+
+ LogMode
+
+
+ MaximumSizeInBytes
+
+
+ RecordCount
+
+
+ LogName
+
+
+
+
+
+
+
+ Default
+
+ System.Diagnostics.Eventing.Reader.ProviderMetadata
+
+
+
+
+
+
+ Name
+
+
+ LogLinks
+
+
+ Opcodes
+
+
+ Tasks
+
+
+
+
+
+
+
+
+
diff --git a/src/Modules/Windows-Core/Microsoft.PowerShell.Diagnostics/GetEvent.types.ps1xml b/src/Modules/Windows-Core/Microsoft.PowerShell.Diagnostics/GetEvent.types.ps1xml
new file mode 100644
index 0000000000..bebbb9ea51
--- /dev/null
+++ b/src/Modules/Windows-Core/Microsoft.PowerShell.Diagnostics/GetEvent.types.ps1xml
@@ -0,0 +1,139 @@
+
+
+
+
+
+ System.Diagnostics.Eventing.Reader.EventLogConfiguration
+
+
+ PSStandardMembers
+
+
+ DefaultDisplayPropertySet
+
+ LogName
+ MaximumSizeInBytes
+ RecordCount
+ LogMode
+
+
+
+
+
+
+
+ System.Diagnostics.Eventing.Reader.EventLogRecord
+
+
+ PSStandardMembers
+
+
+ DefaultDisplayPropertySet
+
+ TimeCreated
+ ProviderName
+ Id
+ Message
+
+
+
+
+
+
+
+ System.Diagnostics.Eventing.Reader.ProviderMetadata
+
+
+ ProviderName
+ Name
+
+
+ PSStandardMembers
+
+
+ DefaultDisplayPropertySet
+
+ Name
+ LogLinks
+
+
+
+
+
+
+
+ Microsoft.PowerShell.Commands.GetCounter.CounterSet
+
+
+ Counter
+ Paths
+
+
+
+
+ Microsoft.PowerShell.Commands.GetCounter.PerformanceCounterSample
+
+
+ PSStandardMembers
+
+
+ DefaultDisplayPropertySet
+
+ Path
+ InstanceName
+ CookedValue
+
+
+
+
+
+
+
+ Microsoft.PowerShell.Commands.GetCounter.PerformanceCounterSampleSet
+
+
+ PSStandardMembers
+
+
+ DefaultDisplayPropertySet
+
+ Timestamp
+ Readings
+
+
+
+
+
+
+
+ Microsoft.PowerShell.Commands.GetCounter.PerformanceCounterSampleSet
+
+
+ Readings
+
+ $strPaths = ""
+ foreach ($ctr in $this.CounterSamples)
+ {
+ $strPaths += ($ctr.Path + " :" + "`n")
+ $strPaths += ($ctr.CookedValue.ToString() + "`n`n")
+ }
+ return $strPaths
+
+
+
+
+
diff --git a/src/Modules/Windows-Core/Microsoft.PowerShell.Diagnostics/Microsoft.PowerShell.Diagnostics.psd1 b/src/Modules/Windows-Core/Microsoft.PowerShell.Diagnostics/Microsoft.PowerShell.Diagnostics.psd1
index eb03f078d2..a394a1931c 100644
--- a/src/Modules/Windows-Core/Microsoft.PowerShell.Diagnostics/Microsoft.PowerShell.Diagnostics.psd1
+++ b/src/Modules/Windows-Core/Microsoft.PowerShell.Diagnostics/Microsoft.PowerShell.Diagnostics.psd1
@@ -5,9 +5,9 @@ CompanyName="Microsoft Corporation"
Copyright="© Microsoft Corporation. All rights reserved."
ModuleVersion="3.0.0.0"
PowerShellVersion="3.0"
-CmdletsToExport="Get-WinEvent", "New-WinEvent"
+CmdletsToExport="Get-WinEvent", "New-WinEvent", "Get-Counter", "Import-Counter", "Export-Counter"
NestedModules="Microsoft.PowerShell.Commands.Diagnostics.dll"
-TypesToProcess="..\..\GetEvent.types.ps1xml"
-FormatsToProcess="..\..\Event.format.ps1xml"
+TypesToProcess="GetEvent.types.ps1xml"
+FormatsToProcess="Event.format.ps1xml", "Diagnostics.format.ps1xml"
HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=390783'
-}
\ No newline at end of file
+}