How to delete pst file after deleting store using c# - outlook

I m removing the store and would like to delete the .pst file associated with it. I am developing a VSTO addin, where in once user logout then I would like to delete .pst file created for it. Again when user login, then will create new store and new .pst file associated with it.

PST provider keeps the PST file open for 30 minutes (or until the process terminates) for the performance and sharing purposes after it is removed from a profile.
You might want to play with the registry key mentioned in https://www.betaarchive.com/wiki/index.php/Microsoft_KB_Archive/222328 to make sure the file is closed sooner.
If this is a temporary PST file that the end user does not necessarily need to see, you can create an auxiliary exe that processes the PST. After the process exits, the PST file can be deleted. Note that you would need to use Extended MAPI (C++ or Delphi only) or Redemption (I am its author - any language, use RDOSession.LogonPstStore) as the Outlook Object Model calls would still be marshalled back to the outlook.exe address space where your addin is running.

Related

Powershell Script to Create Outlook 2019 Personal Folder

Currently users have their own inbox folder and due to corporate policy emails will automatically be deleted after a set period of time.
Some emails however users would like to be able to keep for reference.
In order to accomplish allowing users to keep their importasnt emails; a personal folder file .pst needs to be created. The deletion policy will on affect the exchange profile folder that they currently use. This special personal folder should not be touched by the corporate system.
I need to be able to run a powershell script to automatically create this folder for the user (logged in user on the computer) and assign it in outlook 2019 for use, the user will then copy their specific emails into that personal folder. If I can't do it for the current logged in user - then by a collection of usernames and put in their one drive folder ??
Anyone with knowledge of how to or code to do this, I would appreciate your help - while I can code - I'am not a Powershell Guru so specifics and functions that experts might know exactly - I do not know, so please in your answer provide good guidance.
I am using windows 10 .1909 and the powershell version that ships with it.
The Outlook object model provides the AddStoreEx method which adds a Personal Folders file (.pst) in the specified format to the current profile.
Sub CreateUnicodePST()
Dim myNameSpace As Outlook.NameSpace
Set myNameSpace = Application.GetNamespace("MAPI")
myNameSpace.AddStoreEx "c:\" & myNameSpace.CurrentUser & "\.pst",olStoreUnicode
End Sub
After creating additional storage in the Outlook profile users can move items for keeping them locally. Or you may consider creating a VBA script or COM add-in for doing that programmatically. See Walkthrough: Create your first VSTO Add-in for Outlook for getting started quickly.

How to create Global Address List folder in Outlook programmatically?

I have Outlook plugin (written with Visual C++) which syncs contacts with DAV server (which acts as a replacement to Exchange). Personal contacts are fine but I don't know how to mimic the behavior of Global Address List (GAL).
Ideally, I want to create GAL folder the user will be able to search just like how it happens when Outlook is connected to Exchange. Is it possible at all? Perhaps, it's not possible with Outlook Object Model but still possible with MAPI? Can anybody point me in the right direction on how to start?
I need to support Outlook 2007+ but supporting only the newest versions (for this particular functionality) is an option, too.
Originally, I just synced the entire GAL folder and made it read-only so that Outlook stored the local copy of the entire GAL. This does not work well when the GAL size stretches to thousands of records.
You cannot do that - the address book provider can tell Outlook to only allow searches and never display the actual contents of the container.
You cannot do that with an Outlook folder unless you create your own MAPI store provider: then you can return any data you want depending on what the user is doing.

How can I open an Outlook data file programmatically?

In my current environment, I have to run Outlook as administrator on my workstation and that doesn't play well with some of my other software that is using the Outlook 2010 Developer Reference to move messages around in the Outlook mailbox.
The only thing I've been able to do to keep from getting the error code 0x8004010F is to "Close" the most current Outlook Data File I use as permanent storage and then reopen it. However, I need to do that now programmatically. I can't find anything in the Outlook 2010 Developer Reference about opening/closing the data files but surely Outlook can do it.
How can I do this?
Clarification: When I say that I need to 'close then open' the data file, it is within the current session of the Outlook mail client. The act of closing/opening the data file allows Outlook to receive/process the commands to move messages within the Exchange storage space.
The error is MAPI_E_NOT_FOUND. What exactly raises that error?
You can use Namespace.AddStore/AddStoreEx to add a PST store and Namespace.RemoveStore to close it. Keep in mind however that the PST provider will still keep the PST file locked for 30 minutes or until Outlook closes.

Dynamically changing file lock/access permissions on open file

I have a client application where we try to check files in and out from SharePoint for editing. I am using SharePoint's SOAP interfaces and some FrontPage interfaces to do this. It used to work fine under SharePoint 2007, but with 2010 I can't check out or check in a file if I have the file open for editing. I get a message like "FileXXX is locked for exclusive use by DOMAIN\user" when I examine the returned error message. I also cannot update any of the user defined SharePoint fields for a file/list if the file is open for editing.
My question is this: Is there a way to change the access/lock for an open file to make it non-exclusive temporarily and then restore it?
Note: Some of my data files are opened using windows file handles (flat files) and others are opened using windows structured storage (compound document files).
This may not work for Sharepoint specifically, but the ReOpenFile() API does what you want. I don't know of any other way to do this.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365497(v=vs.85).aspx

Windows API hook, custom save as file dialog to save directly to webserver via POST

I want to write a custom save as dialog that is hooked into the File -> "Save As" of most Windows program. This custom dialog will allow the user to enter their username, password, destination folder and uploads the file to the web server via a POST. If the user clicks cancel, it will call the original file dialog.
I've been reading up about Windows API hooking and this is vaguely how I think I would approach this:
Intercept "Save As"
Display my custom dialog, return some temporary path on the drive
Let the program write file to the temporary path, assume it calls WINAPI CreateFile(...) for now
Read the temporary file and upload to web server
Clean up temporary file
But I still can't get my head around the steps required to pull this off. Assuming I can intercept the "Save As" and CreateFile function, how do I detect the CreateFile was called from a "Save As" and not just any random file creation? I can think of a hack where I keep track of the time difference of when the File dialog got open and CreateFile got called.
My alternative solution is to use the existing file dialog and create a special folder on the disk, that is constantly monitored. When a file gets written there it will call an external program that uploads the file. I haven't looked into how to do this yet. I suspect this is easier.
UPDATE
As a first baby step, I wrote a .NET task tray application that allows the user to enter their login details and a folder to monitor. Whenever a file gets dropped in there there it will upload to the web server. So far it seems to work. Now I just need to figure out how to add a nice shortcut to the left pane of the file dialog. Once that's done I think I got a solution I'm happy with.
There is no need to hook or patch anything. Create a shell namespace extension that supports IStorage::CreateStream and implements it by returning a stream that POSTs its data to the Web server. The user can then choose to save the file to your namespace extension in order to upload the file.
Hooking the standard save dialog requires you to inject a DLL into every running process and have it replace the import stub of the the Win32 API GetSaveFileName() function in the process's PE header (something anti-virus and anti-malware apps are not likely to be happy about).
Then there is the new-style save dialog that was introduced in Vista using the new IFileSaveDialog COM interface instead of GetSaveFileName(). For that, you would have to uninstall and replace Microsoft's default FileDialog COM object with a custom implementation.
That does not count custom-made save dialogs, which you are not likely to hook.
If, by some miracle, you can hook the dialog and have it return a custom path of your own creation, you don't need to hook CreateFile() itself, Just monitor the folder that you create for your purposes. Place it where it is unlikely that any other app (or user) besides you will write files to. You can create a custom subfolder in the user's or system'ss AppData folder for that purpose. You can use SHGetSpecialFolderPath() and/or SHGetKnownFolderPath() to find those folders.
The tricky part will be detecting when the file is finished being written to and has been closed. You will have to monitor the folder for changes, such as with ReadDirectoryChangesW() or SHChangeNotifyRegister(), and periodically open new/modified files for exclusive access. If a file is still open by someone else, you won't be able to open it yourself. But once you do open it, you can do whatever you want with it.

Resources