Windows Develop Bookmark and Share   
 index > ClickOnce and Setup & Deployment Projects > Problem using FolderBrowser control in Setup project
 

Problem using FolderBrowser control in Setup project

Hi All,

I am using Microsoft Visual Studio .Net 2003.

I'm experiencing some problems using FolderBrowserDialog control in a Form
run by an Installer class during the Setup process of an application.

I have to ask the user to choose a folder for a one specified file during the Setup process.

When I try to Browse for Folders, I get a Window showing only OK and Cancel
buttons, the description and nothing more (the treeview does not appear)

Any other solution to use Folder Browser Dialog?

Thanks in Advance
anemvr  Monday, May 16, 2005 5:58 AM

Okay, after much testing I couldn't get it to work either, however I came up with the following:


public override void Install(System.Collections.IDictionary stateSaver)
{
 Thread thread = new Thread(new ThreadStart(DoWork));

 thread.SetApartmentState(ApartmentState.STA);
 thread.Start();
 thread.Join(); 
}

private void DoWork()
{
 using (System.Windows.Forms.FolderBrowserDialog dialog = new System.Windows.Forms.FolderBrowserDialog())
 {
  dialog.ShowDialog();
 }
}


 



Basically what we are doing is starting a new thread, setting it to use STA and then displaying the dialog from there.  This should get you started, but remember to make your code thread safe.

Note: If you try to show a FolderBrowserDialog on a thread that is not STA in Visual Studio 2005, an exception is now thrown, so it won't display at all.

David M. Kean  Monday, May 16, 2005 3:40 PM
This is typically because the STAThread attribute is missing on your Main. However, because you are using a custom action, try adding to the method that displays the FolderBrowserDialog, like so:


[STAThread]
private void ShowFolderBrowser()
{
   using (FolderBrowserDialog dialog = new FolderBrowserDialog))
   {
         dialog.ShowDialog();
   }
}

 
David M. Kean  Monday, May 16, 2005 10:07 AM
Hi David M. Kean,

Thanks for your help. 

I have tried with above code. Still I am not able to see the treeview in FolderBrowserDialog.

Is there any other solution, through which I can achieve my requirement (treeview has to be appeared).

Thanks for any help.
anemvr  Monday, May 16, 2005 1:50 PM

Okay, after much testing I couldn't get it to work either, however I came up with the following:


public override void Install(System.Collections.IDictionary stateSaver)
{
 Thread thread = new Thread(new ThreadStart(DoWork));

 thread.SetApartmentState(ApartmentState.STA);
 thread.Start();
 thread.Join(); 
}

private void DoWork()
{
 using (System.Windows.Forms.FolderBrowserDialog dialog = new System.Windows.Forms.FolderBrowserDialog())
 {
  dialog.ShowDialog();
 }
}


 



Basically what we are doing is starting a new thread, setting it to use STA and then displaying the dialog from there.  This should get you started, but remember to make your code thread safe.

Note: If you try to show a FolderBrowserDialog on a thread that is not STA in Visual Studio 2005, an exception is now thrown, so it won't display at all.

David M. Kean  Monday, May 16, 2005 3:40 PM

Hi David M. Kean,

Thank you for your help.

I have incorporated the above code in my setup code. Now FolderBrowserDialog is working good in my setup project. I am able to see the Treeview now.

Onec again Thanks for your timely help.

anemvr  Tuesday, May 17, 2005 11:30 AM
From Visual C# Express MSDN:
=======
"

New threads are initialized as ApartmentState.MTA if their apartment state has not been set before they are started. Apartment state must be set before a thread is started.

Note

The main application thread is initialized to ApartmentState.MTA by default. The only way to set the apartment state of the main application thread to ApartmentState.STA is to apply the STAThreadAttribute attribute to the entry point method.

The SetApartmentState method, along with the GetApartmentState method and the TrySetApartmentState method, replaces the ApartmentState property.

"

=====

So, I did set the atribute for the Main function like this:

[STAThread]
public static void Main(){...}

and it worked ok with the FolderBrowserDialog, without the need to create a special thread just for displaing the dialog.

But setting this atribute for the Main function will affect in any way the capacity of my app to work with multiple threads?

I did some test and it seems to work ok with multiple test, but I don't consider myself a expert in this field.. I wood apreciate a more adviced voice

Thank You


IrimiaBC  Tuesday, April 18, 2006 1:37 AM

It doesnt work to me. Could you help me? I dont think that creating a new thread is the solution. I´m trying to set <StaThread()> in the main of the installer class. I cant understand why it doesnt works.

Any help would be appreciated.

jorge1234567  Wednesday, June 14, 2006 11:01 AM
You can't change the ApartmentState of an installer thread, hence why you have to create another thread. Why doesn't it work for you?
David M. Kean  Wednesday, June 14, 2006 2:05 PM

I'm glad I checked before posting this same problem. Thanks to David for the answer. Would anyone like to tell me why it works this way? Any one find a KB article on this?

Meanwhile, to do who are like me arrive at this problem via C# and VSS 2005 (BTW, the wrong thread state did not throw an exception for me), here is the C# code that works for me. Note that "myFolderDialog" is my name for the FolderDialog on my form.

public string getFilePath(string dialogString)
{
try {
string pathname = null;
Thread FolderDlgThread = new Thread(getFilePathThread);
FolderDlgThread.SetApartmentState(
ApartmentState.STA);
FolderDlgThread.Start();
FolderDlgThread.Join();
pathname = myFolderDialog.SelectedPath;
return pathname;
}
catch (Exception err) {
displayException(err);
return null;
}
}

[STAThread]
public void getFilePathThread()
{
try
{
string pathname = null;
myFolderDialog.Site =
null;
DialogResult stat = myFolderDialog.ShowDialog();
if (stat == DialogResult.OK) {
pathname = myFolderDialog.SelectedPath;
}
}
catch (Exception err)
{
displayException(err);
}
}

PaulSQL  Tuesday, October 31, 2006 4:10 AM

I have been developing an SSIS package and encountered this issue. The BrowseFolderDialog is blank. It appears as a form, but without a treeview in it. The C# code above worked when nothing else would. Here it is in VB.NET specialized for SSIS:

Code Snippet

Public Sub Main()

Dim thread As New Threading.Thread(New Threading.ThreadStart(AddressOf DoWork))

thread.SetApartmentState(Threading.ApartmentState.STA)

thread.Start()

thread.Join()

Dts.TaskResult = Dts.Results.Success

End Sub

Private Sub DoWork()

Dim fn As String

Dim sfd As New System.Windows.Forms.FolderBrowserDialog

sfd.RootFolder = Environment.SpecialFolder.Desktop'use this for special folders, or set the selected path text for normal or even UNC start paths

sfd.Description = "Drop CSV Files Where?"'The folder browser dialog's caption

If sfd.ShowDialog = Windows.Forms.DialogResult.OK Then fn = sfd.SelectedPath Else Dts.TaskResult = Dts.Results.Failure 'SSIS stuff

Dts.Variables("varDestFolder").Value = fn 'SSIS stuff

End Sub

UsarianMSkiff  Wednesday, June 18, 2008 9:06 PM

The reason this will always be unpredictable is that you're running on a msiexec.exe process with a restricted set of rights in a threading environment where Windows Installer does not expect you to be showing UI. You're supposed to collect user data up front in the UI sequence and set properties that are used during the actual install (while progress is showing).Your custom actions run too late tochange installationfolders, so effectively all you're doing is application configuration. You should be doing this with a configuration app that runs after the install, and you should just choose a reasonable default folder at install time. The interesting question is from a user that says "but I want to use a different folder now because the folder I used at install time doesn't exist any more. What do I do? Reinstall the darn app again?".

PhilWilson  Wednesday, June 18, 2008 9:31 PM

Just for sharing ^^

Don't use Thread.Join() here, otherwise you will be facing UI of main form gets stuck.

I use Control.Invoke to set the text box on main form, and bind it to the backend member variable.

Code Snippet

public class Utility
{
static Utility()
{
_folderBrowserDialog = new FolderBrowserDialog();
_folderBrowserDialog.ShowNewFolderButton = false;
_folderBrowserDialog.RootFolder = Environment.SpecialFolder.MyComputer;

_mydelegate = new SetControlValueDelegate(SetControlValue);
}

public static void GetFilePath(Control ctrl)
{

Thread folderDlgThread = new Thread(new ParameterizedThreadStart(doWork));

folderDlgThread.SetApartmentState(ApartmentState.STA);
folderDlgThread.Start(ctrl);

}


[STAThread]
private static void doWork(object data)
{
lock (_thisLock)
{
if (_folderBrowserDialog.ShowDialog() == DialogResult.OK)
{
_folderPath = _folderBrowserDialog.SelectedPath;

Control ctrl = (Control)data;
if (ctrl.InvokeRequired)
{
ctrl.Invoke(_mydelegate, new object[] { data, _folderPath });
}
}
else
_folderPath = string.Empty;
}
}

public delegate void SetControlValueDelegate(Control ctrl, string value);

private static SetControlValueDelegate _mydelegate;

private static void SetControlValue(Control ctrl, string value)
{
TextBox temp = ctrl as TextBox;
if (temp != null)
{
temp.Text = value;

}
}

private static FolderBrowserDialog _folderBrowserDialog;
private static string _folderPath;

private static Object _thisLock = new Object();
#endregion
}

Austin

天鎖斬月  Monday, July 21, 2008 2:12 AM
I have implemented the above code butthe FolderBrowserDialog is appearing belowthe actual form!
Please Help.
Rupi.k  Wednesday, April 29, 2009 3:24 PM

You can use google to search for other answers

Custom Search

More Threads

• not able to remove earlier versions before 1.0 in setup project
• Windows Media Encoder app AND Windows Encoder install?
• How to save VS2008 project into VS2005?
• Prerequisites problem using Click Once
• clickonce prerequisites always deployed
• How to place a new font into [Fonts System] with click once
• How to Deploy Other Config Files Other than App.Config???
• Some of the users not getting prompts to download latest deployed version
• Web Deploying - Using Config Files?
• .NET Application Updater - the process cannot access the file