dll to PowerShell

Tagged: ,

This topic contains 13 replies, has 3 voices, and was last updated by Profile photo of Dave Wyatt Dave Wyatt 8 months, 2 weeks ago.

Viewing 14 posts - 1 through 14 (of 14 total)
  • Author
    Posts
  • #33691
    Profile photo of Paul Smith
    Paul Smith
    Participant

    Hi

    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?

    Many thanks
    Paul

    #33692
    Profile photo of Ivan Seriavin
    Ivan Seriavin
    Participant

    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.

    Thanks,
    Ivan

    #33693
    Profile photo of Paul Smith
    Paul Smith
    Participant

    Hi Ivan

    Many thanks for your reply.

    Im new to c# so this could be completely wrong but my code has been set out like this:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Net;
    using System.IO;

    namespace test
    {
    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.

    Paul

    #33694
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    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)

    #33713
    Profile photo of Paul Smith
    Paul Smith
    Participant

    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.

    #33714
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    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.)

    #33717
    Profile photo of Ivan Seriavin
    Ivan Seriavin
    Participant

    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:

    $myObject.(Args)

    .
    Hope that helps.

    Thanks,
    Ivan

    #33718
    Profile photo of Paul Smith
    Paul Smith
    Participant

    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?

    #33719
    Profile photo of Ivan Seriavin
    Ivan Seriavin
    Participant

    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.

    #33721
    Profile photo of Paul Smith
    Paul Smith
    Participant

    Perfect. Thanks Ivan and Dave – it's now working exactly like I need it to 🙂

    #33727
    Profile photo of Paul Smith
    Paul Smith
    Participant

    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?

    #33729
    Profile photo of Ivan Seriavin
    Ivan Seriavin
    Participant

    That should work fine, as long as that different function will be available to PowerShell (i.e. public)

    #33730
    Profile photo of Paul Smith
    Paul Smith
    Participant

    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?

    #33732
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    _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.

Viewing 14 posts - 1 through 14 (of 14 total)

You must be logged in to reply to this topic.