2017-03-03 69 views
0

作爲文件存儲遷移項目的一部分,我試圖更改一些Excel工作簿中的某些Excel鏈接以反映新的文件存儲位置。使用C#打開一個非密碼保護的Excel工作簿,其中包含受密碼保護的Excel工作簿的鏈接

我在VS2017 RC中使用Winforms和C#來開發我打算部署的解決方案。

在我的代碼頂部,我有以下代碼,以便關閉警報並關閉鏈接的自動更新。

excelApp.Visible = true; 
excelApp.DisplayAlerts = false; 
excelApp.AskToUpdateLinks = false; 

在我的解決方案;我在Excel Workbook對象上調用ChangeLink方法,並傳入舊鏈接,新鏈接和Excel鏈接類型。

如果我打開工作簿保護一個非密碼包含鏈接到那些沒有密碼保護其他工作簿,我不明白一個問題,我的解決方案繼續成功改變鏈接的要求。

如果我打開包含鏈接到的密碼保護其他工作簿一非受密碼保護的工作簿,Excel中發出提示該鏈接工作簿輸入密碼。

有沒有人有任何想法抑制這個二級提示輸入鏈接的工作簿的密碼?我的代碼在下面,我等待你的迴應。

if (MsOfficeHelper.IsPasswordProtected(fileName)) 
    { 
     while ((excelApp.Workbooks.Count == 0) && (!allPasswordUsed)) 
     { 
      // Open workbook - trying each password from password list in turn 
      foreach (var excelPassword in excelPasswords) 
      { 
       try 
       { 
        excelWorkbook = excelApp.Workbooks.Open(Filename: fileName, UpdateLinks: Excel.XlUpdateLinks.xlUpdateLinksNever, Password: excelPassword); 
        allPasswordUsed = true; 
        resultsOut = resultsOut.AppendLine(fileName + " - Opened"); 
       } 
       catch (Exception WTF) 
       { 
        //MessageBox.Show(WTF.Message); 
       } 
      } 

      // Open workbook - trying each password from password list in turn 
      foreach (var excelPassword in excelPasswords) 
      { 
       try 
       { 
        excelWorkbook = excelApp.Workbooks.Open(Filename: fileName, UpdateLinks: Excel.XlUpdateLinks.xlUpdateLinksNever, Password: excelPassword.ToLower()); 
        allPasswordUsed = true; 
        resultsOut = resultsOut.AppendLine(fileName + " - Opened"); 
        // 
       } 
       catch (Exception WTF) 
       { 
        //MessageBox.Show(WTF.Message); 
       } 
      } 

      allPasswordUsed = true; 
      resultsOut = resultsOut.AppendLine(fileName + " - All known passwords used - Unable to Open File"); 
     } 
    } 
    else 
    { 
     // Open Workbook - no password required 
     excelWorkbook = excelApp.Workbooks.Open(Filename: fileName, UpdateLinks: Excel.XlUpdateLinks.xlUpdateLinksNever); 
     resultsOut = resultsOut.AppendLine(fileName + " - Opened"); 
    } 
+1

這是問答網站,而不是論壇。問題放在問題框中。沒有必要在標題中加入某種「標記」來進一步標記它們。 –

+0

@Damien_The_Unbeliever - 我問過一個問題,也許你可以重新閱讀我的文章。 –

+0

是的,但我的意思是說,由於某種原因,你覺得有必要在標題前添加「ISSUE - 」。我在編輯時做的是刪除那個標記,然後我的評論是幫助解釋*爲什麼*標記是不必要的。 –

回答

0

好的。 我一直無法找到任何有關解決這個問題的信息,所以我一直沒有選擇,只能開發一個使用調用Windows API的解決方法。

這是我開發的解決方案或解決方法。

在我的winform中,我已經將以下聲明添加到Windows API。

[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)] 
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 

[DllImport("user32.dll", CharSet = CharSet.Auto)] 
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); 

[DllImport("USER32.DLL")] 
public static extern bool SetForegroundWindow(IntPtr hWnd); 

我還在winform的頂部添加了以下內容。

public bool fileOpenInProgress = false; 

爲了我的winform,我加入了一個BackgroundWorker控制。 在此BackgroundWorker控件上,我將WorkerSupportsCancellation屬性設置爲True。

在BackgroundWorker控件的DoWork事件處理程序中,我已指定調用以下方法。

private void workerXLPwdDialogCheck_DoWork(object sender, DoWorkEventArgs e) 
{ 
    while (fileOpenInProgress) 
    { 

     IntPtr hwndExcel = FindWindow(lpClassName: "XLMain", lpWindowName: null); 
     SetForegroundWindow(hwndExcel); 

     try 
     { 
      IntPtr hwndPasswordDialog = FindWindow(lpClassName: null, lpWindowName: "Password"); 
      if (hwndPasswordDialog != IntPtr.Zero) 
      { 

       // Make the Password Dialog the active window 
       SetForegroundWindow(hwndPasswordDialog); 
       SendMessage(hwndPasswordDialog, WM_CLOSE, IntPtr.Zero, IntPtr.Zero); 
      } 

      IntPtr hwndSelectSheetDialog = FindWindow(lpClassName: null, lpWindowName: "Select Sheet"); 
      if (hwndSelectSheetDialog != IntPtr.Zero) 
      { 

       // Make the Password Dialog the active window 
       SetForegroundWindow(hwndSelectSheetDialog); 
       SendMessage(hwndSelectSheetDialog, WM_CLOSE, IntPtr.Zero, IntPtr.Zero); 
      } 


     } 
     catch (Exception WTF) 
     { 
      MessageBox.Show(WTF.Message); 
     } 
    } 
} 

在我的代碼的其餘部分,我做的Excel文件,並改變鏈接開幕,我有以下的代碼

  fileOpenInProgress = true; 
      workerXLPwdDialogCheck.RunWorkerAsync(); 

      StringBuilder resultsOut = new StringBuilder(); 

      if (MsOfficeHelper.IsPasswordProtected(fileName)) 
      { 
       while ((excelApp.Workbooks.Count == 0) && (!allPasswordUsed)) 
       { 
        // Open workbook - trying each password from password list in turn 
        foreach (var excelPassword in excelPasswords) 
        { 
         try 
         { 

          excelWorkbook = excelApp.Workbooks.Open(Filename: fileName, UpdateLinks: Excel.XlUpdateLinks.xlUpdateLinksNever, Password: excelPassword); 
          allPasswordUsed = true; 
          resultsOut = resultsOut.AppendLine(fileName + " - Opened"); 
         } 
         catch (Exception WTF) 
         { 
          //MessageBox.Show(WTF.Message); 
         } 
        } 

        // Open workbook - trying each password from password list in turn 
        foreach (var excelPassword in excelPasswords) 
        { 
         try 
         { 
          excelWorkbook = excelApp.Workbooks.Open(Filename: fileName, UpdateLinks: Excel.XlUpdateLinks.xlUpdateLinksNever, Password: excelPassword.ToLower()); 
          allPasswordUsed = true; 
          resultsOut = resultsOut.AppendLine(fileName + " - Opened"); 
          // 
         } 
         catch (Exception WTF) 
         { 
          //MessageBox.Show(WTF.Message); 
         } 
        } 

        allPasswordUsed = true; 
        resultsOut = resultsOut.AppendLine(fileName + " - All known passwords used - Unable to Open File"); 
       } 
      } 
      else 
      { 
       // Open Workbook - no password required 
       excelWorkbook = excelApp.Workbooks.Open(Filename: fileName, UpdateLinks: Excel.XlUpdateLinks.xlUpdateLinksNever); 
       resultsOut = resultsOut.AppendLine(fileName + " - Opened"); 
      } 

      // Assuming there is an openwork book object 
      // check to see if it contains links and attempt to update them. 
      if (excelApp.Workbooks.Count > 0) 
      { 
       excelWorkbook = excelApp.ActiveWorkbook; 
#pragma warning disable IDE0019 // Use pattern matching 
       Array olinks = excelWorkbook.LinkSources(Excel.XlLink.xlExcelLinks) as Array; 
#pragma warning restore IDE0019 // Use pattern matching 
       if (olinks != null) 
       { 
        if (olinks.Length > 0) 
        { 
         resultsOut = resultsOut.AppendLine(" " + fileName + " - " + olinks.Length.ToString() + " links."); 
         foreach (var olink in olinks) 
         { 
          oldLink = olink.ToString(); 

          // Search through list of linked files to find the oldLink 
          foreach (LinkedFile linkedFile in linkedFiles) 
          { 
           if (oldLink == linkedFile.OldLink) 
           { 
            newLink = linkedFile.NewLink; 
            break; 
           } 
          } 

          try 
          { 

           excelWorkbook.ChangeLink(Name: oldLink, NewName: newLink, Type: Excel.XlLinkType.xlLinkTypeExcelLinks); 
           resultsOut = resultsOut.AppendLine(" SUCCESS - ChangeLink from " + oldLink + " to " + newLink); 
           Application.DoEvents(); 
          } 
          catch (Exception whoopsy) 
          { 
           resultsOut = resultsOut.AppendLine(" FAILURE - ChangeLink from " + oldLink + " to " + newLink); 
           Application.DoEvents(); 
          } 

          //resultsOut = resultsOut.AppendLine(" " + oldLink); 

         } // End For loop 
        } 
        else 
        { 
         resultsOut = resultsOut.AppendLine(" No links."); 
        } 

       } 

       excelWorkbook.Close(SaveChanges: true); 
       resultsOut = resultsOut.AppendLine(fileName + " - Closed"); 
       resultsOut = resultsOut.AppendLine(" "); 

      } 

      // Stop the background worker that checks for the existence of a 
      // Excel Password Dialog 
      fileOpenInProgress = false; 
      workerXLPwdDialogCheck.CancelAsync(); 
      return resultsOut.ToString(); 

這有點擊任何「取消按鈕的效果密碼「或」選擇工作表「對話框。

它可能不是最漂亮的解決方法或解決方案,但它是功能性的。

相關問題