I know that Powershell can call .NET code, which might look like this
PS> [Reflection.Assembly]::LoadFile(($ScriptDir + ".\SharpSvn-x64\SharpSvn.dll"))
PS> $SvnClient = New-Object SharpSvn.SvnClient
And I know that where C# has out
arguments, Powershell has [ref]
arguments, which might look like this:
PS> $info = $null
PS> $SvnClient.GetInfo($repo.local, ([ref]$info))
True
PS> $info
(...long output snipped...)
NodeKind : Directory
Revision : 16298
Uri : http://server/path/to/remoterepo
FullPath : C:\path\to\localrepo
(...long output snipped...)
And I know that in C# you can overload functions, like the SharpSvn library does for its SvnClient.Update() method:
Update(ICollection(String))
- Recursively updates the specified paths to the latest (HEAD) revisionUpdate(String)
- Recursively updates the specified path to the latest (HEAD) revisionUpdate(ICollection(String), SvnUpdateArgs)
- Updates the specified paths to the specified revisionUpdate(ICollection(String), SvnUpdateResult)
- Recursively updates the specified paths to the latest (HEAD) revisionUpdate(String, SvnUpdateArgs)
- Recursively updates the specified pathUpdate(String, SvnUpdateResult)
- Recursively updates the specified path to the latest (HEAD) revisionUpdate(ICollection(String), SvnUpdateArgs, SvnUpdateResult)
- Updates the specified paths to the specified revisionUpdate(String, SvnUpdateArgs, SvnUpdateResult)
- Recursively updates the specified path to the latest (HEAD) revisionBut, what if we want to put all of this together? If, say, I want to call the 6th version of Update()
, the one that takes a String and an SvnUpdateResult, where the SvnUpdateResult is a C# out object? My first instinct was to try something like this:
PS> $repopath = "C:\path\to\localrepo"
PS> $update = $null
PS> $svnclient.update($repopath, [ref]$update)
Multiple ambiguous overloads found for "Update" and the argument count: "2".
At line:1 char:18
+ $svnclient.update <<<< ($repopath, [ref]$update)
+ CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MethodCountCouldNotFindBest
OK, maybe I have to cast the arguments?
PS> $svnclient.update([string]$repopath, [ref][SharpSvn.SvnUpdateResult]$update)
Multiple ambiguous overloads found for "Update" and the argument count: "2".
At line:1 char:18
+ $svnclient.update <<<< ([string]$repopath, [ref][SharpSvn.SvnUpdateResult]$update)
+ CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MethodCountCouldNotFindBest
But that doesn't seem to work either. Other things I've tried:
$update
as [SharpSvn.SvnUpdateResult][ref]
- that is, reversing the order that I cast it. That results in an error which states: "[ref] can only be the final type in type conversion sequence."$update
to SharpSvn.SvnUpdateResult
before using it: $update = [SharpSvn.SvnUpdateResult]$null
. This results in the same "Multiple ambiguous overloads" error I ran into above$update
to ref
before using it: $update = [ref]$null
. This results in an error: 'Cannot convert the "System.Management.Automation.PSReference" value of type "System.Management.Automation.PSReference" to type "SharpSvn.SvnUpdateResult".'It seems like casting it twice is the problem - the final cast just overrides the first cast, they don't complement each other. Is this what's happening? Is there a way to cast something twice? Is there another way around this problem?
Thanks in advance for any help.
This might not be an ideal solution but you could use Add-Type and make a more PowerShell friendly type that wraps the Update method.
Add-Type -TypeDefinition "
public class SvnClientEx
{
public static SvnUpdateResult Update(SvnClient client, string path)
{
SvnUpdateResult result;
client.Update(path, out result);
return result;
}
}
"
$result = [SvnClient]::Update($svnClient, $repopath)
This does seem to be quite hard to get right.
What version of PowerShell is this?
Are SvnUpdateArgs
and SvnUpdateResult
related (i.e. one class derives from the other)? I shall assume not.
Based on a similar scenario I constructed, with the current version (4.0) of PowerShell, this works, I think:
PS> $repopath = "C:\path\to\localrepo"
PS> [SharpSvn.SvnUpdateResult]$update = $null
PS> $svnclient.Update([string]$repopath, [ref]$update)
However, I could only get this to work with one of the overloads!? Not sure if it is by coincidence, but this was the overload which was listed first when I said $svnclient.Update
to see the overload definitions.
In my version of PowerShell, if I give the second argument as [ref][SharpSvn.SvnUpdateResult]$update
, the overload seems to be resolved correctly, the method runs without error, but the object assigned to the "out" parameter seems to be lost.
Even if $repopath
is declared type-safely as [string]$repopath = "C:\path\to\localrepo"
, it seems that we still have to say [string]$repopath
again when we pass it (by value).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With