I am creating a simple application that will allow users to download .ICS files, and import them into their chosen calendar application/site.
I am happy with the creation process, but have a question regarding opening them in outlook.
(will be developed in C#, ASP.NET)
When I open one, it adds a new calendar, and doesn't add the events to the existing calendar.
Is it possible to open, and add to the existing calendar?
Example from a generate ICS file below (test data obviously)
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//hacksw/handcal//NONSGML v1.0//EN
BEGIN:VEVENT
DTSTART:20100623T1101100Z
DTEND:20100623T1401400Z
SUMMARY: England v Slovenia
LOCATION: Some where in South Africa
END:VEVENT
BEGIN:VEVENT
DTSTART:20100624T1101100Z
DTEND:20100624T1401400Z
SUMMARY: England v Slovenia again (replay)
LOCATION: Some where in South Africa
END:VEVENT
END:VCALENDAR
Yes, but that has to happen by the user and not the ICS file; I remember dealing with this before too, if you want to import into an existing calendar, there is an import feature in the menu...
Sorry for the vagueness, I dealt with that long ago and cannot remember the exact steps... I did find the answer in the help I believe, but essentially you can import them in, but if you open up the ICS directly, it creates a new calendar.
Also, it isn't smart enough to delete the old ones, so if you import more than once, you will have duplicates.
HTH.
To add events to an existing calendar, first you have to save .ics file and then import it, choosing Import instead of New while importing.
Related
Short Version
I am attempting to access the TimeZoneStruct using VSTO from an Outlook Appointment.
The following error is thrown when attempting to access it.
System.Runtime.InteropServices.COMException (0x80040102): Object does not support property "http://schemas.microsoft.com/mapi/id/{00062002-0000-0000-C000-000000000046}/82330102".
Interestingly, I am able to get a similar property, TimeZoneDescription, using the same method with no exceptions:
http://schemas.microsoft.com/mapi/id/{00062002-0000-0000-C000-000000000046}/8234001F
My code is below; the first call to GetProperty succeeds, but the second does not.
//OK returns TimeZone Description string
dynamic tz1 = pa.GetProperty("http://schemas.microsoft.com/mapi/id/{00062002-0000-0000-C000-000000000046}/8234001F");
//NOK throws a COMException
dynamic tzStruct = pa.GetProperty("http://schemas.microsoft.com/mapi/id/{00062002-0000-0000-C000-000000000046}/82330102");
Long Version
I am developing a plugin that reads the Outlook calendar.
Currently the difficulty is with recurring appointments that were created with different timezones that have different Daylight Savings Time settings.
In order to find all appointments of a recurring meeting series, I need timezone information.
The first approach I used was to obtain the timezone information by extracting the timezone name. This works in most cases but is not ideal.
Outlook.PropertyAccessor pa = appointment.PropertyAccessor;
dynamic tz1 = pa.GetProperty("http://schemas.microsoft.com/mapi/id/{00062002-0000-0000-C000-000000000046}/8234001F");
This returns a string similar to (UTC+01:00) Amsterdam, Berlijn, Bern, Rome, Stockholm, Wenen.
This works correctly, but appointments that were sent from PC's with different languages, or in the case of "old" meetings with "obsolete" timezones that were deleted in a Windows Update, this does not work so well.
I will get meetings from computers from other languages, for instance this timezone is in French and my computer will not find it.
(UTC+03:00) Moscou, Saint-Pétersbourg, Volgograd
There are also updates; this timezone below no longer exists. Volograd was put in its own timezone at UTC+04:00 in 2016. See link from Microsoft.
Old: (UTC+03:00) Moscow, St. Petersburg, Volgograd
New: (UTC+03:00) Moscow, St. Petersburg
Obviously, matching the timezone name is never going to work.
I am focusing on getting the full information using the TimeZoneStruct instead; which should allow me to create a custom TimeZoneInfo Object; and then later I will be able to convert it into Local Time.
My problem is that when attempting to access this struct, I am getting the following error:
System.Runtime.InteropServices.COMException (0x80040102): Object does not support property "http://schemas.microsoft.com/mapi/id/{00062002-0000-0000-C000-000000000046}/82330102".
I have looked at OutlookSpy and can see that the property is indeed accessible.
I am using .NET Framework 4.6; Outlook 2016; Visual Studio 2015; Windows 8.1.
Any suggestions?
UPDATE
I'm trying to access this property using VBscript on Outlook Spy and getting a similar error.
The properties that are not PT_BINARY seem to work, for some reason.
Any ideas?
here's how to repeat the experiment
Using OutlookSpy, select a recurring appointment.
Make sure you are selecting the master and open the "Current Item" to run a script on the current AppointmentItem.
Enter the following code.
See screenshot for reference.
set msg = AppointmentItem
set pa = msg.PropertyAccessor
debug.print pa.GetProperty("http://schemas.microsoft.com/mapi/id/{00062002-0000-0000-C000-000000000046}/8234001F")
debug.print pa.GetProperty("http://schemas.microsoft.com/mapi/id/{00062002-0000-0000-C000-000000000046}/82310003")
debug.print pa.GetProperty("http://schemas.microsoft.com/mapi/id/{00062002-0000-0000-C000-000000000046}/82330102")
Outlook likes to play the Big Brother to prevent you from modifying, or sometimes even accessing, some properties that it considers special.
Using Extended MAPI (C++ or Delphi) or Redemption (any language, I am its author) instead of OOM is the only workaround.
I wanted to implement a trial version of my .NET application and I came across solutions that involved saving the dates in the app data folder. The questions I have are related to that solution and I would have commented over there but I dont have enough credits to comment.
So the solution I am following basically saves the created date and last opened date in a folder within App Data folder. If the folder did not exist before hand it creates one and after that checks the validity. That is all very good and it works.
What I want to know is:
1) What if an educated user navigates to the app data folder and deletes the folder. My solution would create a new folder and then it would be like starting over again. What would be the solution to that? I can only think of saving those credentials in different folders and checking all of them. Or maybe create that folder and the credentials during installation (which I dont know how to, I am using InstallSheild Wizard in Visual Studio). So any ideas regarding this?
2) What if originally I gave the client a 30 day trial and I was reading the dates from that folder and then validating. Then sometime later the customer buys a yearly subscription or something. How do cater that change? I could change the validation criteria in the code (I dont think that is very good either) but more importantly how can I sort of reset the app data folder? So that the validation of one year starts from the new installation/update date.
I have very little experience in developing .NET applications and even less in dealing with licenses etc. So kindly let me know a better way if there exists.
You need to hide the file in a secret folder / registry.
You can store subcription info into a file in same folder with the application. Your app will check this file first, if it does not exists, we will check the trail file.
The best solution I found was built right into Visual Studio.
Just go into properties of your project and select settings.
Add the fields you want to save. In my case they were the installed and last opened dates. And set the scope to User.
You can now access those fields by Properties.Settings.Default.%propertyname%
and do validations and set values as required.
At the end just save the settings.
The settings are saved in the hidden application data folder so they are safe from user intervention.
We are writing a c# server to generating the .ics files which would be shared by people from different timezones. We have one requirement says if the people in Sydney open the file the event says 9:30pm. The people in Perth should also see it as 9:30pm. i.e. No auto timezone offset applied the calendar by outlook.
I have looked many places and yet to find a solution.
Is that possible?
I don't think this really makes sense in terms of what an ics file represents - it's an invitation to an event, where "an event" is a thing which happens at a specific time. If something's happening at 09:30 in Sydney, then it's not happening at 09:30 in Perth so it can't be the same event. Sounds to me like you need to create multiple events, one for each timezone.
I have an ics file from google (attached below) and when I open the same in outlook, it doesnt add any event on the date mentioned in the file "20120823". But in DDay.ICal dll I use for programatically fetching the calendar events, the dll returns me 730 events. Any idea??
I saw a link that said that DDay have resolved this google calendar issue but seems its still not resolved. Any hack to this available will help greatly.
ICS content
BEGIN:VEVENT
DTSTART;VALUE=DATE:20120823
DTEND;VALUE=DATE:20120824
RRULE:FREQ=DAILY;UNTIL=20120824
EXDATE;VALUE=DATE:20120824
EXDATE;VALUE=DATE:20120823
DTSTAMP:20131031T111655Z
UID:xxxxxxxxxxxxxxxxxxxxxxxx#google.com
CREATED:20120621T142631Z
DESCRIPTION:
LAST-MODIFIED:20120621T142631Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Test Summary
TRANSP:TRANSPARENT
END:VEVENT
END:VCALENDAR
Below code returns me 730 occurances
IList<Occurrence> occurrences = iCal.GetOccurrences(
new iCalDateTime(2010, 1, 1, "US-Eastern"),
new iCalDateTime(2016, 12, 31, "US-Eastern"));
Issue is basically with google calendar but DDay have incorporated the issue in the code and republished the new dlls # http://www.ddaysoftware.com/Pages/Projects/DDay.iCal/
(Don't use dday.ical; use ical.net. It contains many performance enhancements and bugfixes.)
Looks like you found a bug. Which I fixed, and added a unit test for. It's in ical.net version 2.2.8+.
I know how to remove a store from Outlook by using _namespace.removestore([folder]), which is working fine.
But what can I do if the store does not exist as a physical file on disc anymore? In that case every acces to the store produces a messagebox Store couldn't be found. Please select one and a file open dialog is shown. Even an assignment like store = stores[i] checks whether the file exists and causes this message.
As a user I can right click on the store in Outlook an select close [PST]. Everything is ok after that. But i would like to do this programmatically. Can anyone tell me how to do this or someone has a good website to this topic?
You can do that in Extended MAPi (C++ or Delphi) - you will need to find the PST store row in the message service table (IMsgServiceAdmin::GetMsgServiceTable) based on the store entry id, then call IMsServiceAdmin::DeleteMsgService().
You can also use Redemption (I am its author) for that - RDOPSTStore.Remove will remove the store from the profile even if the PST file does not exist.