保存文件对话框无法在 Windows XP 中返回

本文关键字:XP 返回 Windows 对话框 保存文件 | 更新日期: 2023-09-27 18:17:48

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

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

菜单项的代码:

            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位。

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

我已经搜索了一下,似乎没有很多像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(( 实际上显示了对话框结果。

保存文件对话框无法在 Windows XP 中返回

一般来说,当这样的事情发生在我身上时,我发现我又从try...catch函数的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关键字会有所帮助。

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

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

意识到这一点后,该错误很快导致SaveFileDialog离开,而是通过确保正确引用我的所有文件来解决。

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

一个简单的问题,尽管在Windows 7中SaveFileDialog不会永久更改工作目录,这引起了我的困惑。 希望这对遇到此问题的其他任何人有所帮助。