Use a .NET Framework Class to Open a File Dialog Box

Use a .NET Framework Class to Open a File Dialog Box

  • Comments 7
  • Likes

Summary: Microsoft PFEs Adam Haynes and Shubert Somer talk about using a .NET Framework class to open a file dialog box.

Microsoft Scripting Guy, Ed Wilson, is here. Today, we have part 5 of 5 guest blogs written by Adam Haynes with help from his friend Shubert Somer. If you have not read parts 1, 2, 3, and 4, you will want to go back and read them before you read today’s blog post.

Take it away, Adam ...

<SCRIPT >

 [reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null
$openFile = New-Object System.Windows.Forms.OpenFileDialog
$openFile.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*"
If($openFile.ShowDialog() -eq "OK"
{get-content $openFile.FileName} 

</SCRIPT >

Image of script

I think Shubert covered line 1, so let’s move on with the rest of the script.

Image of script

On line 3, we have to use the New-Object cmdlet because, as we discussed in a previous post, we have to instantiate the OpenFileDialog Class. If you need to refresh on constructors, see Shubert’s explanation in the part 2 post.

Line 4 is actually copied from the MSDN site. I stumbled across the Filter property when I was browsing the object and used the example provided on MSDN.

Image of script

Line 6 took me a couple of tries since I was not familiar with the object (remember, it is an object because we used the New-Object cmdlet). Once I had the OpenFileDialog object, I just started trying the methods that are listed on MSDN (and Get-Member) to see what they did. The Show Dialog() Method looked promising and, in fact, provided all the information I needed to finish the snippet.  

ShowDialog() returns a DialogResult Enumeration of either an OK or Cancel. Remember we talked about enumerations in part 3? Now, how do I know that an enumeration is returned? Because MSDN says so. An unexpected side effect of this dialog is that you can’t click OK in the dialog window until you select a file to open, so you get an input validation bonus. Once the file is selected and the user clicks Open, we simply pass the path to the Get-Content cmdlet on line 8 and resume your regularly scheduled Windows PowerShell script. There is no sense in re-inventing the wheel by using .NET Framework to read the file when we already have a cmdlet for that.

Image of script

One other thing to note about line 6 is that we could swap out [System.Windows.Forms.DialogResult]::OK for OK, and Windows PowerShell would understand what is meant; however, we would miss out on the opportunity to rehash the enumeration topic, and this guarantees that we get what we asked for. You know what happens when you assume?

I hope all of these pieces come together for you, and you start poking around MSDN a little and try out some things that you learned here. The beauty of digging into .NET Framework with Windows PowerShell is that you don’t have to know how to “code” or learn how to use Visual Studio. Let’s call Windows PowerShell a gateway language. There is much more to learn, and as Shubert mentioned in a previous post, there are many ways to do the same thing. So, the way that meets your requirements is the right way.

We encourage you to take the concepts we discussed in this blog series and have a peak at the .NET Framework Class Library. To start, pick a namespace that you are familiar with. I know Active Directory, so that is where I started. If you are more familiar with Exchange or SharePoint, start there. Pick anything you can think of regardless of whether it is immediately useful, and make it work. Start simple, and then dig into all of the methods and properties of your new object.

Talking PowerShell, anyone? I use this in meetings when I get bored.

<SCRIPT >

 [reflection.assembly]::loadwithpartialname("System.Speech") | Out-Null
$SayIt = New-Object system.Speech.Synthesis.SpeechSynthesizer
$SayIt.Speak(".Net and PowerShell are cooler than cool")

</SCRIPT >

Image of script

Explain this snippet to yourself based on what we have talked about, and then open up the intertubes and look at MSDN to see how you can change the voice, gender, or age. The point is to just do something that doesn’t matter and have fun with it. When you need to use this on the job, you will be ready and confident to show off your new skills and added value for your boss. Tell them that Microsoft Premier sent you.

~Adam

Thank you, Adam and Shubert. This has been a great series. Awesome job.

Join me tomorrow when Microsoft PowerShell MVP and Honorary Scripting Guy Richard Siddaway brings us part 5 of his Windows PowerShell workflow basics series. It will be a real treat.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Hi Adam, Hi Shubert,

    thank you very much for your effort to tell us more about Powershell and the .Net framework!

    It makes perfectly sense to know more about the objects , classes, namespaces, methods, properties

    and so on that are present and could be more or less directly used within Powershell.

    This is a great deal ... having access to the framework 2.0 ( or 4.0 in PS 3.0 ) power is one of the huge wins

    that powershell offers to us.

    You did a great job trying to get us started with .Net objects and classes, but it definitely is like drilling a hole

    and a huge black box ... you can only scratch the surface presenting some OO terms, giving some small examples and explaining some basic concepts like reflection, assemblies, enumerations and so on.

    This is worth a book on its own! ( Even the Add-Type CmdLet is worth a five part series of blog articles )

    So maybe you left some of us behind, having more questions than before.

    The best resumée might be: If you have to use special .Net features because Powershell doesn't offer some functionality, start over finding information at MSDN e.g. and follow the steps presented here to get more insight into namespaces, classes, objects, methods and properties of the features you may have to explore in more detail.

    Thanks again .. great work, but "hard stuff" :-)

    Klaus.

  • @K_Schulte - Thanks for the feedback and your great summary. I figured for my first blog post ever, I would start with something easy like a 5 part series trying to translate developer language into administrator language :) It was fun and I hope to keep sharing my .Net journey and Shubert keeps sharing his .Net knowledge.  

  • Thanks for the code snippet guys. great for me as a beginner

    I have spotted your deliberate mistake in line 6 of your first bit of code - missing a )

    Also what is the difference between line 6 of the code and line 6 in the code image?

  • Ignore my question, I have read the article properly now :)

  • All fives are awesome. Thanks for those posts.

  • I realize this is well past the date of this post, but I wanted to share what I came up with. This is a way I came up with to combine both Open and Save FileDialog instances into a single function, with a few minor tweaks to things such as title, filter and InitialDirectory for the specific case I used it in. It also checks against the FileOK DialogResult event mentioned in the article. I find this class to be fairly straightforward and flexible to work with. For instance I could have set an InitialDirectory param and specify a default or tell it to open the last location, but I didn't need either of those in this instance.

    I actually only started getting into PowerShell about two months ago so perhaps this isn't the best way to approach it, but it seems to pretty solid to me with my knowledge thus far. I'd love to hear feedback otherwise :)

    This allows me to call the function with the following.
    $OpenPath = Prompt-FilePath -Open
    $SavePath = Prompt-FilePath -Save -FileName $SomeFile

    #Open and save dialog function
    Function Prompt-FilePath{
    Param(
    [Parameter(Mandatory=$True,
    Position=0,
    ParameterSetName="Open")]
    [Switch]$Open,

    [Parameter(Mandatory=$True,
    Position=0,
    ParameterSetName="Save")]
    [Switch]$Save,

    [Parameter(Mandatory=$False,
    Position=1,
    ParameterSetName="Open")]
    [Parameter(Mandatory=$True,
    Position=1,
    ParameterSetName="Save")]
    [ValidateNotNullOrEmpty()]
    [String]$FileName
    )
    Try{
    [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
    If ($Open) {
    $FileDialog = New-Object System.Windows.Forms.OpenFileDialog
    $FileDialog.Title = "Open XML Document"
    } ElseIf ($Save) {
    $FileDialog = New-Object System.Windows.Forms.SaveFileDialog
    $FileDialog.Title = "Save XML Document"
    $FileDialog.FileName = $FileName
    }
    $FileDialog.InitialDirectory = '\\path\to\network\share'
    $FileDialog.Filter = "XML File (*.xml) | *.xml"
    If (!($FileDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK)) {
    If ($Open) {
    Throw "Open file dialog was cancelled."
    } ElseIf ($Save) {
    Throw "Save file dialog was cancelled."
    }
    } Else {
    Return $FileDialog.FileName
    }
    } Catch [Exception] {
    Throw "File selection was not completed."
    }
    } # End Function Prompt-FilePath

  • Why would your comment box not save tab formatting or support HTML tags? Posting code examples would be so much better. Notepad++ has an amazing function to export formatting and syntax highlighting in HTML.