Merge pull request #943 from PowerShell/andschwa/cmdlet-example
Add cmdlet example project with readme
This commit is contained in:
commit
88c3d56162
7
docs/cmdlet-example/NuGet.config
Normal file
7
docs/cmdlet-example/NuGet.config
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
<packageSources>
|
||||||
|
<add key="CI Builds (dotnet-core)" value="https://www.myget.org/F/dotnet-core/api/v3/index.json" />
|
||||||
|
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
|
||||||
|
</packageSources>
|
||||||
|
</configuration>
|
129
docs/cmdlet-example/README.md
Normal file
129
docs/cmdlet-example/README.md
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
Building a C# Cmdlet
|
||||||
|
====================
|
||||||
|
|
||||||
|
This example project demonstrates how to build your own C# cmdlet for
|
||||||
|
PowerShell.
|
||||||
|
|
||||||
|
Setup
|
||||||
|
-----
|
||||||
|
|
||||||
|
We use the [.NET Command Line Interface][dotnet-cli] (`dotnet`) to build the
|
||||||
|
cmdlet library. Install the `dotnet` tool and ensure `dotnet --version` is at
|
||||||
|
least `1.0.0-rc2`.
|
||||||
|
|
||||||
|
.NET CLI uses a `project.json` file for build specifications:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "SendGreeting",
|
||||||
|
"description": "Example C# Cmdlet project",
|
||||||
|
"version": "1.0.0-*",
|
||||||
|
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.PowerShell.5.ReferenceAssemblies": "1.0.0-*"
|
||||||
|
},
|
||||||
|
|
||||||
|
"frameworks": {
|
||||||
|
"netstandard1.5": {
|
||||||
|
"imports": [ "net40" ],
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore": "5.0.1-*",
|
||||||
|
"Microsoft.NETCore.Portable.Compatibility": "1.0.1-*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that no source files are specified. .NET CLI automatically will build all
|
||||||
|
`.cs` files in the project directory.
|
||||||
|
|
||||||
|
Going through this step-by-step:
|
||||||
|
|
||||||
|
- `"name": "SendGreeting"`: Name of the assembly to output (otherwise it
|
||||||
|
defaults to the name of the containing folder).
|
||||||
|
|
||||||
|
- `"version": "1.0.0-*"`: The wild-card can be replaced using the
|
||||||
|
`--version-suffix` flag to `dotnet build`.
|
||||||
|
|
||||||
|
- [Microsoft.PowerShell.5.ReferenceAssemblies][powershell]: Contains the SDK
|
||||||
|
reference assemblies for PowerShell version 5. Targets the `net40` framework.
|
||||||
|
|
||||||
|
- [netstandard1.5][]: The target framework for .NET Core portable libraries.
|
||||||
|
This is an abstract framework that will work anywhere its dependencies work.
|
||||||
|
|
||||||
|
- `"imports": [ "net4" ]`: Since the PowerShell reference assemblies target the
|
||||||
|
older `net40` framework, we `import` it here to tell `dotnet restore` that we
|
||||||
|
know we're loading a possibly-incompatible package.
|
||||||
|
|
||||||
|
- [Microsoft.NETCore][netcore]: Provides a set of packages that can be used when
|
||||||
|
building portable libraries on .NETCore based platforms.
|
||||||
|
|
||||||
|
- [Microsoft.NETCore.Portable.Compatibility][portable]: Enables compatibility
|
||||||
|
with portable libraries targeting previous .NET releases like .NET Framework
|
||||||
|
4.0. Required to build against the PowerShell reference assemblies package.
|
||||||
|
|
||||||
|
Other dependencies can be added as needed; refer to the
|
||||||
|
[.NET Core package gallery][myget] for package availability, name, and version
|
||||||
|
information.
|
||||||
|
|
||||||
|
Because the .NET Core packages are not yet released to NuGet.org, you also need
|
||||||
|
this `NuGet.config` file to setup the [.NET Core MyGet feed][myget]:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
<packageSources>
|
||||||
|
<clear />
|
||||||
|
<add key="CI Builds (dotnet-core)" value="https://www.myget.org/F/dotnet-core/api/v3/index.json" />
|
||||||
|
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
|
||||||
|
</packageSources>
|
||||||
|
</configuration>
|
||||||
|
```
|
||||||
|
|
||||||
|
[dotnet-cli]: https://github.com/dotnet/cli#new-to-net-cli
|
||||||
|
[powershell]: https://www.nuget.org/packages/Microsoft.PowerShell.5.ReferenceAssemblies
|
||||||
|
[netstandard1.5]: https://github.com/dotnet/corefx/blob/master/Documentation/architecture/net-standard-applications.md
|
||||||
|
[netcore]: https://dotnet.myget.org/feed/dotnet-core/package/nuget/Microsoft.NETCore
|
||||||
|
[portable]: https://dotnet.myget.org/feed/dotnet-core/package/nuget/Microsoft.NETCore.Portable.Compatibility
|
||||||
|
[myget]: https://dotnet.myget.org/gallery/dotnet-core
|
||||||
|
|
||||||
|
Building
|
||||||
|
--------
|
||||||
|
|
||||||
|
.NET Core is a package-based platform, so the correct dependencies first need to
|
||||||
|
be resolved:
|
||||||
|
|
||||||
|
```
|
||||||
|
dotnet restore
|
||||||
|
```
|
||||||
|
|
||||||
|
This reads the `project.json` and `NuGet.config` files and uses NuGet to restore
|
||||||
|
the necessary packages. The generated `project.lock.json` lockfile contains the
|
||||||
|
resolved dependency graph.
|
||||||
|
|
||||||
|
Once packages are restored, building is simple:
|
||||||
|
|
||||||
|
```
|
||||||
|
dotnet build
|
||||||
|
```
|
||||||
|
|
||||||
|
This will produce the assembly `./bin/Debug/netstandard1.5/SendGreeting.dll`.
|
||||||
|
|
||||||
|
This build/restore process should work anywhere .NET Core works, including
|
||||||
|
Windows, Linux, and OS X.
|
||||||
|
|
||||||
|
Deployment
|
||||||
|
----------
|
||||||
|
|
||||||
|
In PowerShell, check `$env:PSMODULEPATH` and install the new cmdlet in its own
|
||||||
|
module folder, such as, on Linux,
|
||||||
|
`~/.powershell/Modules/SendGreeting/SendGreeting.dll`.
|
||||||
|
|
||||||
|
Then import and use the module:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
> Import-Module SendGreeting # Module names are case-sensitive on Linux
|
||||||
|
> Send-Greeting -Name World
|
||||||
|
Hello World!
|
||||||
|
```
|
13
docs/cmdlet-example/SendGreeting.Tests.ps1
Normal file
13
docs/cmdlet-example/SendGreeting.Tests.ps1
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
Describe "Send-Greeting cmdlet" {
|
||||||
|
It "Should be able build the cmdlet" {
|
||||||
|
Remove-Item -Recurse -Force bin -ErrorAction SilentlyContinue
|
||||||
|
dotnet restore --verbosity Error | Should BeNullOrEmpty
|
||||||
|
dotnet build | ?{ $_ -match "Compiling SendGreeting for .NETStandard,Version=v1.5" } | Should Not BeNullOrEmpty
|
||||||
|
}
|
||||||
|
|
||||||
|
It "Should be able to use the module" {
|
||||||
|
Import-Module -ErrorAction Stop ./bin/Debug/netstandard1.5/SendGreeting.dll
|
||||||
|
Send-Greeting -Name World | Should Be "Hello World!"
|
||||||
|
Remove-Module SendGreeting
|
||||||
|
}
|
||||||
|
}
|
30
docs/cmdlet-example/SendGreeting.cs
Normal file
30
docs/cmdlet-example/SendGreeting.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Example from https://msdn.microsoft.com/en-us/library/dd901838(v=vs.85).aspx
|
||||||
|
|
||||||
|
using System.Management.Automation; // Windows PowerShell assembly.
|
||||||
|
|
||||||
|
namespace SendGreeting
|
||||||
|
{
|
||||||
|
// Declare the class as a cmdlet and specify and
|
||||||
|
// appropriate verb and noun for the cmdlet name.
|
||||||
|
[Cmdlet(VerbsCommunications.Send, "Greeting")]
|
||||||
|
public class SendGreetingCommand : Cmdlet
|
||||||
|
{
|
||||||
|
// Declare the parameters for the cmdlet.
|
||||||
|
[Parameter(Mandatory=true)]
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return name; }
|
||||||
|
set { name = value; }
|
||||||
|
}
|
||||||
|
private string name;
|
||||||
|
|
||||||
|
// Overide the ProcessRecord method to process
|
||||||
|
// the supplied user name and write out a
|
||||||
|
// greeting to the user by calling the WriteObject
|
||||||
|
// method.
|
||||||
|
protected override void ProcessRecord()
|
||||||
|
{
|
||||||
|
WriteObject("Hello " + name + "!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
docs/cmdlet-example/project.json
Normal file
19
docs/cmdlet-example/project.json
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"name": "SendGreeting",
|
||||||
|
"description": "Example C# Cmdlet project",
|
||||||
|
"version": "1.0.0-*",
|
||||||
|
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.PowerShell.5.ReferenceAssemblies": "1.0.0-*"
|
||||||
|
},
|
||||||
|
|
||||||
|
"frameworks": {
|
||||||
|
"netstandard1.5": {
|
||||||
|
"imports": [ "net40" ],
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore": "5.0.1-*",
|
||||||
|
"Microsoft.NETCore.Portable.Compatibility": "1.0.1-*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6
test/powershell/CmdletExample.Tests.ps1
Normal file
6
test/powershell/CmdletExample.Tests.ps1
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
try {
|
||||||
|
Push-Location $PSScriptRoot/../../docs/cmdlet-example
|
||||||
|
./SendGreeting.Tests.ps1
|
||||||
|
} finally {
|
||||||
|
Pop-Location
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user