Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Current directory from a DLL invoked from Powershell wrong

Tags:

c#

powershell

dll

I have a DLL with a static method which would like to know the current directory. I load the library

c:\temp> add-type -path "..."

...and call the method

c:\temp> [MyNamespace.MyClass]::MyMethod()

but both Directory.GetCurrentDirectory() and .Environment.CurrentDirectory get the current directory wrong...

what is the correct way to do this?

like image 204
ekkis Avatar asked Sep 18 '25 13:09

ekkis


2 Answers

There are two possible "directories" you can have in powershell. One is the current directory of the process, available via Environment.CurrentDirectory or Directory.GetCurrentDirectory(). The other "directory" is the current location in the current Powershell Provider. This is what you see at the command line and is available via the get-location cmdlet. When you use set-location (alias cd) you are changing this internal path, not the process's current directory.

If you want some .NET library that uses the process's current directory to get the current location then you need to set it explicitly:

[Environment]::CurrentDirectory = get-location

Powershell has an extensible model allowing varying data sources to be mounted like drives in a file system. The File System is just one of many providers. You can see the other providers via get-psprovider. For example, the Registry provider allows the Windows Registry to be navigated like a file system. Another "Function" lets you see all functions via dir function:.

like image 135
Mike Zboray Avatar answered Sep 21 '25 02:09

Mike Zboray


If the command in your DLL inherits from System.Management.Automation.PSCmdLet, the current PS location is available in SessionState.Path.

public class SomeCommand : PSCmdlet
{
    protected override void BeginProcessing()
    {
      string currentDir = this.SessionState.Path.CurrentLocation.Path;
    }
}

To get to the path without a session reference, this code seems to work. This solution I found after going through code that makes GIT autocomplete in PS GIT Completions, specifically this function here.

public class Test
{
  public static IEnumerable<string> GetPath()
  {
    using (var ps = PowerShell.Create(RunspaceMode.CurrentRunspace))
    {
      ps.AddScript("pwd");
      var path = ps.Invoke<PathInfo>();
      return path.Select(p => p.Path);
    }
  }
}

Output:

PS C:\some\folder> [Test]::GetPath()
C:\some\folder
like image 25
Willem Avatar answered Sep 21 '25 03:09

Willem