Greetings
I have a problem with locating .pst files. **
The task
** is to find all .pst files on a machine and create a list of them.
I tried to use Registry entry: "HKCU\Software\Microsoft\Office\%OfficeVersion%\Outlook\Search\Catalog". Looks like it contains list of all .pst & .ost files, but turned out it also has entries of deleted(or moved) files and it updates only if you connect .pst manually in Outlook. So if you move your old .pst in some kind of "Archive" my registry will not contain info about it.
I understand that looking through all files takes too much time, so I want to avoid that.
Also, keep in mind that user might have a lot of mailboxes and a lot of .pst(some of them might not even be connected to Outlook at all). And I can't use such things as Redemption or anything. Just plain C#(may be some C++ MAPI lib)
Thanks a lot.
The PST file locations is stored in the profile sections in the registry. The officially supported API designed to access and manipulate the profile data is the IProfAdmin interface (you can play with it in OutlookSpy (I am its author) if you click the IProfAdmin button). PST path is stored in the PR_PST_PATH property. Extended MAPI can only be accessed from C++ or Delphi.
The profile data is stored in the registry, so in theory you could read the data from the registry, but the key names are profile specific and are generated randomly (profile section name is a guid). Also note that the profile data location in the registry is Outlook version specific.
You can use ProfMan (it comes with the distributable version of Redemption); ProfMan can be used from any language. The following script (VB) retrieves PST files names from all local profiles:
'Print the path to all the PST files in all profiles
PR_PST_PATH = &H6700001E
set Profiles=CreateObject("ProfMan.Profiles")
for i = 1 to Profiles.Count
set Profile = Profiles.Item(i)
set Services = Profile.Services
Debug.Print "------ Profile: " & Profile.Name & " ------"
for j = 1 to Services.Count
set Service = Services.Item(j)
If (Service.ServiceName = "MSPST MS") or (Service.ServiceName = "MSUPST MS") Then
MsgBox Service.Providers.Item(1).ProfSect.Item(PR_PST_PATH)
End If
next
next
You can also retrieve PST file names from PST stores using the Outlook Object Model (but that requires Outlook to be running, and you can only do that for the currently used profile) - use the Store.FilePath property:
set vApp = CreateObject("Outlook.Application")
for each vStore in vApp.Session.Stores
MsgBox vStore.DisplayName & " - " & vStore.FilePath
next
Related
Im trying to get the Users/Shared folder location in Mac so that i can write common user data(license) to it.I tried using
System.IO.Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.CommonApplicationData));
But its returning the folder in which I'm logged in.I know that i need to place the common application data in the Application Support folder but i think root privilege is required for this.If there is a better way to write to that folder,please suggest.
UPDATE:
I tried doing
File.Copy ("myfile.rtf", "Users//Shared//ll.txt");
But i get this exception >> Destination directory not found: Users/Shared
In OS X the directory is simply /Users/Shared, and it's directly off the root of the volume. There's no need to do Environment.GetFolderPath...
If you want to have user data or application data that can be shared by multiple users (read+write) you'll either want to create your own directory:
/Users/Shared/MyApp
and/or you can use:
/Users/Shared/Library/Application Support/MyApp
This way your application can share user data and application settings with all users. The /Library/Application Support folder (not to be confused with the one shared one), is owned by the system and anything that needs to write to it must obtain permission. The contents are read only, even for admin level users — something you'll want to consider when deciding where to store shared application data.
Situation: OneDrive for Business syncs files from Sharepoint Site Document Library to local directory:
C:\Users\users\Sharepoint\Library\Test.pttx
However with PowerPoint InterOp the:
presentation.Path
Is:
https://company.sharepoint.com/Library/Shared%20Documents/
Which is the correct path for Sharepoint.
How can I access the local directory?
Update: I found a similar question on MSDN but no answer
According to this post, the synced folders can be looked up in this multi-string registry value:
HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Common
\Internet\LocalSyncClientDiskLocation
Given that your local path and SharePoint URL look like
C:\Users\User\SharePoint\Library - Documents\Folder\SubFolder\Document.pptx and
https://***.sharepoint.com/Library/Shared%20Documents/Folder/SubFolder/Document.pptx,
you could try extracting the local part Folder/SubFolder/Document.pptx from the URL, add it to the local folder paths retrieved from the registry value and check for file existence.
If I understand correctly you want a way in Powerpoint (VSTO) to get the local path of the Sync'd directory? A method in the Powerpoint Object Model like presentation.GetLocalPath()?
I dont know why (in the MSDN link in your question) the MSFT CSG engineer said that it was impossible.
Sorry for the mistake, after the further investigation, it is
impossble. For the Word Application, the file is stored on the
OneDrive, and the "Offline" is cache mode for OneDrive, it is
transparent to Word Application (Word Application only know it is a
document on OneDrive), so when you check the location of the opened
document, the location is "http:/d.docs.live.net/xxxx/xx.docx" rather
than "C:\XXX\XXX".
This article shows you how you can Change the location where you sync SharePoint libraries on your computer. Obviously there isn't a method in the Powerpoint Interop Library but its definitely possible.
1) My first thought was to see if the OneDrive for Business sync app wizard saves any registry key or anything like that (using ProcessMonitor) but it probably stores the local directory in the cloud.
2) My second thought is a bit outside the box, just put a text file in https://company.sharepoint.com/Library/Shared%20Documents/LocalDrivePath.txt, then create an Extension method called presentation.GetLocalPath() and use the WebClient class to download the string.
Pseudo code:
public string GetLocalPath(this Microsoft.Office.Interop.PowerPoint.Presentation presentation)
{
WebClient client = new WebClient();
string localPath = client.DownloadString(presentation.Path + "LocalDrivePath.txt");
//Some good old protective programming to quickly identify the problem if the file doesn't exist
if (!string.IsNullOrEmpty(localPath)) throw new Exception("Issue: LocalDrivePath.txt not found in " + presentation.Path + Environment.Newline + "Please add the file for this Office Documents' sync'd (offline) local folder to be identified.");
return localPath;
}
Call it like so:
presentation.GetLocalPath();
I have my project files on my Dropbox folder so I can play around with my files at the office as well.
My project contains an EmbeddableDocumentStore with UseEmbeddedHttpServer set to true.
const int ravenPort = 8181;
NonAdminHttp.EnsureCanListenToWhenInNonAdminContext(ravenPort);
var ds = new EmbeddableDocumentStore {
DataDirectory = "Data",
UseEmbeddedHttpServer = true,
Configuration = { Port = ravenPort }
};
Now, this day when I started my project on my office pc I saw this message: Could not open transactional storage: D:\Dropbox\...\Data
Since it's early in my development stage I deleted the data folder on my Dropbox and the project started flawlessly. Now I'm back at home I ran into the same issue! I don't want to end up deleting this folder every time of course.
Can't I store my development data on my Dropbox? Should I bypass something to get this to work?
Set a data directory to a physical disk volume on your local computer. You will not be able to use any sort of mapped drive, network share, UNC path, dropbox or skydrive as a data directory. Just because you have a drive letter does not mean you have a physical disk.
The only types of non-physical storage that even make sense is a LUN attached from a SAN over iSCSI or FibreChannel, or an attached VHD in a virtualized or cloud environment. They will all present as physical disks to the OS.
This would be the case for just about ANY data access environment. Try it with SQL Server if you don't believe me. In RavenDB's case, it is using ESENT as its data store, which requires direct access to the filesystem.
Update
To clarify, even if you are storing on a physical disk, you can't rely on any type of synchronization technology like DropBox or SkyDrive. Why? Because they will be taking a shared read lock on the files to watch for changes. Technologies like ESENT (which RavenDB is based upon) require an exclusive lock to the file.
Other technologies like SQL Server and Windows Virtual Machine also take exclusive locks on their data stores. Why? Because they are constantly reading and writing bits of data in a random-access manner to the file. Would you really want DropBox to be trying to perform an sync operation for every bit of data change? It would be very inefficient and problematic.
Applications that use shared locks don't have this problem. For example, when you work on an MS Word document, it is all being done in memory. When you save the file, DropBox can read the entire file and sync it to the cloud. It can optimize by sending only the bits that have changed, but it still needs to be able to read the file to do so.
So if DropBox has a shared read lock on the ESENT file, then when RavenDB tries to open it exclusively, it gets an error and raises the exception you are seeing.
I’m converting an existing piece of code using Redemption (an MS Exchange library) to operate under a service account. The issue I’m having is that I’m unable to look up mail folders as I previously was.
The first hurdle in moving to a service account was overcome by switching
_rdoSession.Logon() // <- Which uses the account’s MAPI profile, and throws an exception under a service account
To:
_rdoSession.LogonExchangeMailbox("", "mailserver.example.com");
The problem comes with trying to access specific folders. Previously I was able to use:
_session.GetFolderFromPath("\\\\Mailbox - Example shared mailbox\\Inbox\\FolderOne");
_session.GetFolderFromPath("\\\\Mailbox - Example shared mailbox\\Inbox\\FolderTwo");
Under a service account, I can’t address shared mail accounts with that same syntax, as I get the error:
Could not open store "Mailbox – Example shared mailbox": Error in IMAPITable.FindRow: MAPI_E_NOT_FOUND
Some Googling has shown the beginning step is to use:
_session.Stores.GetSharedMailbox("Example shared mailbox ")
I've verified this returns the correct shared mailbox object.
However - from there, there are no search methods. I can try my luck with building new code to navigate the folder structure from the .RootFolder property, but this seems like a hack.
How should I be accessing specific folders in a shared mailbox, run under a service account in Redemption?
You can use either
store = _session.Stores.GetSharedMailbox("Example shared mailbox ");
folder = store.IPMRootFolder.Folders.Item("Inbox").Folders.Item("FolderTwo");
or
store = _session.Stores.GetSharedMailbox("Example shared mailbox ");
folder = store.GetDefaultFolder(olFolderInbox).Folders.Item("FolderTwo");
I am trying to make an Outlook 2003 add-in using Visual Studio 2008 on Windows XP SP3 and Internet Explorer 7.
My add-in is using custom Folder Home Page which displays my custom form, which wraps Outlook View Control.
I get COM Exception with 'Exception from HRESULT: 0xXXXXXXXX' description every time when I try to set Folder property of the OVC. Error code is a random number, every time is different. It is not the first access to control's properties, before that, View and ViewXML properties are set already. Control is marked as Safe for Scripting.
I am using value of the CurrentFolder.FolderPath property of the active explorer, which seems to be a right one:
Outlook.Explorer currentExplorer = app.ActiveExplorer();
if (currentExplorer != null)
{
ovcWrapper.Folder = currentExplorer.CurrentFolder.FolderPath;
}
This is top of the stack trace:
System.Runtime.InteropServices.COMException (0xXXXXXXXX): Exception from HRESULT: 0xXXXXXXXX
at Microsoft.Office.Interop.OutlookViewCtl.ViewCtlClass.set_Folder(String pVal)
at AxMicrosoft.Office.Interop.OutlookViewCtl.AxViewCtl.set_Folder(String value)..
This is happening only if the folder is located in non-default PST file. Changing to folder inside default PST file will produce no exception.
I must underline that everything worked just fine before I went to holiday :). It seems that Windows XP installed some updates which changed default security of Internet Explorer or Outlook 2003 while I was absent.
On the other (virtual machine) with Office 2007 and Internet Explorer 6, without any updates, everything is working just fine.
After a while, I finally find out what is the solution: change a name of the external storage to something new.
During startup of the addin, it loads the non-default PST file, and changes its name (not the name of the pst file, but the name of the root folder) to "Documents".
This is code:
session.AddStore("C:\\test.pst"); // loads existing or creates a new one, if there is none.
storage = session.Folders.GetLast(); // grabs root folder of the new fileStorage.
if (storage.Name != storageName) // if fileStorage is brand new, it has default name.
{
storage.Name = "Documents";
session.RemoveStore(storage); // to apply new fileStorage name, it have to be removed and added again.
session.AddStore(storagePath);
}
Solution is not to use 'Documents' as a name any more, but something new. Problem is not related to specific name.
Dobri Dan, nency :)I don't know if I can really offer a "silver bullet" solution given the information here...but here are a few ideas/notes to try out:Having worked with Outlook on a few projects in the past, I can tell you that it is a funny bird sometimes when it comes to giving/granting access to outside users/processes. It sometimes requires the user to manually confirm access or log in...so make certain that you have
app.Session.Logon()
taken care of somewhere.The other thing I notice is the use of app.ActiveExplorer() Make certain that this function is returning exactly what you think it is; It takes the topmost window on the user's desktop...which is usualyy but not always the window you are trying to work with, so just doublecheck.