SaveFileDialog无法在Windows XP中返回

时间:2011-12-13 15:41:44

标签: c# visual-studio-2010 windows-7 windows-xp savefiledialog

我正在使用Visual Studio 2010中的C#在Windows 7上使用winforms。 目前在Windows 7中安装和从调试器下面的代码工作。但是,在Windows XP中安装程序时,永远不会到达最后一行。

此代码从MenuStrip调用,然后传递给后续方法,以根据菜单中单击的项目执行操作。但是,这不是SaveFileDialog失败的唯一地方,它总是在ShowDialog()方法上失败。

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);
                }
            }

失败的代码:

            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());

我无法弄清楚为什么没有调用最后一行,感觉SaveFileDialog的ShowDialog()方法没有完成。之后程序继续正常运行,但不再与文件目录交互,也无法创建新进程。

调试器中没有剩余错误,也没有事件日志。我使用Visual Studio 2010在Windows XP上重建它并且工作正常,只有当程序在Windows 7中创建然后安装在Windows XP上时才出现错误。 Windows 7是64位。

我应该注意,我从Debug中抛出了所有异常 - >异常。

我一直在搜索,似乎没有很多像SaveFileDialog这样的基本方法失败的问题,关于可能导致这个问题的任何想法?


基于以下答案的进一步分析使我相信这或许与SaveFileDialog的调用方式有关。由于这是从MenuStrip调用的,我相信它是作为一个单独的线程出现的。这可能是ShowDialog()方法永远不会返回的原因,但我无法确定原因。为了找到问题,我创建了一个单独的窗口表单,除了有一个打开保存文件对话框的按钮之外什么也没做。此按钮有效,并且正确返回,但在将控制权返回到原始线程时,它似乎再次失败。这完全基于我为调试目的而进行的日志记录。

记录代码:

            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);
                }
            }

其他窗口代码:

            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;
                }
            }

上面的代码可以工作,而MessageBox.Show()实际上显示了对话框结果。

2 个答案:

答案 0 :(得分:1)

一般来说,当这样的事情发生在我身上时,我发现我的catch函数的try...catch例程中出现了另一个异常。

试试这个,看看是否有帮助:

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);
    }
  }
}

修改

如果您重写Buffer_Load方法,那该怎么办:

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;
}

this关键字有时会有所帮助。

答案 1 :(得分:0)

事实证明这个问题比我第一次意识到的要简单。在Windows XP中,“保存文件”或“打开文件”对话框将更改工作目录并使程序在该位置查找。不幸的是,我没有在我的Logger中预料到这一点,因此日志文件正在移动到意外的位置。

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

意识到这一点后,错误很快就会从SaveFileDialog中消失,而是通过确保我的所有文件都被正确引用来解决。

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

一个简单的问题,虽然在Windows 7中,SaveFileDialog不会永久改变工作目录,这引起了我的困惑。希望这能帮助遇到此问题的其他人。