Why is my custom search folder criteria not being applied on some computers? - vsto

I've created an Outlook addin that uses AdvancedSearch to find all emails with a UserProperty defined by my addin.
This works on my own desktop and laptop, but doesn't work on my customer's device. We're both using the newest version of Outlook from Office 365, however he's on Windows 7 and I'm on Windows 10. I suspect this might be a Group Policy issue since he's part of an organisation, but telling him that isn't useful unless I can point at what specific policy needs to be changed, or what exactly is causing the issue, so he can tell the IT department exactly what's wrong.
I've enabled error messages so I can see any exceptions, but none show up. The only time an exception is thrown (to my knowledge) is when the addin attempts to create the folders if they're already there; if the folders are deleted, no exceptions are thrown by the addin.
This is the code that adds the search folders
private void SearchFolders(Outlook.Application application)
{
string scope = "Inbox";
string filter = $"http://schemas.microsoft.com/mapi/string/{{00020329-0000-0000-C000-000000000046}}/{userProperty} = true";
Outlook.Search search = null;
Outlook.MAPIFolder folderInbox = null;
Outlook.MAPIFolder folderSentMail = null;
Outlook.NameSpace ns = null;
try
{
ns = application.GetNamespace("MAPI");
folderInbox = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
//MessageBox.Show(folderInbox.FolderPath.ToString());
folderSentMail = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail);
scope = "\'" + folderInbox.FolderPath + "\'";
search = application.AdvancedSearch(scope, filter, true);
search.Save("GDPR - indbakke");
scope = "\'" + folderSentMail.FolderPath + "\'";
search = application.AdvancedSearch(scope, filter, true);
search.Save("GDPR - Sendt post");
}
catch (Exception e)
{
MessageBox.Show(e.StackTrace, "An exception was thrown");
}
finally
{
if (search != null) Marshal.ReleaseComObject(search);
if (folderInbox != null) Marshal.ReleaseComObject(folderInbox);
if (folderSentMail != null) Marshal.ReleaseComObject(folderSentMail);
if (ns != null) Marshal.ReleaseComObject(ns);
}
}
The variable userProperty is instantiated as a string at the top of the file, and is simply the name of the UserProperty.
The search folders are supposed to include any mails that have the UserProperty set to true. However, the inbox search folder will sometimes include all emails in the inbox, while the "sent mail" search folder will just include nothing at all.
I know that marking the emails works on his device, since the column I added to show this property shows up, and shows that the email is marked correctly. It's just the search folders that don't work.
Looking at the search criteria in OutlookSpy shows me that the criteria are different on my computer compared to his. My PC shows the following:
rt : RES_PROPERTY
res.resProperty :
relop : RELOP_EQ
ulPropTag : GDPRMarked (0x8532000B)
lpProp :
ulPropTag : GDPRMarked (0x8532000B)
Value : true
while his PC shows this for the inbox:
rt : RES_EXIST
res.resExist :
ulPropTag : PR_SUBJECT_W (0x0037001F)
and this for the outgoing:
rt : RES_PROPERTY
res.resProperty :
relop : RELOP_EQ
ulPropTag : http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/GDPRMarked (0x8569001F)
lpProp :
ulPropTag : http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/GDPRMarked (0x8569001F)
Value : true

If you never added the property to the folder fields (and hence specified the property type), Outlook will assume that "GDPRMarked" is a string property.
The right criteria shows PT_BOOLEAN property type (0x8532000B), the bad one specifies PT_UNICODE (0x8569001F).

Related

How to exclude certain images from autosave in Gatan Digital Micrograph (GMS) in DM-script

I am trying to mimic the autosave function in GMS v3 so that I can use in version 1 and 2. I would like to first acknowledge that the main bulk of the script originates from Dr Bernhard Schaffer's "How to script... Digital Micrograph Scripting Handbook". I have modified it a bit, so that any new image recorded by the camera can be autosave into the file. However, I met some problems because if I decide to click on live-view image and move the image around, or using live-fft, the live view image or the FFT image will be saved as well. One of the ideas I have is to use the taggroup information such as the "Acquisition:Parameters:Parameter Set Name" because for live view or live-FFT, this would be either in search or focus mode. Another idea is to use the document ID e.g iDocID = idoc.ImageDocumentGETID() to locate the ID of the live image. However, i am clueless then how to use this information to exclude them from autosaving. Can anyone point to me how i can proceed with this script?
Below is the script
Class PeriodicAutoSave : Object
{
Number output
PeriodicAutoSave(Object self) Result("\n Object ID"+self.ScriptObjectGetID()+" created.")
~PeriodicAutoSave(Object self) Result("\n Object ID"+self.ScriptObjectGetID()+" destroyed")
Void Init2(Object self, Number op)
output=op
Void AutoSave_SaveAll(Object self)
{
String path, name, targettype, targettype1, area, mag, mode, search, result1
ImageDocument idoc
Number nr_idoc, count, index_i, index, iDocID, iDocID_search
path = "c:\\path\\"
name = "test"
targettype=="Gatan Format (*.dm4)"
targettype1 = "dm4"
If (output) Result("\n AutoSave...")
nr_idoc = CountImageDocuments()
For (count = 1; count<nr_idoc; count++)
{
idoc = GetImageDocument(count) //imagedocument
index = 1 // user decide the index to start with
index_i= nr_idoc - index
If (idoc.ImageDocumentIsDirty())
{
idoc = getfrontimagedocument()
iDocID = idoc.ImageDocumentGetID()
TagGroup tg = ImageGetTagGroup(idoc.ImageDocumentGetImage(0)) // cannot declare an 'img' for this line as it will prompt an error?
tg.TagGroupGetTagAsString("Microscope Info:Formatted Indicated Mag", mag)
Try{
{
idoc.ImageDocumentSavetoFile( "Gatan Format", path+index_i+"-"+name+"-"+mag+".dm4")
idoc.ImageDocumentSetName(index_i + "-"+name+"-"+mag+".dm4")
idoc.ImageDocumentClean()
}
If (Output) Result("\n\t saving: "+idoc.ImageDocumentGetCurrentFile())
}
Catch{
Result("\n image cannot be saved at the moment:" + GetExceptionString())
Break
}
Result("\ Continue autosave...")
}
}
}
}
Void LaunchAutoSave()
{
Object obj = Alloc(PeriodicAutoSave)
obj.Init2(2)
Number task_id = obj.AddMainThreadPeriodicTask("AutoSave_SaveALL",6)
//Sleep(10)
while(!shiftdown()) 1==2
RemoveMainThreadTask(task_id)
}
LaunchAutoSave()
thank you very much for your pointers! I have tried and it works very well with my script. as the 'TagGroupDoesTagExist' only refers to the taggroup, I modified further to include the tags I want to filter e.g "Search" or "Focus" and it seems to work well. The script that I modified to your existing ones is as below :
If (idoc.ImageDocumentIsDirty())
{
//now find out what is a filter condition and skip if it is true
skip = 0
TagGroup tg = idoc.ImageDocumentGetImage(0).ImageGetTagGroup()
tg.TagGroupGetTagAsString("Microscope Info:Formatted Indicated Mag", mag)
tg.TagGroupGetTagAsString("Acquisition:Parameters:Parameter Set Name", mode)
skip = tg.TagGroupDoesTagExist("Acquisition:Parameters:Parameter Set Name")
if(skip && (mode == "Search" || mode== "Focus")) continue
Your idea of filtering is a good one, but there is something strange with your for loop.
in
nr_idoc = CountImageDocuments()
For (count = 1; count<nr_idoc; count++)
{
idoc = GetImageDocument(count) //imagedocument
you iterate over all currently open imageDocuments (except the first one!?) and get them one by one, but then in
If (idoc.ImageDocumentIsDirty())
{
idoc = getfrontimagedocument()
you actually get the front-most (selected) document instead each time. Why are you doing this?
Why not go with:
number nr_idoc = CountImageDocuments()
for (number count = 0; count<nr_idoc; count++)
{
imagedocument idoc = GetImageDocument(count)
If (idoc.ImageDocumentIsDirty())
{
// now find out what is a filter condition and skip if it is true
number skip = 0
TagGroup tg = idoc.ImageDocumentGetImage(0).ImageGetTagGroup()
skip = tg.TagGroupDoesTagExist("Microscope Info:Formatted Indicated Mag")
if (skip) continue
// do saving
}
}

Why is a DOORS Module sometimes null when trying to edit the Module via DXL?

I'm new to DXL programming language in IBM DOORS. However, I think I have managed to do many interesting things: create Modules, create Objects, create Links, delete Objects etc.
However, I have a very specific problem regarding "null" Modules. I've just written null between "" because the modules exist and they are referenced with a correct name.
When doing this:
Module m1 = edit("1. MY_MODULE", false)
save(m1)
close(m1)
An error like this appears:
enter image description here
You could not understand what does that mean as it is spanish. Basically states this: "Module null parameter in the first position of the argument." That means that the "m1" is null, as the parameter for save() method is null.
The point is that it is an error which appears only sometimes. It seems that the Module is null as it has been previously opened and DOORS does not close properly.
Is there any way, any method...whatever to avoid this error?
I assume that the script cannot find the module when another folder is active.
Try
Module m1 = edit ("/myproject/myfolder/mysubfolder/1. MY_MODULE", false)
There might be many reasons that the module can't be opened in edit mode. For example: User do not have write access OR Module is being used by other user, etc.
However, you can get around the error with the below code snippet:
Module m = edit('My_module', false)
if(!null m) {
//execute program
...
}
else {
//do something
}
I hope this helps.
How does your script work? do you open the same module again and again and sometimes get the error or do you open lots of modules and for some of them it works and for others it doesn't? In the latter case, perhaps you misspelled the path. You could add some sanity checks like
string fullPathToMod = "/myproject/myfolder.."
Item i = item fullPathToMod;
if null i then error "there is no item called " fullPathToMod
if "Module" != type i then error "there is an item, but it's not a module, it's a " type i
This is how the Code is structured:
void checkModule(string folderPath, string mName, Skip list, int listSize, int listLastIndex, string headers[], string heading[], string headerKey, bool uniqueKey, string combinedKey[]){
if (module mName){
Folder f = folder(folderPath)
current = f
Module m = edit(folderPath""mName, false)
current = m
Object o = first(m) // error sometimes: Se ha pasado un parametro Module null en una posiciĆ³n de argumento 1
if (o == null){
loadModule(m, list, listSize, listLastIndex, headers, heading)
} else {
updateModule(m, mName, list, listSize, listLastIndex, heading, headerKey, headers, uniqueKey, combinedKey)
save(m)
close(m)
}
if (lastError() != ""){
print "Error: " lastError() "\n"
}
} else {
print "No module " mName ".\n"
}
}
Exactly it breaks in line:
current = m
But as said, only sometimes, not always.
BTW, I'm executing this script via Batch, via Java code. One curious thing is that if I close DOORS, and execute the script it does execute correctly. It is as if it needs to be closed in order to edit modules correctly.
I pressume current can be used more than once with different types of Items. I guess it should not be wrong, but it breaks saying (more or less):
Null value passed to DXL commmand (current Module).
Obviously, it means that m is null, but I cannot see any reason for that.

dnn 7+ search is not indexing custom module items

I have a dnn 7.2.2 development site running under dnndev.me on my local machine. I have created a simple product catalogue module and am trying to integrate the new search for dnn 7.
Here is the implementation of ModuleSearchBase in my feature/business controller
Imports DotNetNuke.Entities.Modules
Imports DotNetNuke.Services.Exceptions
Imports DotNetNuke.Services.Search
Imports DotNetNuke.Common.Globals
Namespace Components
Public Class FeatureController
Inherits ModuleSearchBase
Implements IUpgradeable
Public Overrides Function GetModifiedSearchDocuments(moduleInfo As ModuleInfo, beginDate As Date) As IList(Of Entities.SearchDocument)
Try
Dim SearchDocuments As New List(Of Entities.SearchDocument)
'get list of changed products
Dim vc As New ViewsController
Dim pList As List(Of vw_ProductList_Short_Active) = vc.GetProduct_Short_Active(moduleInfo.PortalID)
If pList IsNot Nothing Then
''for each product, create a searchdocument
For Each p As vw_ProductList_Short_Active In pList
Dim SearchDoc As New Entities.SearchDocument
Dim ModID As Integer = 0
If p.ModuleId Is Nothing OrElse p.ModuleId = 0 Then
ModID = moduleInfo.ModuleID
Else
ModID = p.ModuleId
End If
Dim array() As String = {"mid=" + ModID.ToString, "id=" + p.ProductId.ToString, "item=" + Replace(p.Name, " ", "-")}
Dim DetailUrl = NavigateURL(moduleInfo.TabID, GetPortalSettings(), "Detail", array)
With SearchDoc
.AuthorUserId = p.CreatedByUserId
.Body = p.ShortInfo
.Description = p.LongInfo
.IsActive = True
.PortalId = moduleInfo.PortalID
.ModifiedTimeUtc = p.LastUpdatedDate
.Title = p.Name + " - " + p.ProductNumber
.UniqueKey = Guid.NewGuid().ToString()
.Url = DetailUrl
.SearchTypeId = 2
.ModuleId = p.ModuleId
End With
SearchDocuments.Add(SearchDoc)
Next
Return SearchDocuments
Else
Return Nothing
End If
Catch ex As Exception
LogException(ex)
Return Nothing
End Try
End Function
End Class
End Namespace
I cleared the site cache and then I manually started a search re-index. I can see from the host schedule history that the re-index is run and completes.
PROBLEM
None of the items in the above code are added to the index. I even used the Luke Inspector to look into the lucene index and that confirms that these items are not added.
QUESTION
I need help figuring out why these items are not getting added or I need help on how to debug the indexing to see if anything is going run during that process.
Thanks in Advance
JK
EDIT #1
I ran the following procedure in Sql Server to see if the module is even listed in the search modules:
exec GetSearchModules[PortalId]
The module in question does appear in this list. The indexing is called for the featureController, but the results are not added to the lucene index. Still need help.
EDIT #2
So I upgraded to 7.3.1 in the hopes that something during the installation would fix this issue. But it did not. The search documents are still getting created/ returned by the GetModifiedSearchDocuments function but the documents are not being added to the Lucene index and therefore do not appear in the search results.
EDIT #3
The break point is not getting hit like i thought after the upgrade, but I added a try catch to log exceptions and the following error log is getting created when I try to manually re-index (cleaned up to keep it short)
AssemblyVersion:7.3.1
PortalID:-1
PortalName:
DefaultDataProvider:DotNetNuke.Data.SqlDataProvider, DotNetNuke
ExceptionGUID:d0a443da-3d68-4b82-afb3-8c9183cf8424
InnerException:Sequence contains more than one matching element
Method:System.Linq.Enumerable.Single
StackTrace:
Message:
System.InvalidOperationException: Sequence contains more than one matching element
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
at DotNetNuke.Services.Scheduling.Scheduler.CoreScheduler.LoadQueueFromTimer()
at DotNetNuke.Services.Scheduling.Scheduler.CoreScheduler.Start()
Source:
Server Name: KING-PC
EDIT #4
Okay, I fixed the problem in edit three following This Disucssion on the DNN issue tracker, but still no items being added to the lucene index.
The breakpoint is hit, and once i leave the debugger running for a while i get the following error:
{"Exception of type 'Lucene.Net.Index.MergePolicy+MergeException' was
thrown."} {"Cannot overwrite:
C:\websites\dnndev.me\App_Data\Search\_1f0.fdt"}
Looks like a permission error. I'll see what I can work out
J King,
I just finished a series on DNNHero.com on Implementing Search in your Module. Parts 3 and 4 are implementing and debugging your ModuleSearchBase implementation.
EDIT: Remove your assignment to the SearchTypeId in your implementation
Also, here is a sample snippet to see how i am setting the attributes of the SearchDocument. Again, watch my video for a whole bunch of other potential pitfalls in the Search implementation.
SearchDocument doc = new SearchDocument
{
UniqueKey = String.Format("{0}_{1}_{2}",
moduleInfo.ModuleDefinition.DefinitionName, moduleInfo.PortalID, item.ItemId),
AuthorUserId = item.AssignedUserId,
ModifiedTimeUtc = item.LastModifiedOnDate.ToUniversalTime(),
Title = item.ItemName,
Body = item.ItemDescription,
Url = "",
CultureCode = "en-US",
Description = "DotNetNuclear Search Content Item",
IsActive = true,
ModuleDefId = moduleInfo.ModuleDefID,
ModuleId = item.ModuleId,
PortalId = moduleInfo.PortalID,
TabId = tab
};

VSTO outlook Add-in How can I retrieve a Exchange Distribution list members from outlook distribution list

I have VSTO Add-in that gets the recipient from the mailitem and save it in our user list.
In case of exchange distribution list or exchange contact as a recipient it works fine by extracting smtp mail address from both of these. For this purpose outlook object model works.
but the problem arises when exchange distribution list is added as a member in the outlook distribution list and mail is sent to this local distribution list. Is there any way to extract smtp addresses of each contact from this nested distribution list.
So far I have user DistListItem.GetMember(i) Method to get a member of this distribution list. It provides a Recipient object and when i try to access a property member.AddressEntry.AddressEntryUserType from this object it throw an exception "The item could not be found".
Does anyone knows how can i get a distribution list member type or entryId from this recipient object?
private void GetDistributionListMembers()
{
Outlook.SelectNamesDialog snd =
Application.Session.GetSelectNamesDialog();
Outlook.AddressLists addrLists =
Application.Session.AddressLists;
foreach (Outlook.AddressList addrList in addrLists)
{
if (addrList.Name == "All Groups")
{
snd.InitialAddressList = addrList;
break;
}
}
snd.NumberOfRecipientSelectors =
Outlook.OlRecipientSelectors.olShowTo;
snd.ToLabel = "D/L";
snd.ShowOnlyInitialAddressList = true;
snd.AllowMultipleSelection = false;
snd.Display();
if (snd.Recipients.Count > 0)
{
Outlook.AddressEntry addrEntry =
snd.Recipients[1].AddressEntry;
if (addrEntry.AddressEntryUserType ==
Outlook.OlAddressEntryUserType.
olExchangeDistributionListAddressEntry)
{
Outlook.ExchangeDistributionList exchDL =
addrEntry.GetExchangeDistributionList();
Outlook.AddressEntries addrEntries =
exchDL.GetExchangeDistributionListMembers();
if (addrEntries != null)
foreach (Outlook.AddressEntry exchDLMember
in addrEntries)
{
Debug.WriteLine(exchDLMember.Name);
}
}
}
}

ClearCase : list the content of a directory (ls) using CAL

In ClearCase, you can list the content of a directory using "cleartool ls".
My question is how can I do the same thing using CAL (ClearCase Automation Layer). The reason I prefer the COM API is because I won't have to parse the output of "ls".
So far, I am able to get the VOB and the View successfully, but I didn't find any method for listing the content.
My code so far:
IClearCase cc = new ApplicationClass();
CCVOB vob = cc.get_VOB("\\VOB-name");
CCView view = cc.get_View("ViewTag");
Thank you for your help.
I wrote VonC's answer in C# for those interrested.
string[] files = Directory.GetFiles("View path here", "*.*", SearchOption.AllDirectories);
foreach (string file in files)
{
try
{
CCVersion ver = cc.get_Version(file);
Console.WriteLine(ver.Path);
}
catch(Exception) {/*the file is not versioned*/}
}
May be this is a good start:
Set CC = Wscript.CreateObject("ClearCase.Application")
Set DirVer = CC.Version(".")
Set FSO = CreateObject("Scripting.FileSystemObject")
Set Folder = FSO.GetFolder(DirVer.Path)
Wscript.Echo "Files under source control: "
For Each File in Folder.Files
On Error Resume Next
Set Ver = CC.Version(File.Name)
If Err.Number = 0 Then
Wscript.Echo Ver.ExtendedPath
End If
Next
The idea being to use ICCVersion methods to try accessing the version of a file. If it does not return an error, it is indeed a versioned file.
Now I know the file is versioned, how can I remove it (rmname).
Do not use RemoveVersion():
Removes irretrievably the version (equivalent to cleartool rmver)
WARNING! This is a potentially destructive operation. Because CAL does not prompt the user for input under any circumstances, there is no confirmation step when RemoveVersion is invoked. Invoking RemoveVersion is equivalent to running cleartool rmver with the -force option.
Instead use the RemoveName from the ICCElement interface.