2017-03-03 74 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(); 

这有点击任何“取消按钮的效果密码“或”选择工作表“对话框。

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

相关问题