- January 11, 2016 at 4:35 am #33691
I have created a C# project in Visual Studio and I am looking at the best way to access this in PowerShell.
I created the project to produce a dll. I can access this fine in visual studio by running:
test.Class1.find("username", "password", "type", "id")
but when I import the dll in PowerShell I don't have access to the find to run the command.
Do I have to change the visual studio project to allow PowerShell access?
Would it be better to write a PowerShell module?
PaulJanuary 11, 2016 at 5:13 am #33692
Hi Paul! Without looking at the code, I assume that the problem may be with access modifiers for your class. In C# if you don't explicitly define your top class to be public, it is created with internal scope. If it is defined as public, maybe the method is not.
If that doesn't help, please paste an sample of your code and I'll take a closer look.
IvanJanuary 11, 2016 at 5:44 am #33693
Many thanks for your reply.
Im new to c# so this could be completely wrong but my code has been set out like this:
public class Class1
public static void find(string username, string password, string type, string id)
//Code here which finished by producing a string.
Many thanks for your help.
PaulJanuary 11, 2016 at 5:51 am #33694
Looks fine to me. Once you've loaded up your DLL (with Add-Type -Path c:\your\dllfile.dll), you should be able to do: [test.Class1]::find($username, $password, $type, $id)January 11, 2016 at 8:52 am #33713
Perfect! I was trying to call the find incorrectly.
One last question – the c# code ends with a Console.WriteLine which appears on screen in PowerShell. is there a way to capture this in PowerShell value? I tried
$test = [test.Class1]::find($username, $password, $type, $id) but this didn't work.January 11, 2016 at 8:54 am #33714
Not really. Console.WriteLine() is kind of like C#'s version of Write-Host. It writes to the console, and doesn't provide data in any sort of return value or parameter that the code can inspect later. (This also may cause a problem if your DLL were ever to be used in a non-console application, such as the PowerShell ISE.)January 11, 2016 at 9:14 am #33717
Yeah, I agree with Dave. You'll have to call it as [test.Class1]::find("username", "password", "type", "id") because that's how static members of classes are invoked in PowerShell.
If you had some non-static methods, you would have to instantiate an object of Class1 type as follows:
$MyObject = New-Object -Type test.Class1
And then you be able to access those methods like that:
Hope that helps.
IvanJanuary 11, 2016 at 9:14 am #33718
ok. No way of changing the c# to enable this?
One option would be to get the c# to output the result to a file and PowerShell to read the file but I would prefer not to do it this way if possible.
Would it be possible to write a custom PowerShell module to do this?January 11, 2016 at 9:20 am #33719
Paul, can you can update your method to return string instead of a void? PowerShell is object oriented, so if you're doing some crazy property value concatenation within your C# code to produce a string just to be able to pass it over to PowerShell, you may want to pass that initial object instead.January 11, 2016 at 9:45 am #33721
Perfect. Thanks Ivan and Dave – it's now working exactly like I need it to 🙂January 11, 2016 at 10:35 am #33727
ok so 1 more question!
my c# code authenticates to a cookiecontainer and then users this to perform other actions.
Is it possible to pass the cookiecontainer to PowerShell and then PowerShell pass this back to different functions in the dll?January 11, 2016 at 10:43 am #33729
That should work fine, as long as that different function will be available to PowerShell (i.e. public)January 11, 2016 at 10:50 am #33730
ok so I could just return the cookie container in c# and capture it in PowerShell like:
$test = [test.Class1]::auth($username, $password, $type, $id)
I can then user $test to pass back the cookie?January 11, 2016 at 11:10 am #33732
_Can_ you do that? Sure. But now you're getting into questions of class design, where it's more about coding style (object oriented vs functional, etc), making a pleasant API, etc. In C#, I would probably lean away from having one class function return a cookie container, then require a caller to pass that container right back in as a parameter to another method.
Instead, I'd probably use non-static methods, and have each instance of the object keep track of the cookie container via a field and/or property. It may not even be necessary to have that field be public, if your class already covers all the uses of the container.
You must be logged in to reply to this topic.