作为文件存储迁移项目的一部分,我正在尝试更改某些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");
}
答案 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;显示的对话框。
它可能不是最漂亮的解决方法或解决方案,但它是有效的。