繁体   English   中英

SharePoint ClientContext.ExecuteQuery在C#应用程序中有效,但在DLL中崩溃

[英]SharePoint ClientContext.ExecuteQuery works in c# application but crashes in DLL

我编写了C#代码以在网站内的SharePoint列表中搜索特定的文件类型,并在列表视图中显示文件名。 该代码在C#Windows应用程序中运行良好,但是当将其编译为C#DLL并从Delphi2007应用程序中调用时,它在碰到对ClientContext.ExecuteQuery()的第一次调用时会崩溃。 没有异常或错误消息-Delphi应用程序只是停止运行。

真正奇怪的部分是我的Delphi测试应用程序具有Web浏览器组件,如果我使用它来导航到站点上的顶级列表,则DLL可以正常工作。

因此,问题是,如果我没有先登录到站点,为什么在DLL中的第一个ExecuteQuery调用会失败?

这是C#代码:

        public void ListFiles()
        {
            string LContains = "<Contains><FieldRef Name='FileLeafRef'/>   <Value Type ='Text'>{0}</Value></Contains>";
            string LNotEqual = "<Contains><FieldRef Name='FileLeafRef'/><Value Type ='Text'>{0}</Value></Contains>";
            string LWhereQuery = "";

            switch (comboFileType.SelectedIndex)
            {
                case 0: LWhereQuery = string.Format(LContains, ".DOC"); break;
                case 1: LWhereQuery = string.Format(LContains, ".PDF"); break;
                case 2: LWhereQuery = string.Format(LNotEqual, "xxxx"); break;
            }


            Uri LUri = new Uri(SharePointURL);
            using (SP.ClientContext LContext = new SP.ClientContext(SharePointURL))
            {
                System.Net.CredentialCache cc = new System.Net.CredentialCache();

                if (!string.IsNullOrEmpty(Domain))
                    cc.Add(LUri, AuthenticationType, new System.Net.NetworkCredential(UserName, Password, Domain));
                else
                    cc.Add(LUri, AuthenticationType, new System.Net.NetworkCredential(UserName, Password));

                LContext.Credentials = cc;
                LContext.AuthenticationMode = SP.ClientAuthenticationMode.Default;

                var LWeb = LContext.Web;
                lvItems.BeginUpdate();
                try
                {
                    try
                    {
                        SP.List LList = LWeb.Lists.GetByTitle(DefaultListName);

                        SP.CamlQuery LQuery = new SP.CamlQuery();
                        LQuery.ViewXml = "<View Scope='RecursiveAll'><Query><Where>"
                            + LWhereQuery
                            + "</Where></Query><RowLimit> 30 </RowLimit></View>";

                        SP.ListItemCollection LItems = LList.GetItems(LQuery);

                        LContext.Load(LItems);
                        LContext.ExecuteQuery();  **<<<< Crash happens here**

                            foreach (SP.ListItem LItem in LItems)
                            {
                                SP.File LFile = LItem.File;
                                LContext.Load(LFile);
                                LContext.ExecuteQuery();

                                var LViewItem = new ListViewItem();

                                try { LViewItem.Text = LFile.Name; }
                                catch { LViewItem.Text = "!Error"; }

                                try { LViewItem.SubItems.Add(LFile.TimeLastModified.ToString()); }
                                catch { LViewItem.SubItems.Add("!Error"); }

                                if (LFile.CheckOutType != Microsoft.SharePoint.Client.CheckOutType.None)
                                {
                                    try { LViewItem.SubItems.Add(LFile.CheckedOutByUser.LoginName); }
                                    catch { LViewItem.SubItems.Add("!Error"); }
                                }
                                else
                                    LViewItem.SubItems.Add("Not checked out.");

                                try { LViewItem.Tag = LFile.ServerRelativeUrl; }
                                catch { LViewItem.Tag = "!Error"; }

                                lvItems.Items.Add(LViewItem);

                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Error: " + ex);
                    }
                }
                finally
                {
                    lvItems.EndUpdate();
                }

        }

该代码位于DLL中对话框形式的.cs中。 表单按原样显示,并且崩溃仅在我单击按钮进行搜索时发生。

我放入一些调试代码来检查所有字符串参数等(通过将它们写入文本文件),它们都可以。

我尝试通过将D2007应用程序指定为“启动外部程序”来从VS调试DLL,但无法使断点正常工作,并且崩溃了,它说: 在系统中发生了'System.StackOverflowException'类型的未处理异常Microsoft.SharePoint.Client.Runtime.dll并建议我可能进行无限次递归调用,但是,如前所述,如果我已经登录到网站并浏览到顶层列表,则代码都可以正常工作,所以我没有认为这是一个递归调用。

更新:通过将Delphi exe复制到与DLL相同的目录中,我可以进行调试。

我尝试使用ExceptionHandlingScope,但没有帮助。 崩溃时的外观如下:

MSSP客户端运行时dll中的StackOverflow错误

范围没有异常,并且错误消息为空白。 我尝试了范围内的一些含义,但无济于事。

整个代码块都在try..catch中,我也尝试将ExecuteQuery行也包装在它自己的try..catch中,但没有任何东西能抓住它。 每次我点击继续时,应用都会崩溃。

我也尝试过在加载网络之前放置一个执行查询,但是它仍然崩溃了。

我认为这与凭证有关吗? 如果我故意输入错误的用户名,则会得到礼貌的“ 401未经授权”,并且不会崩溃。 如果我已经登录,它也不会崩溃?

在尝试了C#测试应用程序之后,我在Delphi XE8上进行了同样的尝试,并且同样有效,因此最终我不得不在XE8中编写一个中间DLL。

我注意到,将TLB从C#DLL导入XE8时,其行为与D2007不同,因为它在构建时抱怨其他缺少的TLB,尤其是system.windows.forms库(和某些依赖项)。 我不确定这是否与XE8正常工作以及D2007失败有关,但希望它能很好地帮助其他需要解决方法的人。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM