Discussion:
[p4] Programming with PowerShell
Avi Levin
2008-08-01 16:52:28 UTC
Permalink
I was given a project to script miscellaneous tasks in Perforce using
Powershell 1.0. However, I've never worked with an API or .NET before
(although I can learn if necessary).

I know there is no "unoffical" way to program with Powershell the way
people do with P4Ruby, but I was given wide latitude to program it in
any way I wanted. Customer support recommended command-line parsing, but
my project might require a more oject-oriented path.

1) What is the best interface for programming Perforce through
Powershell, besides fstat parsing? (passing COM objects, scripting
interface, snap-in, etc.)
2) Where would be the best place to learn about programming Perforce
this way, or in a similar fashion? (tinker with P4Ruby, talk to a
specific person, read documentation, etc.)

Thank you so much for your time.
Arithmomaniac
Avi Levin
2008-08-01 19:00:41 UTC
Permalink
I guess, more specifically, should I be using the P4.NET interface, or
should I use the P4COM interface for better tech support?
Thanks,
Avi Levin
Shawn Hladky
2008-08-01 19:15:18 UTC
Permalink
Check out P4.Net
http://p4dotnet.sourceforge.net/index.php/P4.Net_Overview

I haven't done much in Poweshell, but here's an interactive session I did a
while back as a POC. I did have to deploy the strong-named versions of
p4api.dll and p4dn.dll to the GAC to get this to work. There's probably a
way to get them to load locally, but I didn't take the time to figure it
out.


PS C:\> $p4net = [ System.Reflection.Assembly]::Load("p4api,
Version=1.0.0.0<http://0.9.0.0/>,
Culture=neutral, PublicKeyToken=ff968dc1933aba6f,
processorArchitecture=MSIL")
PS C:\> $p4 = $p4net.CreateInstance("P4API.P4Connection")
PS C:\> $p4.Connect()
PS C:\> $r = $p4.Run("info")
PS C:\> $r[0] | Get-Member


TypeName: P4API.P4Record

Name MemberType Definition
---- ---------- ----------
Equals Method System.Boolean Equals(Object obj)
GetHashCode Method System.Int32 GetHashCode()
GetType Method System.Type GetType()
get_ArrayFields Method P4API.ArrayFieldDictionary
get_ArrayFields()
get_Fields Method P4API.FieldDictionary get_Fields()
get_Item Method System.String get_Item(String key)
set_Item Method System.Void set_Item(String key,
String value)
ToString Method System.String ToString()
Item ParameterizedProperty System.String Item(String key)
{get;set;}
ArrayFields Property P4API.ArrayFieldDictionary ArrayFields
{get;}
Fields Property P4API.FieldDictionary Fields {get;}


PS C:\> $r[0].Fields.Keys
serverVersion
clientHost
clientAddress
serverDate
serverRoot
monitor
clientName
serverAddress
userName
password
clientRoot
serverLicense
PS C:\> $r[0]["serverVersion"]
P4D/NTX86/2005.2/94595 (2006/03/05)
PS C:\> $r[0]["serverRoot"]
G:\p4\Perforce_Live\p4root
PS C:\> $client = $p4.Fetch_Form("client")
PS C:\> $client | Get-Member


TypeName: P4API.P4Form

Name MemberType Definition
---- ---------- ----------
Clone Method P4API.P4Form Clone()
Equals Method System.Boolean Equals(Object obj)
FormatSpec Method System.String FormatSpec()
GetHashCode Method System.Int32 GetHashCode()
GetType Method System.Type GetType()
get_ArrayFields Method P4API.ArrayFieldDictionary
get_ArrayFields()
get_Fields Method P4API.FieldDictionary get_Fields()
get_FormCommand Method System.String get_FormCommand()
get_Item Method System.String get_Item(String key)
get_PermittedFields Method
System.Collections.Specialized.StringCollection get_PermittedFields()
set_Item Method System.Void set_Item(String key,
String value)
ToString Method System.String ToString()
Item ParameterizedProperty System.String Item(String key)
{get;set;}
ArrayFields Property P4API.ArrayFieldDictionary
ArrayFields {get;}
Fields Property P4API.FieldDictionary Fields
{get;}
FormCommand Property System.String FormCommand {get;}
PermittedFields Property
System.Collections.Specialized.StringCollection PermittedFields {get;}


PS C:\> $client["Description"]
Created by shawnh.


PS C:\> $client["Description"] = "Update from psh"
PS C:\> $p4.Save_Form($client)
Client shawnh_dev saved.
PS C:\> $p4.Disconnect()
PS C:\>


On Fri, Aug 1, 2008 at 10:52 AM, Avi Levin <***@zfirmllc.com> wrote:

> I was given a project to script miscellaneous tasks in Perforce using
> Powershell 1.0. However, I've never worked with an API or .NET before
> (although I can learn if necessary).
>
> I know there is no "unoffical" way to program with Powershell the way
> people do with P4Ruby, but I was given wide latitude to program it in
> any way I wanted. Customer support recommended command-line parsing, but
> my project might require a more oject-oriented path.
>
> 1) What is the best interface for programming Perforce through
> Powershell, besides fstat parsing? (passing COM objects, scripting
> interface, snap-in, etc.)
> 2) Where would be the best place to learn about programming Perforce
> this way, or in a similar fashion? (tinker with P4Ruby, talk to a
> specific person, read documentation, etc.)
>
> Thank you so much for your time.
> Arithmomaniac
> _______________________________________________
> perforce-user mailing list - perforce-***@perforce.com
> http://maillist.perforce.com/mailman/listinfo/perforce-user
>
i***@gmail.com
2008-08-02 07:05:16 UTC
Permalink
I implemented all our scripts using Powershell y did it without P4.NET as I
thought it was overkill ... oh well big mistake, today if I had the time I
would recode everything to either Python or C# with P4.NET. Anyhow, P4.NET
is the way to go with Powershell.

Ildefonzo

On Fri, Aug 1, 2008 at 10:52 AM, Avi Levin <***@zfirmllc.com> wrote:

> I was given a project to script miscellaneous tasks in Perforce using
> Powershell 1.0. However, I've never worked with an API or .NET before
> (although I can learn if necessary).
>
> I know there is no "unoffical" way to program with Powershell the way
> people do with P4Ruby, but I was given wide latitude to program it in
> any way I wanted. Customer support recommended command-line parsing, but
> my project might require a more oject-oriented path.
>
> 1) What is the best interface for programming Perforce through
> Powershell, besides fstat parsing? (passing COM objects, scripting
> interface, snap-in, etc.)
> 2) Where would be the best place to learn about programming Perforce
> this way, or in a similar fashion? (tinker with P4Ruby, talk to a
> specific person, read documentation, etc.)
>
> Thank you so much for your time.
> Arithmomaniac
> _______________________________________________
> perforce-user mailing list - perforce-***@perforce.com
> http://maillist.perforce.com/mailman/listinfo/perforce-user
>


__________ Information from ESET Smart Security, version of virus signature
database 3318 (20080801) __________

The message was checked by ESET Smart Security.

http://www.eset.com
Avi Levin
2008-08-01 19:21:22 UTC
Permalink
Thanks. I'm still learning Powershell, so I can't follow the code yet.
But it certainly looks good.
Avi
Philip Kania
2008-08-04 19:26:47 UTC
Permalink
In addition to P4.NET you can use the P4Report ODBC data source from within
PowerShell.
For example:

$builder = new-object System.Data.Odbc.OdbcConnectionStringBuilder
$builder.Dsn = 'Perforce'
$connection = New-Object System.Data.Odbc.OdbcConnection
$builder.connectionstring
$command = New-Object System.Data.Odbc.OdbcCommand "select * from users"
$command.connection = $connection
$connection.open()
$reader = $command.executereader()
while ($reader.Read()) { $reader.Item(0) }
$connection.close()

I've also written a simple PowerShell Provider SnapIn for Perforce. It
presents connections as PSDrives and you are able to navigate things like
users and groups as folders. You cannot currently update Perforce items
through this interface. The Provider uses P4.NET without requiring P4.NET to
be installed in the GAC. I was planning to make this Provider available in
the Public Depot at some point. If you are interested I can do that sooner
rather than later.

Philip Kania

-----Original Message-----

Date: Fri, 1 Aug 2008 13:15:18 -0600
From: "Shawn Hladky" <***@gmail.com>
Subject: Re: [p4] Programming with PowerShell
To: "Avi Levin" <***@zfirmllc.com>
Cc: perforce-***@perforce.com
Message-ID:
<***@mail.gmail.com>
Content-Type: text/plain; charset=ISO-8859-1

Check out P4.Net
http://p4dotnet.sourceforge.net/index.php/P4.Net_Overview

I haven't done much in Poweshell, but here's an interactive session I did a
while back as a POC. I did have to deploy the strong-named versions of
p4api.dll and p4dn.dll to the GAC to get this to work. There's probably a
way to get them to load locally, but I didn't take the time to figure it
out.


PS C:\> $p4net = [ System.Reflection.Assembly]::Load("p4api,
Version=1.0.0.0<http://0.9.0.0/>,
Culture=neutral, PublicKeyToken=ff968dc1933aba6f,
processorArchitecture=MSIL")
PS C:\> $p4 = $p4net.CreateInstance("P4API.P4Connection")
PS C:\> $p4.Connect()
PS C:\> $r = $p4.Run("info")
PS C:\> $r[0] | Get-Member


TypeName: P4API.P4Record

Name MemberType Definition
---- ---------- ----------
Equals Method System.Boolean Equals(Object obj)
GetHashCode Method System.Int32 GetHashCode()
GetType Method System.Type GetType()
get_ArrayFields Method P4API.ArrayFieldDictionary
get_ArrayFields()
get_Fields Method P4API.FieldDictionary get_Fields()
get_Item Method System.String get_Item(String key)
set_Item Method System.Void set_Item(String key,
String value)
ToString Method System.String ToString()
Item ParameterizedProperty System.String Item(String key)
{get;set;}
ArrayFields Property P4API.ArrayFieldDictionary ArrayFields
{get;}
Fields Property P4API.FieldDictionary Fields {get;}


PS C:\> $r[0].Fields.Keys
serverVersion
clientHost
clientAddress
serverDate
serverRoot
monitor
clientName
serverAddress
userName
password
clientRoot
serverLicense
PS C:\> $r[0]["serverVersion"]
P4D/NTX86/2005.2/94595 (2006/03/05)
PS C:\> $r[0]["serverRoot"]
G:\p4\Perforce_Live\p4root
PS C:\> $client = $p4.Fetch_Form("client")
PS C:\> $client | Get-Member


TypeName: P4API.P4Form

Name MemberType Definition
---- ---------- ----------
Clone Method P4API.P4Form Clone()
Equals Method System.Boolean Equals(Object obj)
FormatSpec Method System.String FormatSpec()
GetHashCode Method System.Int32 GetHashCode()
GetType Method System.Type GetType()
get_ArrayFields Method P4API.ArrayFieldDictionary
get_ArrayFields()
get_Fields Method P4API.FieldDictionary get_Fields()
get_FormCommand Method System.String get_FormCommand()
get_Item Method System.String get_Item(String key)
get_PermittedFields Method
System.Collections.Specialized.StringCollection get_PermittedFields()
set_Item Method System.Void set_Item(String key,
String value)
ToString Method System.String ToString()
Item ParameterizedProperty System.String Item(String key)
{get;set;}
ArrayFields Property P4API.ArrayFieldDictionary
ArrayFields {get;}
Fields Property P4API.FieldDictionary Fields
{get;}
FormCommand Property System.String FormCommand {get;}
PermittedFields Property
System.Collections.Specialized.StringCollection PermittedFields {get;}


PS C:\> $client["Description"]
Created by shawnh.


PS C:\> $client["Description"] = "Update from psh"
PS C:\> $p4.Save_Form($client)
Client shawnh_dev saved.
PS C:\> $p4.Disconnect()
PS C:\>


On Fri, Aug 1, 2008 at 10:52 AM, Avi Levin <***@zfirmllc.com> wrote:
I was given a project to script miscellaneous tasks in Perforce using
Powershell 1.0. However, I've never worked with an API or .NET before
(although I can learn if necessary).

I know there is no "unoffical" way to program with Powershell the way
people do with P4Ruby, but I was given wide latitude to program it in
any way I wanted. Customer support recommended command-line parsing, but
my project might require a more oject-oriented path.

1) What is the best interface for programming Perforce through
Powershell, besides fstat parsing? (passing COM objects, scripting
interface, snap-in, etc.)
2) Where would be the best place to learn about programming Perforce
this way, or in a similar fashion? (tinker with P4Ruby, talk to a
specific person, read documentation, etc.)

Thank you so much for your time.
Arithmomaniac
_______________________________________________
Avi Levin
2008-08-05 21:38:14 UTC
Permalink
Thanks a lot! P4.NET is fantastic.
I'm trying to make a collection of objects with the description of
"Product A". When I run
$r = $p4.Run("changes", "-L", "-s", "pending") , I get a P4Record Set.
Can I convert that straight into an object where the fields are
properties for the object, like

change desc
12345 Product A
12346 Product B

Which I could run | while on more easily?
Thanks,
Avi Levin
Philip Kania
2008-08-06 15:57:09 UTC
Permalink
You can use a function like:

function RecordSetToObject ($recordSet) {
$o = New-Object System.Management.Automation.PSObject
foreach ($key in $record.Fields.Keys) {
$n = New-Object System.Management.Automation.PSNoteProperty
$key,$record[$key]
$o.psobject.members.add($n)
}
$o
}

Then use:

$r.Records | %{ RecordSetToObject($_) }


Philip Kania

-----Original Message-----
From: perforce-user-***@perforce.com
[mailto:perforce-user-***@perforce.com] On Behalf Of Avi Levin
Sent: Tuesday, August 05, 2008 5:38 PM
To: perforce-***@perforce.com
Subject: [p4] Programming with PowerShell

Thanks a lot! P4.NET is fantastic.
I'm trying to make a collection of objects with the description of
"Product A". When I run
$r = $p4.Run("changes", "-L", "-s", "pending") , I get a P4Record Set.
Can I convert that straight into an object where the fields are
properties for the object, like

change desc
12345 Product A
12346 Product B

Which I could run | while on more easily?
Thanks,
Avi Levin
_______________________________________________
perforce-user mailing list - perforce-***@perforce.com
http://maillist.perforce.com/mailman/listinfo/perforce-user
Avi Levin
2008-08-06 16:12:29 UTC
Permalink
I'm not sure I would use the provider (I need to update items), but
wouldn't posting it now open it up to more feedback?
Thanks,
Avi Levin

Philip Kania wrote:
> With my Provider I can do this:
>
> sl p4:\changes
> gci | ?{$_.Status -eq "pending"} | select Description
>
> which of course is the same as:
>
> cd p4:\changes
> dir | ?{$_.Status -eq "pending"} | select Description
>
> Philip Kania
>
> -----Original Message-----
> From: perforce-user-***@perforce.com
> [mailto:perforce-user-***@perforce.com] On Behalf Of Avi Levin
> Sent: Tuesday, August 05, 2008 5:38 PM
> To: perforce-***@perforce.com
> Subject: [p4] Programming with PowerShell
>
> Thanks a lot! P4.NET is fantastic.
> I'm trying to make a collection of objects with the description of
> "Product A". When I run
> $r = $p4.Run("changes", "-L", "-s", "pending") , I get a P4Record Set.
> Can I convert that straight into an object where the fields are
> properties for the object, like
>
> change desc
> 12345 Product A
> 12346 Product B
>
> Which I could run | while on more easily?
> Thanks,
> Avi Levin
> _______________________________________________
> perforce-user mailing list - perforce-***@perforce.com
> http://maillist.perforce.com/mailman/listinfo/perforce-user
>
>
Philip Kania
2008-08-06 16:51:45 UTC
Permalink
I'll try to get it posted this week. Feedback would be great.

Philip Kania


-----Original Message-----
From: Avi Levin [mailto:***@zfirmllc.com]
Sent: Wednesday, August 06, 2008 12:12 PM
To: Philip Kania; perforce-***@perforce.com
Subject: Re: [p4] Programming with PowerShell

I'm not sure I would use the provider (I need to update items), but
wouldn't posting it now open it up to more feedback?
Thanks,
Avi Levin

Philip Kania wrote:
> With my Provider I can do this:
>
> sl p4:\changes
> gci | ?{$_.Status -eq "pending"} | select Description
>
> which of course is the same as:
>
> cd p4:\changes
> dir | ?{$_.Status -eq "pending"} | select Description
>
> Philip Kania
>
> -----Original Message-----
> From: perforce-user-***@perforce.com
> [mailto:perforce-user-***@perforce.com] On Behalf Of Avi Levin
> Sent: Tuesday, August 05, 2008 5:38 PM
> To: perforce-***@perforce.com
> Subject: [p4] Programming with PowerShell
>
> Thanks a lot! P4.NET is fantastic.
> I'm trying to make a collection of objects with the description of
> "Product A". When I run
> $r = $p4.Run("changes", "-L", "-s", "pending") , I get a P4Record Set.
> Can I convert that straight into an object where the fields are
> properties for the object, like
>
> change desc
> 12345 Product A
> 12346 Product B
>
> Which I could run | while on more easily?
> Thanks,
> Avi Levin
> _______________________________________________
> perforce-user mailing list - perforce-***@perforce.com
> http://maillist.perforce.com/mailman/listinfo/perforce-user
>
>
Loading...