Information Management Policy in SharePoint - sharepoint

An obscure puzzle, but it's driving me absolutely nuts:
I'm creating a custom Information Management Policy in MOSS. I've implemented IPolicyFeature, and my policy feature happily registers itself by configuring a new SPItemEventReceiver. All new items in my library fire the events as they should, and it all works fine.
IPolicyFeature also has a method ProcessListItem, which is supposed to retroactively apply the policy to items that were already in the library (at least, it's supposed to do that for as long as it keeps returning true). Except it doesn't. It only applies the policy to the first item in the library, and I have absolutely no idea why.
It doesn't seem to be throwing an exception, and it really does return true from processing that first item, and I can't think what else to look at. Anyone?
Edit: Cory's answer, below, set me on the right track. Something else was indeed failing -- I didn't find out what, since my windbg-fu isn't what it should be, but I suspect it was something like "modifying a collection while it's being iterated over". My code was modifying the SPListItem that's passed into ProcessListItem, and then calling SystemUpdate on it; as soon as I changed the code so that it created its own variable (pointing at the exact same SPListItem) and used that, the problem went away...

There's only a couple of things I can think of to try. First, are you developing on the box where you might be able to use Visual Studio to debug? So just stepping through it.
Assuming that's not the case - what I'd do is fire up WinDBG and attach it to the process just before I registered the policy. Turn on first chance exceptions so that it breaks whenever they occur. you can do that by issuing the command "sxe clr" once it is broken in. Here's a little more info about WinDBG:
http://blogs.msdn.com/tess/archive/2008/06/05/setting-net-breakpoints-in-windbg-for-applications-that-crash-on-startup.aspx
What I'd do is then watch for First Chance exceptions to be thrown, and do a !PrintException to see what is going on. My guess is that there is an exception being thrown somewhere that is causing the app to stop processing the other items.
What does the logic look like for your ProcessListItem? Have you tried just doing a return true to make sure it works?

Some nice ideas there, thanks. The Visual Studio debugger wasn't showing an exception (and I've wrapped everything in try/catch blocks just in case), but I hadn't thought of trying Windbg...

Related

Why am I getting a DDE error when opening a file in Explorer that associated with our application?

Our legacy MDI desktop application uses the /dde switch in the association. When opening a file associated with it, and the application has not yet started up, Explorer pops up the following error:
There was a problem sending the command to the program.
The registry looks something like this:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\App.Document]
#="App File"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\App.Document\DefaultIcon]
#="d:\\Program Files (x86)\\MyApp\\version\\app.exe,1"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\App.Document\shell]
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\App.Document\shell\open]
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\App.Document\shell\open\command]
#="\"C:\\Program Files\\App\\app.exe\" /dde"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\App.Document\shell\open\ddeexec]
#="[open(\"%1\")]"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\App.Document\shell\print]
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\App.Document\shell\print\command]
#="C:\\Program Files\\App\\app.exe /dde"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\App.Document\shell\print\ddeexec]
#="[print(\"%1\")]"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\App.Document\shell\printto]
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\App.Document\shell\printto\command]
#="C:\\Program Files\\App\\app.exe /dde"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\App.Document\shell\printto\ddeexec]
#="[printto(\"%1\",\"%2\",\"%3\",\"%4\")]"
Just to be clear, I just took these entries from the registry. I'm not well versed in what they do, but I can hazard a guess that they link the verbs to actions by way of the DDE interface.
Note that if the application has already started up, the document opens up fine in that instance. This is only an issue if the application hasn't started up and must execute a new instance of the application.
So, what is happening is that the associated file is opened through Explorer by double clicking on it, and the associated application is executed. Explorer would then pop up that message and our application would do nothing. Double clicking on the file a second time would then open the document.
We've had this issue previously, but we just decided to ignore it for a few years as no one really knew what it was and we had other priorities at the time. Our workaround was to tell the user to change the /dde to "%1". Yeah, lame, but it worked well enough. One issue with doing that though, was that it would execute a new instance of the application, regardless if the application was already running or not.
Anyways, this issue is now starting to become an actual problem and needs to be fixed. One of our developers is saying that the DDE system is antiquated and we should try writing a COM component that will redirect to our application like Visual Studio does as debugging this issue could take a while. I've not verified that yet, nor researched how much effort that would be. However, either may be resource intensive, either on the debugging or the research side, so I'm trying to do some preliminary research to see what I can dig up and determine which is the better approach.
Stepping in the code, I was able to determine that it gets to a ::SetWindowPlacement() call and stepping over that will cause the error message box to pop up (if Explorer hasn't timed out first). As it is a WINAPI, I cannot step into that function to see what it is doing.
The application is written mostly in VC/VC++ using MFC/API and other libraries.
So my question is, does anyone know why this is happening and how it can be fixed?
Edit
Some additional information:
I was able to intercept all of the SendMessage()/PostMessage()/DispatchMessage() function calls non-destructively, which will log all of the messages. This was achieved by using MS Detours 3.0.
What I am seeing is that there are 4 SendMessage calls with a WM_COPYDATA message which appears to be coming out of shell32.dll. However, it doesn't appear to be the messages that are at fault though.
Putting a __debugbreak() when it detects the WM_COPYDATA message results in no error until a few steps beyond. How far depends on if I step or if I put a breakpoint and run the code to somewhere beyond where I thought I was getting the error. Using DebugBreak() seems to slow down the debugger to the point where I can't step without the error showing up.
What I can't understand is that there doesn't appear to be any rhyme or reason as to what is triggering the error message to pop up. I doesn't appear to be a timeout as the timeout appears to be long until I start stepping in the code, and sometimes no messages are being Sent/Posted by the code. So there's no WM_DDE_ACK (or any message for that matter) being sent back to the Explorer window that has initiated this. This is very frustrating.
To further complicate things, if I use the intrinsic __debugbreak() call and I have a breakpoint somewhere else in the code, it sometimes can stop at that breakpoint rather than stopping at the __debugbreak(). And sometimes, when I run the code immediately when I get control of the debugger, it will sometimes result in a second break, as if it hit another __debugbreak(). What's that all about? Inconsistent debugging is certainly making this issue even harder to track down. >:(
This DDE stuff is still the in use for MDI interfaces. So if one EXE opens different files.
If you can launch you application multiple times and this is OK, for the customer, switching the entries in the registry to the normal place holders from the SDI is OK too.
Usually this message is shown from the explorer, if the EXE doesn't get ready in a specific time to accept the DDE commands.
So the main question for you is: What is changed or so slow in the application that the DDE messages are not retrieved.
On case would be if it takes a real long time until the message loop starts. A running message loop for the main window is required for DDE support.
SetWindowPos istself will not be the problem, but it might cause hundreds of messages (WM_SIZE, ...) to be fired to your application, and every handler in your application here might be the problem.
Just place a little timer inside the application in front of the SetWindowPos and check how long it takes to return...
Check how long the app takes, until InitInstance is exited with TRUE. After InitInstance exits CWinApp::Run starts and the message loop starts.
I've run into the same problem.
My solution was to add the ../ddeexec/* section in the registry on application startup and then remove them on application exit.
Not a very nice solution but it is easy to do, and it works.

Android Studio: Adding #+id through Design GUI Generates Errors

I have found a workaround for this, which I will be posting as an answer, but it still raises the question of why it happened in the first place.
When I try to add a new id through the Design GUI, I type the name into the box:
id_sample
As soon as I tab out of the box, it prepends #+id/:
#+id/id_sample
which sounds reasonable enough, because - hey, it's got to put in the instruction to add a new id per the documentation, right?
But when I go into the java code, autocomplete is giving me gibberish on the code side - because of the extra #+id/, autocomplete gives me #+id/id_sample for a grand total of
menu.findItem(R.id.#+id/id_sample);
which has invalid characters; while deleting them:
menu.findItem(R.id.id_sample);
gives the error Cannot resolve symbol 'id_sample' because the xml is insisting that the correct name includes the invalid characters. Catch 22.
So how do I properly reference an id?
Looking in the xml, the #+id/ actually gets added to the #+id/id_sample:
android:id=#+id/#+id/id_sample
which obviously gives the compiler a heart attack. Having figured out what was going on, it is easy (though tedious) enough to jump into the xml and delete the extra #+id/ but I can't see any way to get the designer to put it in right in the first place.
Once this is corrected in the xml, it gets automatically corrected in the GUI, autocomplete will give you the correct name when you go into the java code, and the compiler will recognize it.
All that's left is to wonder if there is something I'm doing wrong that is causing this. Is this a known (or unknown) bug? Knowing what is wrong, it can be fixed in the xml, but it seems the GUI should have gotten it right in the first place. Right?

How can I prevent Glimpse 1.8.2 from posting to api.mixpanel.com?

At certain times in its operation, Glimpse 1.8.2 POSTs to api.mixpanel.com.
What is it sending?
How can I stop this from happening?
How can I opt out?
From "avanderhoorn" at https://groups.google.com/forum/#!searchin/getglimpse-dev/mixpanel/getglimpse-dev/7WgpX_Menz4/tnqJBwt20ZgJ:
I'm sorry this caught you off guard, that is not our intension.
This is to be expected and went out with the last release - http://blog.getglimpse.com/2014/02/04/glimpse-1-8-2-released/ (see Glimpse Insights support). Its a part of an effort to try and make better decisions for choices we make -http://blog.getglimpse.com/2014/01/22/getting-greater-insights-into-glimpse/.
It is a part of core but when switched off, its a complete removal (from the blog post):
If you do opt-out, there will be no traces of Insights in your code base. Insights was designed not simply to be a switch on or off, but to be a complete removal. Meaning no traces of the Insights code will remain if you choose to opt out.
The information being gathered can be viewed if you have a look at local storage. If you want a better view than that, you can get the client repo - https://github.com/glimpse/glimpse.client/ - and running the test client - https://github.com/Glimpse/Glimpse.Client/blob/master/test/Client.html. Once you have that open you will see a tab called "Insights" on the right which shows the data as its being collected. Also, if you want to see the source code involved, its isolated to this one file - here is the specific code that captures the events https://github.com/Glimpse/Glimpse.Client/blob/master/source/glimpse.insight.js#L345-L520.
You are right about the fact that it should be on the site. We have a new site coming out soon and its noted there. Its an oversight and the fact that we have been focusing on the new stuff. In response to an earlier question - https://twitter.com/greensky/status/431491507590160384 - we have also updated the Glimpse.axd to have the code required to opt-out. This will go out with the next release.
As an action item on this, I'll update the config help page of the current website to make sure the same information thats in the post will be noted there. Also I would like your feedback if there is anything else you think we can do to help. For the sake of completeness, the following is the opt-out code which goes in your web.config:
<glimpse>
<clientScripts>
<ignoredTypes>
<add type="Glimpse.Core.ClientScript.Insight, Glimpse.Core"/>
</ignoredTypes>
</clientScripts>
</glimpse>
Lastly, as we get time, we will be making the data collected publicly available. If this is something you are interested in helping out with, we could sure use the help. We believe that information like this will not only help us make better decisions, but help the community inform us what they want beyond what we here from the occasional person on twitter or at conferences.
Let us know what you think.

Open a dialog from a Sitecore uiUpload Pipeline process

I'm currently trying to show a SheerResponse.YesNoCancel() dialog within the Save uiUpload pipeline process from Sitecore. The problem appears when I do that call and it throws a NullException. I thought it was weird so I started copying the code from Sitecore's DLL and adding it to my solution. After that, I found that if the property OutputEnable is false it returns a ClientCommand that is NULL and when it tries to add a control to it, the Exception appears. So Fixing that I was able to finish the execution of that method. Anyway I still can't show the dialog. So the question is: Can I show a Dialog from a Sitecore uiUpload pipeline?
Have you tried using Sitecore.Context.ClientPage.ClientResponse.YesNoCancel(), i did something similar to what you are trying to do, but i used Alert(), worked fine for me.
Update: Actually inside uiUpload pipeline you can't call this method, however what you can do is use HttpContext.Current.Response.Write("<html><head><script type=\"text/Javascript\">[Your Java Script</script></head></html>"), you will need to abort the pipeline after this args.AbortPipeline();, not sure if this will help your case or not
No you cannot. From http://sdn.sitecore.net/Articles/Media/Prevent%20Files%20from%20Uploading.aspx:
The uiUpload pipeline is run not as part of the Sheer event, but as part of the form loading process in response to a post back. This is because the uploaded files are only available during the "real" post back, and not during a Sheer UI event. In this sense, the uiUpload pipeline has not been designed to provide UI.
That page was written for v5.1 and 5.2, but I'm pretty sure it still applies. The page claims that you can emit javascript to the page like Ahmed suggested, but it didn't work when I tried it.

Top-level exception handling for (visual) web parts

I've looked into this quite extensively and I've found the following:
You can do some clever stuff to catch most errors by implementing a base class, see Andreas Knudsen's solution for this.
The Error event in UserControl never gets fired, see details here: http://weblogs.asp.net/vga/archive/2003/06/16/8748.aspx
What I can't find is any general way to catch errors occurring in postback events, such as the click event for a button, at the web part or user control level. What I mean by general is a something I can implement in a baseclass.
I'm aware the I should do proper try/catch in my code, but for large teams I'd like to be sure that a web part never crashes the page, but always shows a nice message and allows execution to continue for the other web parts on the page.
I don't think it's possible but I'd love to be proved wrong.
Thanks,
Bjoern
I think this is possible, but you have to work around the fact that when asp.net distributes the postback events it couldn't care less about your user control definitions, instead it only cares about controls that explicitly implement IPostBackEventHandler (like button / dropdown etc)
For pages you can override and try/catch RaisedPostBackEvent like for the other methods. (if you ever wanted a generic page-exception handling setup. (if you want this then please reconsider. I spent way too much time in my last project basically reimplementing the default asp.net exception handling logic just to get this to work. the devil's in the details)
What you could do is to have a base page in your system which all pages inherit from and which overrides RaisePostBackEvent(source, eventArgs). In this method you could see if the source inherits from your exception handling base control, or if it is contained within a control which does this. (navigate the parent graph)
If it is contained by one then do a try/catch around the call to base.Raise.... (see the code in
Transparent generic exception handling for asp.net / MOSS2007 (with code) ) and call the exceptionhappened method on the first candidate you found if indeed any exceptions occur.

Resources