2011-12-13 76 views
2

我正在使用Windows 7上的winforms,在Visual Studio 2010中使用C#。 目前在Windows 7中安装以及从调试器安装下面的代码。但是,当程序安装在Windows XP中时,永远不会到达最后一行。SaveFileDialog无法在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()); 

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

调试器中没有错误,也没有事件日志。我已经使用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()实际显示的对话框的结果。

+1

常见的对话框使用COM,并且如果您不在单线程的公寓中,则以各种奇怪的方式运行。你的'Main'方法有'[STAThread]'属性吗? –

+0

嘿乔,是的,我有[STAThread]我的主: \t \t \t \t [STAThread] \t \t \t \t静态无效的主要() \t \t \t \t { \t \t \t \t \t Application.EnableVisualStyles() ; \t \t \t \t \t Application.SetCompatibleTextRenderingDefault(false); \t \t \t \t \t Application.Run(new frmLTSBC()); \t \t \t \t} – Direweasel

+0

如果你注释掉“string playlistSaveLocation ...”和接下来的两行,会发生什么? Win7计算机上播放列表保存位置的值是多少?也许UAC安全性是干扰性的。 – LarsTech

回答

0

原来这个问题比我第一次意识到的要简单。在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不会永久性地改变工作目录,这引起了我的困惑。希望这可以帮助遇到此问题的其他人。

1

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

+0

嘿JP2Code,我试过上面的,它没有产生任何额外的信息。该代码似乎挂在ShowDialog()上。对话框打开,用户选择一个地方保存和文件名,然后点击“好”,然后失败。 如果用户点击取消,一切正常。 – Direweasel

+0

我也尝试直接添加一个try catch循环,但没有任何结果。感觉ShowDialog根本没有完成它的工作。 \t \t \t \t'尝试 \t \t \t \t { \t \t \t \t \t结果= sfd.ShowDialog(); \t \t \t \t} \t \t \t \t赶上(异常前) \t \t \t \t { \t \t \t \t \t MessageBox.Show( “对话框问题:” + ex.Message); \t \t \t \t}' 'code' – Direweasel

+0

我已经添加了一个编辑部分。也许...... – jp2code