Bagikan melalui


Minding Path Inputs in a Cmdlet

When I was a Monad neophyte, I was asked to write a Cmdlet taking a file path as a parameter. A big mistake I made was not keeping in mind that in Monad the FileSystem provider was just one of the many providers. (This makes Monad different from many other shells where you are always in a directory.) For a path-taking Cmdlet, this means two things. The first is that the input path can be specifying a non-FileSystem provider such as the registry provider. The second is that the Cmdlet can be invoked from a non-FileSystem provider. This makes a relative input path not relative to the FileSystem provider. Besides the provider issues, a path in Monad can also be drive-qualified or home-relative. Also, a drive can be mounted at a location that is not the root of the file system.

To deal with all these conditions, the Cmdlet needs to call SessionState.Path.GetResolvedProviderPathFromMshPath and checks the provider returned . If the path does not exist, SessionState.Path.GetUnresolvedProviderPathFromMshPath is used. However, as of Beta 3, this API does not return the provider. We are looking to add a version that does return the provider in V1. As usual, we can't promise this will happen.

In future versions, we hope to provide enough functionalities so that Cmdlets that writes to a path can use InvokeProvider.Content.GetWriter(path). This enables the Cmdlet to write to any provider that implements the IContentCmdletProvider interface. Moreover, the Cmdlet does not need to worry about what provider a path specifies. Again, we can't promise this will happen.

--
Kevin Loo [MSFT]
Microsoft Command Shell Development
Microsoft Corporation
This posting is provided "AS IS" with no warranties, and confers no rights.

Comments

  • Anonymous
    January 30, 2006
    After reading this posting, I found out all of my cmdlets that write to files would fail when invoked from anywhere outside of the file system provider. Now, I need to go back and fix them.
    Thanks for bringing this up.
  • Anonymous
    February 01, 2006
    I notice you didn't say anything about the MshPath attribute; this seems to me to be the preferable way of doing things...

    Also, how should we handle writing binary files? We can't really get a stream to write to, can we? Do we just have to go through the System.IO namespace?

    Nick
  • Anonymous
    February 01, 2006
    The comment has been removed
  • Anonymous
    February 02, 2006
    I can't seem to get set-content to work with binary data, or maybe it's get-content.

    For example, if I have a binary file "test.doc" and I want to copy it to test2.doc:

    new-item test2.doc -t file; get-content test.doc | set-content test2.doc;

    test2.doc is not a valid Word file, even though test.doc is. What should I be doing here?

    Thanks for the responsiveness!

    Nick
  • Anonymous
    February 02, 2006
    Thanks for the advice! I've switched all my cmdlets to take strings and run them through the resolution methods.

    As far as binary content, I can't seem to get set-content to work (or maybe it's get-content):

    get-content test.doc | set-content test2.doc

    Word says that test2.doc is not a valid Word file after doing this, but test.doc is. Am I doing something wrong?

    Nick
  • Anonymous
    February 06, 2006
    Try using the -encoding parameter for set-content.  It can take a value of "byte".

    Jeff Jones
    Technical Lead
    Monad Development
    Microsoft Corporation
    This posting is provided "AS IS" with no warranties, and confers no rights.
  • Anonymous
    February 07, 2006
    That worked; thanks a lot!

    Another question: would it be possible to factor the encoding functionality into something public? It seems that it would apply to more providers than just FS (for example, I use an Encoding parameter on get-uri, a wget analog).

    Thanks again,
    Nick