简体   繁体   中英

SaveFileDialog fails to return in Windows XP

I'm working with winforms on Windows 7, using C# in Visual Studio 2010. Currently in Windows 7 both install and from debugger the code below works. However, when the program is installed in Windows XP, the final line is never reached.

This code is called from a MenuStrip, and then passed to a subsequent method to perform the actions based on the item clicked in the menu. However, this is not the only place where SaveFileDialog is failing and it always fails on the ShowDialog() method.

Code for the MenuItem:

            private void saveOnlyPlaylistToolStripMenuItem_Click(object sender, EventArgs e)
            {
                try
                {
                    MainMenuClick(sender, e);
                }
                catch (Exception ex)
                {
                    StackTrace st = new StackTrace();
                    string methodName = st.GetFrame(1).GetMethod().Name;
                    Logger.LogToFile("Failure in " + methodName + ": " + ex.Message);
                }
            }

Code that is failing:

            Logger.LogToFile("Entered Save Only Playlist.");
            SaveFileDialog sfd = new SaveFileDialog();
            string playlistSaveLocation = config["PlaylistLocation"];
            if (!Directory.Exists(playlistSaveLocation))
                Directory.CreateDirectory(playlistSaveLocation);
            sfd.InitialDirectory = playlistSaveLocation;
            sfd.Filter = "L Playlist (*.lpl)|*.lpl";

            DialogResult result = sfd.ShowDialog();
            Logger.LogToFile("Result of Dialog: " + result.ToString());

I can't figure out why the last line is not being called, it feels like the ShowDialog() method of the SaveFileDialog is no completing. Afterwards the program continues to run fine, but will no longer interact with the file directory and cannot make new processes.

There is no error left in the debugger, nor the event log. I've rebuilt it on a windows XP using Visual Studio 2010 and it worked fine, the error only seems to appear when the program is created in Windows 7 and then installed on Windows XP. Windows 7 is 64 bit.

I should note that I have all exceptions being thrown from Debug -> Exceptions.

I've searched around and there doesn't seem to be many cases of a base method like SaveFileDialog failing, any ideas on what could be causing this issue?


Further analysis based on the answer below has lead to me to believe that perhaps this has something to do with how the SaveFileDialog is being called. Since this is being called from a MenuStrip, I believe it is coming out as a separate thread. This may be the reason why the ShowDialog() method is never returning, but I can't pinpoint why that would be. In an effort to find the problem, I created a separate window form that did nothing but had a button to open a save file dialog. This button works, and correctly returns, but upon returning control back to the original thread it seems to fail again. This is all based on the logging I am placing for debugging purposes.

Logging code:

            public static void LogToFile(string message, FileInfo fInfo)
            {
                try
                {
                    if (!fInfo.Exists)
                        using (FileStream fs = fInfo.Create()) ;

                    message = DateTime.Now.ToString("yyyy-MM-dd hh-mm-ss") + ": " + message;

                    File.AppendAllText(fInfo.FullName, message + "\n");
                }
                catch (Exception ex)
                {
                    StackTrace st = new StackTrace();
                    string methodName = st.GetFrame(1).GetMethod().Name;
                    MessageBox.Show("Failure in " + methodName + ": " + ex.Message);
                }
            }

Code for additional Window:

            public partial class Buffer : Form
            {
                public Buffer()
                {
                    InitializeComponent();
                }

                private void Buffer_Load(object sender, EventArgs e)
                {
                    Logger.LogToFile("Entered Save Only Playlist.");
                    SaveFileDialog sfd = new SaveFileDialog();
                    sfd.Filter = "Playlist (*.lpl)|*.lpl";
                    DialogResult result = System.Windows.Forms.DialogResult.Cancel;
                    try
                    {
                        result = sfd.ShowDialog();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Dialog problem: " + ex.Message);
                    }
                    Logger.LogToFile("Result of Dialog: " + result.ToString());
                    MessageBox.Show("Result of Dialog: " + result.ToString());
                    DialogResult = result;
                }
            }

The code above works, and the MessageBox.Show() actually shows the dialog result.

Generally, when something like this happens to me, I have found that I am getting yet another exception thrown from withing my catch routine of my try...catch function.

Try this and see if it helps:

private void saveOnlyPlaylistToolStripMenuItem_Click(object sender, EventArgs e) {
  StackTrace st = null;
  string message = null;
  try {
    MainMenuClick(sender, e);
  } catch (Exception ex) {
    st = new StackTrace();
    message = ex.Message;
  }
  if (st != null) {
    try {
      string methodName = st.GetFrame(1).GetMethod().Name;
      Logger.LogToFile("Failure in " + methodName + ": " + ex.Message);
    } catch (Exception ex) {
      MessageBox.Show(ex.Message);
    }
  }
}

EDIT:

What if you rewrite your Buffer_Load method like so:

private void Buffer_Load(object sender, EventArgs e)
{
  Logger.LogToFile("Entered Save Only Playlist.");
  DialogResult result = System.Windows.Forms.DialogResult.None;
  using (SaveFileDialog sfd = new SaveFileDialog())
  {
    sfd.Filter = "Playlist (*.lpl)|*.lpl";
    try
    {
      // Add `this`
      result = sfd.ShowDialog(this);
    }
    catch (Exception ex)
    {
      MessageBox.Show("Dialog problem: " + ex.Message);
    }
  }
  Logger.LogToFile("Result of Dialog: " + result.ToString());
  MessageBox.Show("Result of Dialog: " + result.ToString());
  // leave this line out - it would likely close your form:
  // DialogResult = result;
}

The this keyword helps, sometimes.

Turns out this issue was simpler than I first realized. In windows XP a Save File or Open File Dialog will change the working directory and cause the program to look in that location. Unfortunately I had not anticipated this in my Logger and therefore the log file was moving to an unexpected location.

            Logger.WriteToFile("DEBUG TEXT", "Debug.log");

Upon realizing this, the error quickly lead away from the SaveFileDialog and instead was resolved by ensuring all my files were being correctly referenced.

            string path = Path.Combine(Application.StartupPath, "Debug.log");
            Logger.WriteToFile("DEBUG TEXT", path);

A simple problem, though in Windows 7 a SaveFileDialog does not permanently alter the working directory and this caused my confusion. Hope this helps anyone else who runs into this issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM