2011-12-13 78 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