Powershell Cmdlet:确定本地目录中文件的实际文件路径

本文关键字:文件 中文 路径 Cmdlet Powershell | 更新日期: 2023-09-27 18:29:23

我有一个自定义cmdlet,可以这样调用:

Get-Info ".'somefile.txt"

我的commandlet代码看起来像这样:

[Parameter(Mandatory = true, Position = 0)]
public string FilePath { get; set; }
protected override void ProcessRecord()
{
    using (var stream = File.Open(FilePath))
    {
        // Do work
    }
}

然而,当我运行该命令时,我会得到以下错误:

Could not find file 'C:'Users'Philip'somefile.txt'

我没有从C:'Users'Philip执行此cmdlet。由于某些原因,我的cmdlet无法检测到工作目录,因此像这样的本地文件无法工作。在C#中,当提供本地".''"文件路径时,建议使用什么方法来检测正确的文件路径?

Powershell Cmdlet:确定本地目录中文件的实际文件路径

查看SessionState属性的Path属性。它有一些常用于解析相对路径的实用函数。根据您是否要支持通配符,选项会有所不同。这个论坛帖子可能有用。

现在我使用GetUnresolvedProviderPathFromPsPath。然而,在这个stackoverflow问题的帮助下,我可以根据微软的指导方针来设计我的cmdlet,这正是我想要的。那里的答案非常全面。我不想删除这个问题,但我投票决定关闭它,因为这个问题完全重复,而且那里的答案更好。

您尝试过吗:

File.Open(Path.GetFullPath(FilePath))

您应该能够使用以下内容

var currentDirectory = ((PathInfo)GetVariableValue("pwd")).Path;

如果从PSCmdlet而不是Cmdlet继承。源

或者,类似于:

this.SessionState.Path

可能会起作用。

    /// <summary>
    /// The member variable m_fname is populated by input parameter
    /// and accepts either absolute or relative path.
    /// This method will determine if the supplied parameter was fully qualified, 
    /// and if not then qualify it.
    /// </summary>
    protected override void InternalProcessRecord()
    {
        base.InternalProcessRecord();
        string fname = null;
        if (Path.IsPathRooted(m_fname))
            fname = m_fname;
        else
            fname = Path.Combine(this.SessionState.Path.CurrentLocation.ToString(), m_fname);
        // If the file doesn't exist
        if (!File.Exists(fname))
            throw new FileNotFoundException("File does not exist.", fname);
    }

这就是我解决相对路径的方法,我认为它是独立于平台的。

using System.Management.Automation;
namespace ProofOfConcept {
    [Cmdlet(VerbsDiagnostic.Test, "PathNormalization")]
    [OutputType(typeof(string))]
    public class TestPathNormalization : PSCmdlet {
        private string pathParameter = String.Empty;
        [Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true)]
        public String Path {
            get { return this.pathParameter; }
            set { this.pathParameter = value; }
        }
        protected override void ProcessRecord() {
            base.ProcessRecord();
            WriteDebug(this.pathParameter);
            string normalizedPath = this.SessionState.Path.NormalizeRelativePath(this.pathParameter, String.Empty);
            WriteDebug(normalizedPath);
            WriteObject(normalizedPath);
        }
    }
}