使用C#打开一个非密码保护的Excel工作簿,其中包含指向受密码保护的Excel工作簿的链接

时间:2017-03-03 12:42:26

标签: c# excel

作为文件存储迁移项目的一部分,我正在尝试更改某些Excel工作簿中的某些Excel链接以反映新的文件存储位置。

我在VS2017 RC中使用Winforms和C#来开发我打算部署的解决方案。

在我的代码顶部,我有以下代码,以便关闭警报并关闭链接的自动更新。

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

在我的解决方案中;我在Excel Workbook对象上调用ChangeLink方法并传入旧链接,新链接和Excel链接类型。

如果我打开非密码保护的工作簿,其中包含指向其他未受密码保护的工作簿的链接,我就不会遇到问题而我的解决方案会解决按要求成功更改链接。

如果我打开非密码保护的工作簿,其中包含指向受密码保护的其他工作簿的链接,Excel会发出提示,为该链接的工作簿输入密码。< / p>

有没有人知道如何抑制链接工作簿密码的这个辅助提示?我的代码如下,等待您的回复。

    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 :(得分: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();

这样可以点击任何密码&#39;上的取消按钮。或者&#39;选择表格&#39;显示的对话框。

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