none
VSTO Add-in cannot open file in non-shared location RRS feed

  • Question

  • I have a problem opening files using a PowerPoint VSTO add-in. (PowerPoint 2010, VS 2010, running on Windows 7) When I run the code below, the "if" branch triggers - the file cannot be found. If I comment out the "if", the Presentations.Open method errors with "Powerpoint cannot open the file". The file does exist and the file path is correct; if I use the file path in a PowerPoint VBA macro it works fine.

    But in the VSTO add-in it only works if I specify a file path that's in a publicly Shared folder (the line commented out).

    This problem occurs in both debug mode and when I Publish and install the add-in. It makes no difference whether the PowerPoint file is a *.potx or a *.pptx

            private void btnNewPatternSatz_Click(object sender, EventArgs e)
            {
                string fileName = String.Format("{0}{1}", filePath, "\\TrailPatterns.potx");
                //string fileName = @"C:\SharedFolder\TrailPatterns.potx";
                if (!System.IO.File.Exists(fileName))
                {
                    MessageBox.Show(String.Format("{0} could not be found.", fileName));
                    return;
                }
                PowerPoint.Presentation p = pptApp.Presentations.Open(fileName, offFalse, offTrue, offTrue);
                PowerPoint.CustomLayout cl = p.Designs[1].SlideMaster.CustomLayouts[1];           
                PowerPoint.Slide s = p.Slides.AddSlide(1, cl);
                if (s.Layout != PowerPoint.PpSlideLayout.ppLayoutBlank)
                    s.Layout = PowerPoint.PpSlideLayout.ppLayoutBlank;
                p.ApplyTemplate(fileName);
            }
    
    What do I have to do in order to be able to open a PowerPoint file from my add-in?

    Cindy Meister, VSTO/Word MVP, my blog

    Monday, November 19, 2012 9:40 AM
    Moderator

Answers

  • Hi Cindy :)
     
    Assembly.GetExecutingAssembly().CodeBase is good because it works with Windows Shadow Copy.
     
    Below is the kind of thing I use to construct a file path, I'm not it's any better than your way but it's always worked for me:

    //use CodeBase instead of Location because of Shadow Copy.

    UriBuilder vUri = new UriBuilder(Assembly.GetExecutingAssembly().CodeBase);

    string vPath = Uri.UnescapeDataString(vUri.Path + vUri.Fragment);

    string directory = Path.GetDirectoryName(vPath);

    string DllLocation = Path.Combine(directory, "myFile.dll");

    That would return something like this for a dll installed with my addin:

    "C:\\Program Files\\OfficeAddin\\myFile.dll"

    --
    Ken Slovak
    [MVP-Outlook]
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
    "Cindy Meister MVP" <=?utf-8?B?Q2luZHkgTWVpc3RlciBNVlA=?=> wrote in message news:1c3c81e2-4ca0-492e-8e53-02ca5569559f...

    Hi Damian / all

    I've tracked it down - sort of. There's still a mystery...

    Thank you for keeping after me about the files' existence. In the section that was working yesterday I found a logical error (the <thunk> kind), but have no idea how it slipped in.

    Concerning *.potx the problem is here:

      string fileName = String.Format("{0}{1}", filePath, \\TrailPatterns.potx);

    filePath is determined using:

    string filePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().CodeBase);

    Which is returning the path with this in front of it: "file:\\"

    This is NOT causing a problem with the graphics files (where the logical error was), but IS causing a problem when trying to get the *.potx file. I can work around that by doing this:

    string fileName = String.Format("{0}{1}", filePath, "\\TrailPatterns.potx").Replace("file:\\", "");
    But I would very much like to know why it works in once case, but not in another. And what would be the "better" way to get the path..

    Cindy Meister, VSTO/Word MVP, my blog


    Ken Slovak MVP - Outlook
    Monday, November 19, 2012 7:20 PM
  • i assume that you verified that file really exists there on disk? please use process monitor to see what windows API returns from file access calls to that file.
    Monday, November 19, 2012 10:16 AM
  • from what i remember frameworks like log4net use following construct (and work with addins, asp.net, etc.):

    AppDomain.CurrentDomain.BaseDirectory

    Monday, November 19, 2012 7:43 PM
  • Hi Ken / Damian

    Thank you, both :-)

    AppDomain.CurrentDomain.BaseDirectory manages to return the information without file:\
    Path.Combine is of course much "better" than String.Format.

    It appears that PowerPointApplication.Presentations.Open does not accept a URI format for the path to a presentation, while Shapes.AddPicture does for picking up a graphic.

    Programming using the PowerPoint APIs is always a struggle <sigh>


    Cindy Meister, VSTO/Word MVP, my blog

    Tuesday, November 20, 2012 9:19 AM
    Moderator

All replies

  • Additional information:

    The Add-in is also no longer finding any files added to is as "content" (graphics files for insertion). These were working yesterday - I debugged intensively with no difficulties.

    And now it can also no longer access "shared folders", as it could a few minutes ago.

    I have tried shutting down and re-booting.

    Can an Add-in become "corrupt" in some way?


    Cindy Meister, VSTO/Word MVP, my blog

    Monday, November 19, 2012 10:13 AM
    Moderator
  • i assume that you verified that file really exists there on disk? please use process monitor to see what windows API returns from file access calls to that file.
    Monday, November 19, 2012 10:16 AM
  • Hi Damian

    Yes, the file exists. As I mentioned, VBA can perform the action with no problems. Also, as I mentioned, today the Add-in can't "find" graphics files with which it worked yesterday with no issues.

    <<please use process monitor to see what windows API returns from file access calls to that file>>

    Not too familiar with this, so please bear with me...

    I ran ProcMon with a filter targeting one folder where I copy "content" (graphics files) which were working yesterday, but not today. I can see the (very long) list where I press F5 - starting the Add-in in PowerPoint, then click a button which should insert such a graphic (which worked yesterday). I'm definitely seeing things that look like errors, but I'm not sure what's relevant and what's "to be expected".

    For example: FileSystemControl for the targeted file path "Invalid Device Request" with the detail FSCTL_LMR_QUERY_DEBUG_INFO. There are quite a number of these, surrounded by SUCCESS for QueryDirectory, CreateFile - QueryDirectory, CloseFile.

    Then we come to a block of SearchProtocolHost|FileSystemControl errors for NOT REPARSE POINT followed by BUFFER OVERFLOW with some Devicelo INVALID PARAMETER scattered in and surrounded by lots of SUCCESS.

    Then PowerPoint loads, with the add-in. Towards the end of this, I'm seeing a number of NAME NOT FOUND messages for HPPROFILER.dll in the Debug directory. (I have nothing with this name in my project -I don't know where it comes from, but I do have an HP printer...)

    Then comes another block of Windows Explorer with a similar pattern of INVALID DEVICE REQUEST and BUFFER OVERFLOW, surrounded by SUCCESS.

    At the end, we come to what must have happened when I requested a graphic be inserted. Category PowerPoint, starts with CreateFile NAME NOT FOUND for TrailPatterns.dll.config, followed by a slew of PATH NOT FOUND for TrailPatterns.resources.exe, ending with NAME INVALID for the graphics pattern I tried to insert.

    Then there are more NAME NOT FOUND [edit:continue] for TrailPatterns.dll.config, Microsoft.CSharp.dll, Microsoft.CSharp.exe, followed by PATH NOT FOUND for the same.

    At the very end, another block of Windows Explorer SUCCESS, NOT REPARSE POINT and INVALID PARAMETER messages in a similar pattern as before.

    Does this give you any clues where to attack the problem?


    Cindy Meister, VSTO/Word MVP, my blog


    Monday, November 19, 2012 11:45 AM
    Moderator
  • why is powerpoint looking for trailpatterns.dll and abouts? does this trailpatterns.potx that you try to load contain document level customization? if you open that potx file by double clicking on it from disk, does popwer point load it succesfully without any errors?
    Monday, November 19, 2012 1:04 PM
  • Hi Damian

    TrailPatterns is the name of the add-in, so that's the add-in DLL; the *.potx is a PowerPoint template I'm distributing with the add-in. And yes, PowerPoint (and PowerPoint VBA) can work with it just fine; double-clicking in Windows explorer works fine.

    The problem is only ocurring when a VSTO Add-in tries to work with any file saved to disk. (It loads Resource files loaded into PictureBox controls just fine.) But it worked yesterday.

    I've seen that a critical Windows update that targets VSTO was installed when I shut down, yesterday. Thinking that might be the problem, I tried a system Restore to the point before installation of the update. But that has not solved the problem.


    Cindy Meister, VSTO/Word MVP, my blog

    Monday, November 19, 2012 4:40 PM
    Moderator
  • Hi Damian / all

    I've tracked it down - sort of. There's still a mystery...

    Thank you for keeping after me about the files' existence. In the section that was working yesterday I found a logical error (the <thunk> kind), but have no idea how it slipped in.

    Concerning *.potx the problem is here:

      string fileName = String.Format("{0}{1}", filePath, \\TrailPatterns.potx);

    filePath is determined using:

    string filePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().CodeBase);

    Which is returning the path with this in front of it: "file:\\"

    This is NOT causing a problem with the graphics files (where the logical error was), but IS causing a problem when trying to get the *.potx file. I can work around that by doing this:

    string fileName = String.Format("{0}{1}", filePath, "\\TrailPatterns.potx").Replace("file:\\", "");
    But I would very much like to know why it works in once case, but not in another. And what would be the "better" way to get the path..

    Cindy Meister, VSTO/Word MVP, my blog

    Monday, November 19, 2012 5:21 PM
    Moderator
  • Hi Cindy :)
     
    Assembly.GetExecutingAssembly().CodeBase is good because it works with Windows Shadow Copy.
     
    Below is the kind of thing I use to construct a file path, I'm not it's any better than your way but it's always worked for me:

    //use CodeBase instead of Location because of Shadow Copy.

    UriBuilder vUri = new UriBuilder(Assembly.GetExecutingAssembly().CodeBase);

    string vPath = Uri.UnescapeDataString(vUri.Path + vUri.Fragment);

    string directory = Path.GetDirectoryName(vPath);

    string DllLocation = Path.Combine(directory, "myFile.dll");

    That would return something like this for a dll installed with my addin:

    "C:\\Program Files\\OfficeAddin\\myFile.dll"

    --
    Ken Slovak
    [MVP-Outlook]
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
    "Cindy Meister MVP" <=?utf-8?B?Q2luZHkgTWVpc3RlciBNVlA=?=> wrote in message news:1c3c81e2-4ca0-492e-8e53-02ca5569559f...

    Hi Damian / all

    I've tracked it down - sort of. There's still a mystery...

    Thank you for keeping after me about the files' existence. In the section that was working yesterday I found a logical error (the <thunk> kind), but have no idea how it slipped in.

    Concerning *.potx the problem is here:

      string fileName = String.Format("{0}{1}", filePath, \\TrailPatterns.potx);

    filePath is determined using:

    string filePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().CodeBase);

    Which is returning the path with this in front of it: "file:\\"

    This is NOT causing a problem with the graphics files (where the logical error was), but IS causing a problem when trying to get the *.potx file. I can work around that by doing this:

    string fileName = String.Format("{0}{1}", filePath, "\\TrailPatterns.potx").Replace("file:\\", "");
    But I would very much like to know why it works in once case, but not in another. And what would be the "better" way to get the path..

    Cindy Meister, VSTO/Word MVP, my blog


    Ken Slovak MVP - Outlook
    Monday, November 19, 2012 7:20 PM
  • from what i remember frameworks like log4net use following construct (and work with addins, asp.net, etc.):

    AppDomain.CurrentDomain.BaseDirectory

    Monday, November 19, 2012 7:43 PM
  • Hi Ken / Damian

    Thank you, both :-)

    AppDomain.CurrentDomain.BaseDirectory manages to return the information without file:\
    Path.Combine is of course much "better" than String.Format.

    It appears that PowerPointApplication.Presentations.Open does not accept a URI format for the path to a presentation, while Shapes.AddPicture does for picking up a graphic.

    Programming using the PowerPoint APIs is always a struggle <sigh>


    Cindy Meister, VSTO/Word MVP, my blog

    Tuesday, November 20, 2012 9:19 AM
    Moderator