Downloads:

778

Downloads of v 1.00.0004:

497

Last Update:

4/8/2015

Package Maintainer(s):

Software Author(s):

  • Jon Newman

Tags:

types powershell cmdlets msi

CType

1.00.0004 | Updated: 4/8/2015

Downloads:

778

Downloads of v 1.00.0004:

497

Maintainer(s):

Software Author(s):

  • Jon Newman

CType 1.00.0004

Some Checks Have Failed or Are Not Yet Complete

1 Test Unknown and 1 Passing Test


Validation Testing Unknown


Verification Testing Passed

Details

To install CType, run the following command from the command line or from PowerShell:

>

To upgrade CType, run the following command from the command line or from PowerShell:

>

To uninstall CType, run the following command from the command line or from PowerShell:

>

NOTE: This applies to both open source and commercial editions of Chocolatey.

1. Ensure you are set for organizational deployment

Please see the organizational deployment guide

  • Open Source or Commercial:
    • Proxy Repository - Create a proxy nuget repository on Nexus, Artifactory Pro, or a proxy Chocolatey repository on ProGet. Point your upstream to https://chocolatey.org/api/v2. Packages cache on first access automatically. Make sure your choco clients are using your proxy repository as a source and NOT the default community repository. See source command for more information.
    • You can also just download the package and push it to a repository Download

3. Enter your internal repository url

(this should look similar to https://chocolatey.org/api/v2)

4. Choose your deployment method:


choco upgrade ctype -y --source="'STEP 3 URL'" [other options]

See options you can pass to upgrade.

See best practices for scripting.

Add this to a PowerShell script or use a Batch script with tools and in places where you are calling directly to Chocolatey. If you are integrating, keep in mind enhanced exit codes.

If you do use a PowerShell script, use the following to ensure bad exit codes are shown as failures:


choco upgrade ctype -y --source="'STEP 3 URL'" 
$exitCode = $LASTEXITCODE

Write-Verbose "Exit code was $exitCode"
$validExitCodes = @(0, 1605, 1614, 1641, 3010)
if ($validExitCodes -contains $exitCode) {
  Exit 0
}

Exit $exitCode

- name: Ensure ctype installed
  win_chocolatey:
    name: ctype
    state: present
    version: 1.00.0004
    source: STEP 3 URL

See docs at https://docs.ansible.com/ansible/latest/modules/win_chocolatey_module.html.

Coming early 2020! Central Managment Reporting available now! More information...


chocolatey_package 'ctype' do
  action    :install
  version  '1.00.0004'
  source   'STEP 3 URL'
end

See docs at https://docs.chef.io/resource_chocolatey_package.html.


Chocolatey::Ensure-Package
(
    Name: ctype,
    Version: 1.00.0004,
    Source: STEP 3 URL
);

Requires Otter Chocolatey Extension. See docs at https://inedo.com/den/otter/chocolatey.


cChocoPackageInstaller ctype
{
   Name     = 'ctype'
   Ensure   = 'Present'
   Version  = '1.00.0004'
   Source   = 'STEP 3 URL'
}

Requires cChoco DSC Resource. See docs at https://github.com/chocolatey/cChoco.


package { 'ctype':
  provider => 'chocolatey',
  ensure   => '1.00.0004',
  source   => 'STEP 3 URL',
}

Requires Puppet Chocolatey Provider module. See docs at https://forge.puppet.com/puppetlabs/chocolatey.


salt '*' chocolatey.install ctype version="1.00.0004" source="STEP 3 URL"

See docs at https://docs.saltstack.com/en/latest/ref/modules/all/salt.modules.chocolatey.html.

5. If applicable - Chocolatey configuration/installation

See infrastructure management matrix for Chocolatey configuration elements and examples.

This package was approved by moderator ferventcoder on 5/6/2015.

Description

CType makes it easy to create .NET types, including table formatting and SQL wrappers.


chocolateyInstall.ps1
$dir = Split-Path -Parent $MyInvocation.MyCommand.Path
$path = Join-Path $dir 'tools\CType.msi'
if (Test-Path $path)
{
    Write-Debug "CType\chocolateyInstall.ps1: $path already present"
}
else
{
    Write-Debug "CType\chocolateyInstall.ps1: $path not already present"
}
Write-Debug "CType\chocolateyInstall.ps1: running Install-ChocolateyInstallPackage -PackageName CType -FileType MSI -SilentArgs /Quiet -File $path"
Install-ChocolateyInstallPackage -PackageName CType -FileType MSI -SilentArgs '/Quiet' -File $path
Write-Debug "CType\chocolateyInstall.ps1: ran MSI installer"
chocolateyUninstall.ps1
$dir = Split-Path -Parent $MyInvocation.MyCommand.Path
$path = Join-Path $dir 'tools\CType.msi'
if (Test-Path $path)
{
    Write-Debug "CType\chocolateyUninstall.ps1: found $path"
}
else
{
    Write-Debug "CType\chocolateyUninstall.ps1: did not find $path"
}

$env:chocolateyInstallOverride = "true"
$env:chocolateyInstallArguments = "$path /quiet"
Write-Debug "The current version of Chocolatey appears to contain a bug in Uninstall-ChocolateyPackage,"
Write-Debug "where the -File parameter value is ignored when -FileType is MSI."
Write-Debug "I bypass this by setting"
Write-Debug '$env:chocolateyInstallOverride = "true"'
Write-Debug '$env:chocolateyInstallArguments = "$path /quiet"'
Write-Debug "CType\chocolateyUninstall.ps1: running Uninstall-ChocolateyPackage -PackageName CType -FileType MSI -SilentArgs -File $path"

Write-Debug "CType\chocolateyUninstall.ps1: running Uninstall-ChocolateyPackage -PackageName CType -FileType MSI -SilentArgs /Quiet -File $path"
Uninstall-ChocolateyPackage -PackageName CType -FileType MSI -SilentArgs '/Quiet' -File $path
Write-Debug "CType\chocolateyUninstall.ps1: ran MSI uninstaller"
content\CType\CType.ps1

# CODEWORK Need better parameter validation

[Hashtable]$CType_AddedTypes = @{}

Write-Verbose 'CType.ps1: adding CType base types'
Add-Type -ReferencedAssemblies System.Data -TypeDefinition @'
namespace CType
{
    public class TypeElement
    {
    }
    public class Property : TypeElement
    {
        public string PropertyName;
        public string PropertyType;
        public string PropertyTableWidth;
        public string[] PropertyKeywords;
    }
    public class Parent : TypeElement
    {
        public string ParentTypeName;
    }
    public class Using : TypeElement
    {
        public string Namespace;
    }
    public class ReferencedAssembly : TypeElement
    {
        public string AssemblyName;
    }
    public class SqlWrapper : TypeElement
    {
    }
    public class SqlTemplateObject : TypeElement
    {
        public System.Data.DataRow DataRow;
    }
    public class NoFormatData : TypeElement
    {
    }
}
'@

function Add-CType
{
<#
.SYNOPSIS
Add a locally-defined type to this runspace.

.DESCRIPTION
Add a locally-defined type to this runspace, and optionally define table formatting for the type.
These types can be used as parameter types and in OutputType([typename]) declarations.

.PARAMETER TypeName
Name for the new type. You can include the namespace here or else specify it separately.

.PARAMETER Namespace
Namespace containing the new type. If not specified, the namespace is extracted from TypeName.

.PARAMETER ParentTypeName
Parent class of the new class, default is System.Object

.PARAMETER Using
Other namespaces, typically those containing types specified in PropertyType

.PARAMETER ReferencedAssemblies
Other assemblies, typically those containing types specified in PropertyType

.PARAMETER SqlWrapper
Make the new type a SQL wrapper class for use in ConvertTo-CTypeSqlWrapper.
This is set automatically if any PropertyKeyword contains SQLWrapper,
or if SQLTemplateObject is set.

.PARAMETER SqlTemplateObject
If specified, include all properties of this SQL template object in the SQL wrapper class.
Properties already specified in PropertyName are not affected.
SqlWrapper is automatically set if this is specified.

.PARAMETER NoFormatData
Skip defining formatting metadata for this type.
For example, you might want to combine all the formatting for the types in your module
into a single file.

.PARAMETER PropertyName
Name of a property of the type being defined

.PARAMETER PropertyType
Type of a property of the type being defined

.PARAMETER PropertyTableWidth
Table width in characters of a property of the type being defined.
If one or more properties specify PropertyTableWidth, a formatting directive
will be generated for this type and entered into the runspace.
If not specified, this property is not in the default table format.
This can also be set to '*', in which case this property is displayed at full width;
this should generally only be used for the last property with defined PropertyTableWidth.

.PARAMETER PropertyKeywords
Other keywords. The only keywords currently implemented are "Trim"
which trims leading/trailing whitespace from the output string in the table formatting,
and "SQLWrapper" which designates a read-only property read from the wrapped SQL object.

.EXAMPLE
# Define a new type
PS> @"
PropertyName,PropertyType,PropertyTableWidth,PropertyKeywords
PrimaryTarget,string,25,Trim
SecondaryTarget,string,25,Trim
Weight,int,10
IsPrimary,Boolean,10
Description,String,*
MainConnection,SqlConnection
SecondaryConnection,SqlConnection
"@ | ConvertFrom-Csv | Add-CType -TypeName MyType `
                                 -Namespace MyCompany.Namespace `
                                 -Using System.Data.SqlClient `
                                 -ReferencedAssemblies System.Data

# You can now use this as a full-fledged type, for example define parameters as
# param( [MyCompany.Namespace.MyType]$MyParameter )

# Create an instance of the type
PS> New-Object -TypeName MyCompany.Namespace.MyType -Property @{
    PrimaryTarget = "String1";
    SecondaryTarget = "String2";
    Weight = 4;
    Description = "This is a very long description"
    }

PrimaryTarget             SecondaryTarget           Weight     IsPrimary  Description                                                                                                                
-------------             ---------------           ------     ---------  -----------                                                                                                                
String1                   String2                   4          False      This is a very long description                                                                                            

.EXAMPLE
# Define a new CType Class
ConvertFrom-Csv @'
PropertyType,PropertyName,PropertyTableWidth,PropertyKeywords
string,Name,20
string,HostName,20
DateTime,WhenCreated,25
DateTime,WhenDeleted,25
'@ | Add-CType -TypeName MyCompany.MyNamespace.MyClass
# Create wrapped object
New-Object -Type MyCompany.MyNamespace.MyClass -Property @{
    Name = "MyName"
    WhenCreated = (get-date)
}

.EXAMPLE
# Define a new SQL Wrapper Class
ConvertFrom-Csv @'
PropertyType,PropertyName,PropertyTableWidth,PropertyKeywords
string,Name,20,SQLWrapper
string,HostName,20,SQLWrapper
DateTime,WhenCreated,25,SQLWrapper
DateTime,WhenDeleted,25,SQLWrapper
'@ | Add-CType -TypeName MyCompany.MyNamespace.MyClass -SqlWrapper
# Create wrapped objects
$SqlWrappedObjects = $SqlDataRows | ConvertTo-CTypeSqlWrapper -TypeName MyCompany.MyNamespace.MyClass

.NOTES
This method should only be called once for any class. Calling a second time
is generally harmless as long as the type definition is identical,
otherwise an error will be reported. Types cannot be altered once added to
a process (AppDomain?).

.LINK
ConvertTo-CTypeSqlWrapper
Add-Type
Update-CTypeFormatData
Update-FormatData
#>
    [CmdletBinding()]
    param(
        [string][parameter(Mandatory=$true)]$TypeName,
        [string]$Namespace,
        [string]$ParentTypeName,
        [string[]]$Using,
        [string[]]$ReferencedAssemblies,
        [switch]$SqlWrapper,
        [System.Data.DataRow]$SqlTemplateObject,
        [switch]$NoFormatData,
        [string][parameter(ValueFromPipelineByPropertyName=$true)]$PropertyName,
        [string][parameter(ValueFromPipelineByPropertyName=$true)]$PropertyType,
        [string][parameter(ValueFromPipelineByPropertyName=$true)]$PropertyTableWidth,
        [string[]][parameter(ValueFromPipelineByPropertyName=$true)]$PropertyKeywords
        )
    begin
    {
Write-Verbose -Message @"
$($MyInvocation.InvocationName): TypeName $TypeName
$($MyInvocation.InvocationName): Namespace $Namespace
$($MyInvocation.InvocationName): ParentTypeName $ParentTypeName
$($MyInvocation.InvocationName): Using $Using
$($MyInvocation.InvocationName): ReferencedAssemblies $ReferencedAssemblies
$($MyInvocation.InvocationName): SqlWrapper $SqlWrapper
$($MyInvocation.InvocationName): SqlTemplateObject $SqlTemplateObject
"@
        if (-not $Namespace)
        {
            $nameComponents = $TypeName.Split('.')
            if ($nameComponents.Count -lt 2)
            {
                throw 'You must specify a Namespace or else a TypeName which contains a Namespace'
            }
            $TypeName = $nameComponents[-1]
            $Namespace = $nameComponents[0..($nameComponents.Count - 2)] -join '.'
        }
        if ($CType_AddedTypes["$Namespace.$TypeName"])
        {
            Write-Warning "$($MyInvocation.InvocationName): Class $Namespace.$TypeName was already added; trying anyhow"
        }
        if ($SqlTemplateObject)
        {
            $SqlWrapper = $true
        }
        $propertyList = @()
    }
    process
    {
        if ($PropertyName)
        {
Write-Verbose -Message @"
$($MyInvocation.InvocationName): PropertyName $PropertyName
$($MyInvocation.InvocationName): PropertyType $PropertyType
$($MyInvocation.InvocationName): PropertyTableWidth $PropertyTableWidth
$($MyInvocation.InvocationName): PropertyKeywords $PropertyKeywords
"@
            if (-not $PropertyType)
            {
                throw 'PropertyType must be specified for all properties'
            }
            if ($PropertyTableWidth)
            {
                if ($PropertyTableWidth -ne '*')
                {
                    $w = $PropertyTableWidth -as [int]
                    if ($w -lt 1)
                    {
                        throw "PropertyTableWidth must be either a positive integer or '*' if it is specified"
                    }
                }
            }
            $propertyList += New-Object -TypeName CType.Property -Property @{
                PropertyName = $PropertyName
                PropertyType = $PropertyType
                PropertyTableWidth = $PropertyTableWidth
                PropertyKeywords = $PropertyKeywords
                }
            if ('SQLWrapper' -in $PropertyKeywords)
            {
                $SqlWrapper = $true
            }
        }
    }
    end
    {
        if ($SqlTemplateObject)
        {
            Write-Verbose "$($MyInvocation.InvocationName): SqlTemplateObject specified, adding additional properties"
            foreach ($column in $SqlTemplateObject.Table.Columns)
            {
                $name = $column.ColumnName
                $type = $column.DataType
                if ($name -in $propertyList.PropertyName)
                {
                    Write-Verbose "$($MyInvocation.InvocationName): SqlTemplateObject column $type $name already in property list"            
                }
                else
                {
                    Write-Verbose "$($MyInvocation.InvocationName): SqlTemplateObject column $type $name must be added property list"            
                    $propertyList += New-Object -TypeName CType.Property -Property @{
                        PropertyName = $name;
                        PropertyType = $type;
                        PropertyTableWidth = 0;
                        PropertyKeywords = @('SQLWrapper');
                        }
                }
            }
            $SqlWrapper = $true
        }

        if ($SqlWrapper)
        {
            if ($Using -notcontains 'System.Data')
            {
                $Using += 'System.Data'
            }
            if ($ReferencedAssemblies -notcontains 'System.Data')
            {
                $ReferencedAssemblies += 'System.Data'
            }
        }

        Write-Verbose "$($MyInvocation.InvocationName): building C# type definition"
        $typeDefinition = New-Object -TypeName System.Text.StringBuilder
        $Using = @("System") + ($Using | Where-Object {$_})
        $Using | foreach {
            $null = $typeDefinition.AppendLine("using $_;")
            }
$null = $typeDefinition.AppendLine(@"
namespace $Namespace
{
    public class $TypeName $(if ($ParentTypeName) {": $ParentTypeName"})
    {
"@)
    if ($SqlWrapper)
    {
$null = $typeDefinition.AppendLine(@"
        private System.Data.DataRow WrappedSqlObject;

        public $TypeName(System.Data.DataRow obj)
        {
            this.WrappedSqlObject = obj;
        }

"@)
    }
    foreach ($property in $propertyList)
    {
        $name = $property.PropertyName
        $type = $property.PropertyType
        Write-Verbose "$($MyInvocation.InvocationName) Property $type $name"

        # CSharp seems to be picky about spelling and capitalization of these types
        $typeObject = $type -as [Type]
        if ($typeObject.FullName)
        {
            $type = $typeObject.FullName
        }

        $propertyType = $type
        if ('SqlWrapper' -in $property.PropertyKeywords)
        {
            $valueExpression = "($type)val";
            if ($typeObject.IsValueType)
            {
                $propertytype = "Nullable<$type>"
            }

$null = $typeDefinition.AppendLine(@"
        public $propertyType $name
        {
            get {
                object val = this.WrappedSqlObject["$name"];
                if ((val == null) || (val.GetType().FullName == "System.DBNull"))
                {
                    return null;
                }
            return $valueExpression;
            } // get $propertyType $name
        } // property $propertyType $name


"@)
        }
        else # -not $SqlClassWrapper
        {

$null = $typeDefinition.AppendLine(@"
        public $propertyType $name { get; set; }
"@)

        }
    }

$null = $typeDefinition.AppendLine(@"
    }
}
"@)

        Write-Verbose "$($MyInvocation.InvocationName): Adding type:`n$($typeDefinition.ToString())"
        Add-Type -TypeDefinition $typeDefinition.ToString() -ReferencedAssemblies $ReferencedAssemblies

        $CType_AddedTypes["$Namespace.$classname"] = $true

        if (-not $NoFormatData)
        {
            $tableProperties = $propertyList | Where-Object {$_.PropertyTableWidth}
            if ($tableProperties)
            {
                $text = $tableProperties | Get-CTypeFormatPS1XML -TypeName "$Namespace.$TypeName"
                $text | Update-CTypeFormatData -TypeName "$Namespace.$TypeName"
            }
        }
    }
}

function Update-CTypeFormatData
{
<#
.SYNOPSIS
Add the specified formatting metadata to the current runspace.

.PARAMETER TypeName
Full typename for the type including namespace

.PARAMETER FormatDataString
Format data string from Get-CTypeFormatPS1XML

.EXAMPLE
$tableProperties = ConvertFrom-Csv @'
PropertyType,PropertyName,PropertyTableWidth
string,Name,20
string,HostName,20
DateTime,WhenCreated,25
DateTime,WhenDeleted,25
'@
$text = $tableProperties | Get-CTypeFormatPS1XML -TypeName "$Namespace.$TypeName"
Update-CTypeFormatData -TypeName "$Namespace.$TypeName" -FormatDataString $text

.LINK
Get-CTypeFormatPS1XML
Add-CType
Update-FormatData
Update-CTypeTypeData
#>
    [CmdletBinding()]
    param(
        [string][parameter(Mandatory=$true,Position=0)]$TypeName,
        [string][parameter(Mandatory=$true, ValueFromPipeline=$true)]$FormatDataString
        )
    begin
    {
        $activity = "$($MyInvocation.InvocationName) $TypeName"
        $tempfile = Join-Path $env:temp "$TypeName.$(get-date -Format 'yyyyMMdd-hhmmss-fffffff').format.ps1xml"
        [System.Text.StringBuilder]$text = New-Object -TypeName System.Text.StringBuilder
    }
    process
    {
        $null = $text.AppendLine($FormatDataString)
    }
    end
    {
        Write-Verbose "$activity`: Adding format data to temporary file $tempfile from formatting directive:`n$FormatDataString"
        $FormatDataString | Set-Content -Path $tempFile
        try
        {
            Write-Verbose "$activity`: Updating format data"
            Update-FormatData -PrependPath $tempfile
        }
        catch
        {
            if (Test-Path $tempfile -ErrorAction SilentlyContinue)
            {
                Write-Verbose "$activity`: Deleting temporary file $tempfile"
                Remove-Item $tempfile
            }
        }
    }
}

function Update-CTypeTypeData
{
<#
.SYNOPSIS
Add the specified type metadata to the current runspace.

.PARAMETER TypeName
Full typename for the type including namespace

.PARAMETER TypeDataString
Type metadata string

.EXAMPLE
Update-CTypeTypeData -TypeName "$Namespace.$TypeName" -TypeDataString @"
<?xml version="1.0" encoding="utf-8" ?>
<Types>
    <Type>
        <Name>MyCompany.MyNamespace.MyType</Name>
        <Members>
            <MemberSet>
                <Name>PSStandardMembers</Name>
                <Members>
                    <NoteProperty>
                        <Name>SerializationDepth</Name>
                        <Value>
                            4
                        </Value>
                    </NoteProperty>
                </Members>
            </MemberSet>
        </Members>
    </Type>
</Types>
"@

.LINK
Update-CTypeFormatData
#>
    [CmdletBinding()]
    param(
        [string][parameter(Mandatory=$true,Position=0)]$TypeName,
        [string][parameter(Mandatory=$true, ValueFromPipeline=$true)]$TypeDataString
        )
    begin
    {
        $activity = "$($MyInvocation.InvocationName) $TypeName"
        $tempfile = Join-Path $env:temp "$TypeName.$(get-date -Format 'yyyyMMdd-hhmmss-fffffff').format.ps1xml"
        [System.Text.StringBuilder]$text = New-Object -TypeName System.Text.StringBuilder
    }
    process
    {
        $null = $text.AppendLine($TypeDataString)
    }
    end
    {
        Write-Verbose "$activity`: Adding format data to temporary file $tempfile from formatting directive:`n$TypeDataString"
        $TypeDataString | Set-Content -Path $tempFile
        try
        {
            Write-Verbose "$activity`: Updating format data"
            Update-TypeData -PrependPath $tempfile
        }
        catch
        {
            if (Test-Path $tempfile -ErrorAction SilentlyContinue)
            {
                Write-Verbose "$activity`: Deleting temporary file $tempfile"
                Remove-Item $tempfile
            }
        }
    }
}

function Get-CTypeFormatPS1XML
{
<#
.SYNOPSIS
Returns the text of a PS1XML which defines output formatting for a type.

.DESCRIPTION
Returns the text of a PS1XML which defines output formatting for a type.
Pass this to Update-CTypeFormatData to apply this formatting to the current session.
You can also save this into a PS1XML file associated with your module.

.PARAMETER TypeName
Name for the type

.PARAMETER PropertyName
Name of a property of the type being defined

.PARAMETER PropertyType
Type of a property of the type being defined

.PARAMETER PropertyTableWidth
Table width of a property of the type being defined, per Add-CType.

.PARAMETER PropertyKeywords
Other keywords per Add-CType.

.LINK
Add-CType
Update-CTypeFormatData
#>
    [OutputType([string])]
    [CmdletBinding()]
    param(
        [string][parameter(Mandatory=$true,Position=0)]$TypeName,
        [string][parameter(ValueFromPipelineByPropertyName=$true)]$PropertyName,
        [string][parameter(ValueFromPipelineByPropertyName=$true)]$PropertyType,
        [string][parameter(ValueFromPipelineByPropertyName=$true)]$PropertyTableWidth,
        [string[]][parameter(ValueFromPipelineByPropertyName=$true)]$PropertyKeywords
        )

    begin
    {
        $activity = "$($MyInvocation.InvocationName) $TypeName"
        Write-Verbose $activity
# You could also build this using the [xml] class
$fileHeader = @"
<?xml version="1.0" encoding="utf-8" ?>
<Configuration>
    <ViewDefinitions>

"@
$templateViewHeader = @"
        <View>
            <Name>{0}</Name>
            <ViewSelectedBy>
                <TypeName>{0}</TypeName>
            </ViewSelectedBy>
            <TableControl>
                <TableHeaders>
"@
$templateColumnHeader = @"
                    <TableColumnHeader>
                        <Label>{0}</Label>
                    </TableColumnHeader>
"@
$templateColumnHeaderWithWidth = @"
                    <TableColumnHeader>
                        <Label>{0}</Label>
                        <Width>{1}</Width>
                    </TableColumnHeader>
"@
$headerItemSeparator = @"
                </TableHeaders>
                <TableRowEntries>
                    <TableRowEntry>
                        <TableColumnItems>
"@
$templateColumnItem = @"
                            <TableColumnItem>
                                <PropertyName>{0}</PropertyName>
                            </TableColumnItem>
"@
$templateColumnItemWithTrim = @"
                            <TableColumnItem>
                                <ScriptBlock>
                                  (Out-String -InputObject `$_.{0}).Trim()
                                </ScriptBlock>
                            </TableColumnItem>
"@
$viewFooter = @"
                        </TableColumnItems>
                    </TableRowEntry>
                 </TableRowEntries>
            </TableControl>
        </View>        
"@
$fileFooter = @"
    </ViewDefinitions>
</Configuration>
"@

        $propertyList = New-Object System.Collections.ArrayList

        $fileContent = New-Object System.Text.StringBuilder -ArgumentList $fileHeader
        $null = $fileContent.AppendLine( ($templateViewHeader -f $TypeName) )
    }

    process
    {
Write-Verbose -Message @"
$activity`: PropertyName $PropertyName
$activity`: PropertyType $PropertyType
$activity`: PropertyTableWidth $PropertyTableWidth
$activity`: PropertyKeywords $PropertyKeywords
"@
        if ($PropertyName -and $PropertyTableWidth)
        {
            if (-not $PropertyType)
            {
                throw 'PropertyType must be specified for all properties'
            }
            if ($PropertyTableWidth)
            {
                if ($PropertyTableWidth -ne '*')
                {
                    $w = $PropertyTableWidth -as [int]
                    if ($w -lt 1)
                    {
                        throw "PropertyTableWidth must be either a positive integer or '*' if it is specified"
                    }
                }
            }
            $obj = New-Object -TypeName CType.Property -Property @{
                PropertyName = $PropertyName
                PropertyType = $PropertyType
                PropertyTableWidth = $PropertyTableWidth
                PropertyKeywords = $PropertyKeywords
                }
            $null = $propertyList.Add($obj)
        }
        else
        {
            Write-Verbose "$activity`: Skipping due to null name or width"
        }
    }

    end
    {
        foreach ($p in $propertyList)
        {
            if ($p.PropertyTableWidth)
            {
                if ($p.PropertyTableWidth -eq '*')
                {
                    $null = $fileContent.AppendLine( ($templateColumnHeader -f $p.PropertyName) )
                }
                else
                {
                    $null = $fileContent.AppendLine( ($templateColumnHeaderWithWidth -f $p.PropertyName,$p.PropertyTableWidth) )
                }
            }
        }
        $null = $fileContent.AppendLine( $headerItemSeparator )
        foreach ($p in $propertyList)
        {
            if ($p.PropertyTableWidth)
            {
                if ('Trim' -in $p.PropertyKeywords)
                {
                    $null = $fileContent.AppendLine( ($templateColumnItemWithTrim -f $p.PropertyName) )
                }
                else
                {
                    $null = $fileContent.AppendLine( ($templateColumnItem -f $p.PropertyName) )
                }
            }
        }
        $null = $fileContent.AppendLine( $viewFooter )
        $null = $fileContent.AppendLine( $fileFooter )

        Write-Output $fileContent.ToString()
    }
}


function ConvertTo-CTypeSqlWrapper
{
<#
.SYNOPSIS
Wraps a SQL row in a wrapper object.
.DESCRIPTION
Wraps a SQL row in a wrapper object. The wrapper class must first be defined by
Add-CType -SqlWrapper. The wrapped object has several advantages over the
raw System.Data.DataRow object:
(1) Property value System.DBNull is automatically converted to $null so that it is boolean-false in scripting
(2) Type can be use in [OutputType([typename])] attributes
(3) Type can be assigned formatting directives and other PowerShell type decorations
(4) All properties are read-only
(5) Hides unneeded properties of base SQL object

.PARAMETER InputObject
System.Data.DataRow object to be wrapped

.PARAMETER TypeName
Name of wrapper class, should be the same as for Add-CType

.PARAMETER AddCType
If specified, the type will be created automatically
the first time an input object of this type is received,
where the first object is a template.

.PARAMETER AddCTypeScriptBlock
If specified, the type will be created automatically
the first time an input object of this type is received,
where the first object is a template and this script block
defines additional properties of the type. This implies -AddCType.
Note the limitations in Notes below.

.EXAMPLE
$connection = New-Object System.Data.SqlClient.SqlConnection $connectionString
$command = New-Object System.Data.SqlClient.SqlCommand $commandString,$connection
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter $command
$dataset = New-Object System.Data.DataSet
$null = $adapter.Fill($dataSet)
$result = $tables[0].Rows
$wrappedResult = $result | ConvertTo-CTypeSqlWrapper -TypeName MyCompany.MyNamespace.MyWrapperClass

.NOTES
Note that the type will be defined based on the first InputObject encountered.
Even if subsequent objects have a different property list, the type cannot be changed.

Note that you can define a type using AddCTypeScriptBlock, but because that type
cannot be defined until the first template object is created, you may have difficulty
using the type in an OutputType([typename]) block or a parameter definition.
Consider generating the type definition with ConvertTo-CTypeDefinition
and pasting the CType definition directly into your code.

.LINK
Add-CType
CType
ConvertTo-CTypeSqlDefinition
#>
    [CmdletBinding()]
    param(
        [parameter(ValueFromPipeline=$true)][System.Data.DataRow]$InputObject,
        [parameter(Mandatory=$true,Position=0)][string]$TypeName,
        [switch]$AddCType,
        [ScriptBlock[]][parameter(Position=1)]$AddCTypeScriptBlock
    )
    process
    {
        if ($AddCType -or $AddCTypeScriptBlock)
        {
            if (-not $CType_AddedTypes[$TypeName])
            {
                CType -TypeName $TypeName -TypeElement $AddCTypeScriptBlock,(SqlTemplateObject $InputObject)
            }
        }
        New-Object -TypeName $TypeName -ArgumentList $InputObject
    }
}

function CType
{
<#
.SYNOPSIS
Create a new type
.PARAMETER TypeName
Name of the new type. Include namespace e.g. "MyCompany.MyNamespace.MyClassName"
.PARAMETER TypeElement
One or more script blocks or type elements which define class properties and other elements of the class.
The type elements may only contain objects on the list
property, sqlproperty, parent, use, ref,SqlWrapper, SqlTemplateObject, and NoFormatData,
and the script blocks must evaluate to objects of those types.
The script block definition must begin on the same line as the CType invocation,
or must be linked with backtick.
.EXAMPLE
# Creates a type with 4 properties, three of which are displayed in the default formatter.
CType MyCompany.MyNamespace.MyClassName {
  parent MyCompany.MyNamespace.MyParentClass
  property string PropertyName1 -PropertyTableWidth 20 -PropertyKeywords trim
  if ($true)
  {
    property int PropertyName2  -PropertyTableWidth 15
  }
  property string PropertyName3 -PropertyTableWidth *
  property bool PropertyName4
}
.EXAMPLE
# Creates a type with 4 properties, three SQL wrappers and one non-wrapped property.
# The non-wrapped property can be set like any other read/write property, the others
# always read from the equivalent property of the wrapped DataRow object.
CType MyCompany.MyNamespace.MyClassName {
  parent MyCompany.MyNamespace.MyParentClass
  sqlproperty string PropertyName1 -PropertyTableWidth 20 -PropertyKeywords trim
  sqlproperty int PropertyName2  -PropertyTableWidth 15
  property string PropertyName3 -PropertyTableWidth *
  sqlproperty bool PropertyName4
}
.NOTES
A type with a given name can only be defined once per PowerShell runspace.
If you need to change it you will need to exit the runspace where it is defined.
.LINK
Add-CType
#>
    [CmdletBinding()]
    param(
        [string][parameter(Mandatory=$true,Position=0)]$TypeName,
        [parameter(Position=1)]$TypeElement
        )
    $typeElements = foreach ($element in $TypeElement)
    {
        if ($element)
        {
            if ($element -is [ScriptBlock])
            {
                Invoke-Command -ScriptBlock $element
            }
            elseif ($element -is [ScriptBlock[]])
            {
                $element | foreach {Invoke-Command -ScriptBlock $_}
            }
            else
            {
                $element
            }
        }
    }
    foreach ($element in $typeElements)
    {
        if (-not ($element -is [CType.TypeElement]))
        {
            throw "$($MyInvocation.InvocationName): Invalid TypeElement $($element.GetType().FullName): TypeElement may only contain property, parent, use, ref,SqlWrapper, SqlTemplateObject, and NoFormatData, or script blocks generate them"
        }
    }
    [CType.Property[]]$properties = $typeElements | Where-Object {$_ -is [CType.Property]}
    [string[]]$parentTypes = $typeElements | Where-Object {$_ -is [CType.Parent]} | Select-Object -ExpandProperty ParentTypeName
    [string[]]$using = $typeElements | Where-Object {$_ -is [CType.Using]} | Select-Object -ExpandProperty Namespace
    [string[]]$referencedAssemblies = $typeElements | Where-Object {$_ -is [CType.ReferencedAssembly]} | Select-Object -ExpandProperty AssemblyName
    [System.Data.DataRow]$sqlTemplateObject = $null
    [System.Data.DataRow[]]$sqlTemplateObjects = @($typeElements | Where-Object {$_ -is [CType.SqlTemplateObject]} | Select-Object -ExpandProperty DataRow)
    if ($parentTypes)
    {
        if ($parentTypes.Count -gt 1)
        {
            throw 'You may only specify one parent type'
        }
        $parentType = $parentTypes[0]
    }
    else
    {
        $parentType = $null
    }
    if ($sqlTemplateObjects)
    {
        if ($sqlTemplateObjects.Count -gt 1)
        {
            throw 'You may only specify one SqlTemplateObject'
        }
        $sqlTemplateObject = $sqlTemplateObjects[0]
    }
    else
    {
        $sqlTemplateObject = $null
    }
    [bool]$noFormatData = [bool]($typeElements | Where-Object {$_ -is [CType.NoFormatData]} )
    [bool]$sqlWrapper = [bool]($typeElements | Where-Object {$_ -is [CType.SqlWrapper]} )
    $split = $TypeName.Split('.')
    if ($split.Count -lt 2)
    {
        throw 'You must specify full classname including namespace'
    }
    $classname = $split[-1]
    $namespace = $split[0..($split.Count-2)] -join '.'

    $properties | Add-CType -TypeName $TypeName `
                            -ParentTypeName $parentType `
                            -Using $using `
                            -ReferencedAssemblies $referencedAssemblies `
                            -SqlWrapper:$sqlWrapper `
                            -SqlTemplateObject $SqlTemplateObject `
                            -NoFormatData:$NoFormatData
}

function property
{
<#
.SYNOPSIS
Define a property for use in CType
#>
    [CmdletBinding()]
    [OutputType([CType.Property])]
    param(
        [string][parameter(Mandatory=$true,Position=0)]$PropertyType,
        [string][parameter(Mandatory=$true,Position=1)]$PropertyName,
        [string]$width,
        [switch]$trim
        )
    $propertyHash = @{
        PropertyType=$PropertyType
        PropertyName=$PropertyName
        }
    if ($width)
    {
        $propertyHash['PropertyTableWidth'] = $width
    }
    if ($trim)
    {
        $propertyHash['PropertyKeywords'] = "Trim"
    }
    New-Object -TypeName CType.Property -Property $propertyHash
}

function sqlproperty
{
<#
.SYNOPSIS
Define a SQL wrapper property for use in CType
#>
    [CmdletBinding()]
    [OutputType([CType.Property])]
    param(
        [string][parameter(Mandatory=$true,Position=0)]$PropertyType,
        [string][parameter(Mandatory=$true,Position=1)]$PropertyName,
        [string]$width,
        [switch]$trim
        )
    $propertyHash = @{
        PropertyType=$PropertyType
        PropertyName=$PropertyName
        }
    if ($width)
    {
        $propertyHash['PropertyTableWidth'] = $width
    }
    if ($trim)
    {
        $propertyHash['PropertyKeywords'] = ('SQLWrapper','Trim')
    }
    else
    {
        $propertyHash['PropertyKeywords'] = 'SQLWrapper'
    }
    New-Object -TypeName CType.Property -Property $propertyHash
}

function parent
{
<#
.SYNOPSIS
Specify a parent class for use in CType
#>
    [CmdletBinding()]
    [OutputType([CType.Parent])]
    param(
        [string][parameter(Mandatory=$true,Position=0)]$ParentTypeName
        )
    New-Object -TypeName CType.ParentType -Property @{
        ParentTypeName=$ParentTypeName
        }
}

function use
{
<#
.SYNOPSIS
Specify a Using reference for use in CType
#>
    [CmdletBinding()]
    [OutputType([CType.Using])]
    param(
        [string][parameter(Mandatory=$true,Position=0)]$Namespace
        )
    New-Object -TypeName CType.Using -Property @{
        Namespace=$Namespace
        }
}

function ref
{
<#
.SYNOPSIS
Specify a Referenced Assembly for use in CType
#>
    [CmdletBinding()]
    [OutputType([CType.ReferencedAssembly])]
    param(
        [string][parameter(Mandatory=$true,Position=0)]$AssemblyName
        )
    New-Object -TypeName CType.ReferencedAssembly -Property @{
        AssemblyName=$AssemblyName
        }
}

function SqlWrapper
{
<#
.SYNOPSIS
Specify that a CType should be a SQL Wrapper
.LINK
ConvertTo-CTypeSqlWrapper
#>
    [CmdletBinding()]
    [OutputType([CType.SqlWrapper])]
    param(
        )
    New-Object -TypeName CType.SqlWrapper
}

function SqlTemplateObject
{
<#
.SYNOPSIS
Specify a SQL template object for use in CType
#>
    [CmdletBinding()]
    [OutputType([CType.ReferencedAssembly])]
    param(
        [System.Data.DataRow][parameter(Mandatory=$true,Position=0)]$SqlTemplateObject
        )
    New-Object -TypeName CType.SqlTemplateObject -Property @{
        DataRow=$SqlTemplateObject
        }
}

function NoFormatData
{
<#
.SYNOPSIS
Specify that a CType should not generate formatting data
.DESCRIPTION
Specify that a CType should not generate formatting data.
For example, you might perfer to generate the formatting data using
Get-CTypeFormatPS1XML and enter this into the PS1XML for your module.
#>
    [CmdletBinding()]
    [OutputType([CType.NoFormatData])]
    param(
        )
    New-Object -TypeName CType.NoFormatData
}

function ConvertTo-CTypeDefinition
{
<#
.SYNOPSIS
Generate a string representing a CType definition for the specified SQL object
.DESCRIPTION
Generate a string representing a CType definition for the specified SQL object.
You can paste this string into your module code to generate a CType SQL wrapper
for objects of the specified class, reordering the properties and adding
width and keywords to specify the formatting for the type.
.LINK
CType
Add-CType
ConvertTo-CTypeSqlWrapper
#>
    [CmdletBinding()]
    [OutputType([string])]
    param(
        [System.Data.DataRow][parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)]$SqlTemplateObject
        )
    process
    {
[System.Text.StringBuilder]$typeDefinition = New-Object -TypeName System.Text.StringBuilder -ArgumentList @"
CType YourClassNameHere {
    SqlWrapper
    parent YourParentClassHere

"@
        foreach ($column in $SqlTemplateObject.Table.Columns)
        {
            $name = $column.ColumnName
            $type = $column.DataType
            $null = $typeDefinition.AppendLine("    sqlproperty $type $name")
        }
        $null = $typeDefinition.AppendLine('}')
        $typeDefinition.ToString()
    }
}

function Test-CTypeIsDefined
{
<#
.SYNOPSIS
Test whether a CType type is already defined.
.DESCRIPTION
Test whether a CType type is already defined.
Note that types may not be removed from a PowerShell session once defined.
.PARAMETER TypeName
Name for the type.
.EXAMPLE
if (-not (Test-CTypeIsDefined MyCompany.MyNamespace.ClassName))
{
    CType MyCompany.MyNamespace.ClassName2 {
        CTypeProperty int Property1
        CTypeProperty string Property2
        CTypeProperty boolean Property3
    }
}
.NOTES
This method is fast, but it only detects CType types, not .NET types generally.
.LINK
CType
Add-CType
#>
    [CmdletBinding()]
    [OutputType([bool])]
    param(
        [string][parameter(Mandatory=$true,Position=0)]$TypeName
        )
    return [bool]($CType_AddedTypes[$TypeName])
}

function Test-CTypeDotNetTypeIsDefined
{
<#
.SYNOPSIS
Test whether a type is already defined.
.DESCRIPTION
Test whether a type is already defined.
Note that types may not be removed from a PowerShell session once defined.
.PARAMETER TypeName
Name for the type.
.EXAMPLE
if (-not (Test-CTypeDotNetTypeIsDefined MyCompany.MyNamespace.ClassName))
{
    CType MyCompany.MyNamespace.ClassName2 {
        CTypeProperty int Property1
        CTypeProperty string Property2
        CTypeProperty boolean Property3
    }
}
.NOTES
This method uses .NET reflection to search for the type, so it can take 100-200ms to run.
Use it sparingly. Consider using Test-CTypeIsDefined instead.
.LINK
CType
Add-CType
#>
    [CmdletBinding()]
    [OutputType([bool])]
    param(
        [string][parameter(Mandatory=$true,Position=0)]$TypeName
        )
    $time = Measure-Command {
        $val = [bool]([appdomain]::CurrentDomain.GetAssemblies() | Where-Object DefinedTypes | Where-Object {$_.DefinedTypes.FullName -eq $TypeName})
    }
    Write-Verbose "$($MyInvocation.InvocationName): Searching for type $TypeName took $($time.TotalMilliseconds) milliseconds"
    $val
}
content\CType\CType.psd1
 
content\CType\CType.psm1
# vstfpg06\Consol_06_TPC5 $/Nebula/Source/Ops Tools/current/Scripts/CType/CType.psm1

# Remember the current directory
$Script:ScriptDir = Split-Path $MyInvocation.MyCommand.Path

. $Script:ScriptDir\CType.ps1

Export-ModuleMember -Function '*-CType*',CType,property,sqlproperty,parent,use,ref,SqlWrapper,SqlTemplateObject,NoFormatData
content\CType\en-US\about_CType.help.txt
TOPIC
    about_CType

SHORT DESCRIPTION
    Create real .NET types without having to write .NET code, plus default table formatting!

LONG DESCRIPTION
    CType enables module and script authors to easily create their own .NET types.
    Real .NET types created by CType have several advantages over raw PowerShell mechanisms
    such as hashtables and PSObjects:
    (1) CTypes can be used to create type-safe parameter declarations. If one function
        in your module returns objects of a CType, another function can declare a parameter
        which will only accept instances of the CType.
    (2) CTypes can be used in [OutputType([typename])] declarations for your functions
        which return them. This enables PowerShell (especially PowerShell ISE) to provide
        enhanced IntelliSense to help your user-scripters anticipate the available properties.
    (3) If you specify the -width parameter for any of your properties, CType will
        automatically configure table formatting for your CType.

    CType can also be used to create wrapper classes for SQL rows (System.Data.DataRow).
    These wrapper classes have all the above advantages plus the following:
    (4) Property value System.DBNull is automatically converted to $null so that it is
        boolean-false in scripting. This will help your users who may not be expecting that
        "if ($mydata.ThisPropertyIsDBNull)" will evaluate to $true and execute the if-block.
    (5) All properties are read-only for SQL wrapper classes.
    (6) CType wrapper classes hide unneeded members of the SQL base object, such as
        property Item[index] and methods AcceptChanges(), EndEdit() etc.

    CTypes only exist inside PowerShell runspaces where they are created,
    and disappear when the runspace exits. They do not in any way modify
    your Windows, .NET, or application binaries.

    CTypes can even be dynamic, meaning that the definition is created on-the-fly
    as your module loads or your script executes. The definition can contain
    PowerShell structures such as if, foreach etc, like any ScriptBlock. See the example below.

    You should call CType exactly once for each type, generally when your module is loaded.
    Only one .NET type (including CType) can exist with any given name.
    Once a CType has been defined with a particular name, you cannot change its definition
    other than by exiting the runspace and creating a new runspace.

    When choosing the name for your CType, you must specify a namespace which assures that
    your CType's full name (which includes the namespace) will not conflict with the full name
    of any .NET type defined by anyone else.
    Honor the guidelines specified in MSDN under "Names of Namespaces"!
    If you get this wrong:
    -- your CType may not load if conflicting .NET assemblies are already loaded; and/or
    -- your CType may block conflicting .NET assemblies from loading subsequently.

    The CType module has several functions besides "function CType":
    -- ConvertTo-CTypeSqlWrapper wraps a SQL DataRow instance into a CType you created
       using the SqlWrapper option.
    -- Add-CType offers an alternate syntax to create types. It does the exact same thing
       as "function CType", you can choose which syntax you prefer.
    -- ConvertTo-CTypeDefinition helps you create CType definitions which wrap
       a particular SQL object. You first generate an example SQL object, then run
       ConvertTo-CTypeDefinition, then paste the CType block it emits into your module
       and modify as needed (for example with formatting).
       In general you will use this function to help you write your module.
    -- Get-CTypeFormatPS1XML generates the formatting definition which CType uses to specify
       table formatting. You can use this if you prefer to put the formatting into a
       Format.ps1xml file in your module, rather than have CType add it automatically.
       In general you will use this function to help you write your module.
    -- Update-CTypeFormatData adds a formatting definition to the current PowerShell runspace.
       The definition could come from Get-CTypeFormatPS1XML or from elsewhere.
    -- Test-CTypeIsDefined tests whether you have already defined a particular CType.
    -- Test-CTypeDotNetTypeIsDefined tests whether a particular CType has already been defined,
       whether it is a CType or any other type.
    -- Functions property, sqlproperty, parent, use, ref, SqlWrapper,
       SqlTemplateObject and NoFormatData, are all helpers used in CType definitions.

    The CType module doesn't do anything you couldn't do yourself with Add-Type and
    Update-FormatData -PrependPath. CType saves you the trouble of learning C#
    to write the type definition and Format.ps1xml to write the table formatting.
    If you have more complex needs you may wind up needing to fall back to C#,
    but don't forget that PowerShell can add custom properties and methods to any type
    including CTypes with Add-Member and/or Types.ps1xml (see "Get-Help about_Types.ps1xml").

EXAMPLES
    (1) Here is an example of how to use CType to create a type and use it in your functions:

        CType MyCompany.MyNamespace.MyClassName {
          property string PropertyName1 -width 20 -trim
          if ($true)
          {
            property int PropertyName2  -width 15
          }
          property string PropertyName3 -width *
          property bool PropertyName4
        }

        function New-MyThing
        {
            [CmdletBinding()]
            [OutputType([MyCompany.MyNamespace.MyClassName])]
            param(
                [string]$Value
                )
            return New-Object -TypeName MyCompany.MyNamespace.MyClassName `
                    -Property @{PropertyName3 = $value}
        }

        function Get-MyThing
        {
            [CmdletBinding()]
            param(
                [MyCompany.MyNamespace.MyClassName]$Thing
                )
            $thing.PropertyName3
        }

        $o = New-MyThing -Value 'Value'
        'object default formatting is'
        $o
        'Get-MyThing returns'
        Get-MyThing -Thing $o

    which returns

        object default formatting is

        PropertyName1        PropertyName2   PropertyName3                                                                                                                                                                                                               
        -------------        -------------   -------------                                                                                                                                                                                                               
                             0               Value                                                                                                                                                                                                                       
        Get-MyThing returns
        Value

    Note the following:
    -- You can use the full PowerShell language inside the type definition.
    -- The first '{' in the CType definition must be on the same line,
       unless you use backtick '`'.
    -- Get-MyThing will refuse any parameter not of the type you defined.

    (2) Here is an example of creating and using a SQLWrapper class:

        CType MyCompany.MyNamespace.MyClassName {
          sqlproperty string PropertyName1 -width 20 -trim
          sqlproperty int PropertyName2  -width 15
          property string PropertyName3 -width *
          sqlproperty bool PropertyName4
        }
        $obj = New-Object -TypeName MyCompany.MyNamespace.MyClassName `
                          -ArgumentList $myDataRowObject
        $obj.PropertyName3 = 'SomeString'

        Note that properties 1, 2 and 4 get their values from $myDataRowObject,
        but the value of property 3 is independent and can be set explicitly.


KEYWORDS
    Type, Types, Format, FormatData

SEE ALSO
    Get-Help about_Format.ps1xml
    Get-Help about_Types.ps1xml
    Add-Type
    Update-FormatData
    In MSDN search for "Names of Namespaces"
tools\CType.msi
 

In cases where actual malware is found, the packages are subject to removal. Software sometimes has false positives. Moderators do not necessarily validate the safety of the underlying software, only that a package retrieves software from the official distribution point and/or validate embedded software against official distribution point (where distribution rights allow redistribution).

Chocolatey Pro provides runtime protection from possible malware.

Version Downloads Last Updated Status
CType 1.00.0003 281 Wednesday, March 25, 2015 Approved

This package has no dependencies.

Discussion for the CType Package

Ground Rules:

  • This discussion is only about CType and the CType package. If you have feedback for Chocolatey, please contact the Google Group.
  • This discussion will carry over multiple versions. If you have a comment about a particular version, please note that in your comments.
  • The maintainers of this Chocolatey Package will be notified about new comments that are posted to this Disqus thread, however, it is NOT a guarantee that you will get a response. If you do not hear back from the maintainers after posting a message below, please follow up by using the link on the left side of this page or follow this link to contact maintainers. If you still hear nothing back, please follow the package triage process.
  • Tell us what you love about the package or CType, or tell us what needs improvement.
  • Share your experiences with the package, or extra configuration or gotchas that you've found.
  • If you use a url, the comment will be flagged for moderation until you've been whitelisted. Disqus moderated comments are approved on a weekly schedule if not sooner. It could take between 1-5 days for your comment to show up.
comments powered by Disqus