none
ViewKind Parameter Ignored in ProjectItem.Open if ProjectItem is Set to Open With Default External Editor RRS feed

  • Question

  • Hi all,

    In my VS2010 extension, I have just encountered a situation which I can find no workaround for. As always, I went to Carlos Quintero's MZ-Tools first to see if I could find an answer. In this excellent article of his (http://www.mztools.com/articles/2007/mz2007027.aspx), he discusses how to get "the ProjectItem in the desired view using ProjectItem.Open(viewKind), which returns an EnvDTE.Window object."

    This is the behavior I have experienced until I noticed that if a user selects "Open With..." and sets a default external program to open a given item with, I can no longer programmatically open the item in the text editor (this is required functionality for my extension, since I am not setting the Window to visible, anyway). The screenshot below illustrates my point, even though I am working with my own custom extensions.

    Open With External Default Application

    In this case, calling ProjectItem.Open with every available ViewKind value will cause Program.cs to open in Notepad rather than the text editor. The Window returned from the Open call is always null in this case.

    Is there any way I can force an item to open in the text editor, regardless what its default program/viewer is? Thanks for your help,

    -Mike

    Tuesday, January 6, 2015 5:17 PM

Answers

  • I don't think that is a bug but a limitation of the automation model.

    As workaround, you can use the following method:

    IVsUIShellOpenDocument.OpenSpecificEditor

    If you want something somewhat more palatable you can use the following method:

    VsShellUtilities.OpenDocumentWithSpecificEditor

    Editor guids are stored in the registry entry HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\12.0_Config\Editors, but since you are only interested in the text editor guid, you are lucky because there is already a constant defined Microsoft.VisualStudio.VSConstants.GUID_TextEditorFactory. There is also a constant defined for the logical view: Microsoft.VisualStudio.VSConstants.LOGVIEWID.TextView_guid.

    So, even if text files are set to open with Notepad, this code should open them in the text editor:

             string fullPath;

             Guid editorGuid;
             Guid logicalViewGuid;

             IVsWindowFrame windowFrame;

             fullPath = projectItem.get_FileNames(0);

             editorGuid = Microsoft.VisualStudio.VSConstants.GUID_TextEditorFactory;
             logicalViewGuid = Microsoft.VisualStudio.VSConstants.LOGVIEWID.TextView_guid;

             windowFrame = Microsoft.VisualStudio.Shell.VsShellUtilities.OpenDocumentWithSpecificEditor(this, fullPath, editorGuid, logicalViewGuid);

             if (windowFrame != null)
             {
                windowFrame.Show();
             }
          }


    * My new blog about VSX: http://www.visualstudioextensibility.com * Twitter: https://twitter.com/VSExtensibility * MZ-Tools productivity extension for Visual Studio: http://www.mztools.com.

    Monday, January 26, 2015 3:55 PM
    Moderator

All replies

  • Hi Mike,

    Could you please post your code which opens the Program.cs file? I can't reproduce your problem, I use this code snippet in a VSPackage project, it properly opens the specified ProjectItem with the specified view, even I set a default open view for the ProjectItem. The only thing I need to take note of is that after calling the Open method, I have to set the Visible property to true so that I can see it.

    DTE2 dte = GetService(typeof(SDTE)) as DTE2;
                foreach (Project p in dte.Solution.Projects)
                {
                    foreach (ProjectItem item in p.ProjectItems)
                    {
                        if (item.Name == "Program.cs")
                        {
                            Window window = item.Open(EnvDTE.Constants.vsViewKindCode);
                            window.Visible = true;
                        }
                    }
                }
    I'm using VS2012 on Windows 8 x64.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    • Marked as answer by miesch1 Saturday, January 24, 2015 4:51 AM
    • Unmarked as answer by miesch1 Thursday, March 12, 2015 4:44 PM
    Thursday, January 8, 2015 2:38 AM
    Moderator
  • Caillen,

    Thanks for your response! I guess I oversimplified my scenario and didn't properly test the use case I originally described. You are correct, I verified that a code-type ProjectItem ("Program.cs" in this case) opens correctly in the text editor.

    That made me did deeper to try to isolate my problem. What I am seeing is that non-code files are the culprit here. I can only get code files (.cs, .xaml, etc.) using the vsViewKindCode value to open in the code/text editor. The moment I go to a non-code file the default application will be launched, even when using the other viewKind values. From Carlos' post above, vsViewKindTextView seems to be the correct value to use.

    Expanding on your example, if you add a TextFile1.txt item to your project and configure it to "Open With..." Notepad by default, you should see Notepad get launched when you execute the following code:

    DTE2 dte = GetService(typeof(SDTE)) as DTE2;
    foreach (Project p in dte.Solution.Projects)
    {
        foreach (ProjectItem item in p.ProjectItems)
        {
            Window window;
            if (item.Name == "Program.cs")
            {
                window = item.Open(EnvDTE.Constants.vsViewKindCode);
                window.Visible = true;
            }
            else if (item.Name == "TextFile1.txt")
            {
                // Opens in Notepad and window is null.
                window = item.Open(EnvDTE.Constants.vsViewKindCode);
    
                // Opens in Notepad and window is null.
                window = item.Open(EnvDTE.Constants.vsViewKindTextView);
            }
        }
    }

    Any ideas on how to force TextFile1 to open in the proper text editor? Thanks again,

    -Mike


    • Edited by miesch1 Thursday, January 8, 2015 11:47 PM Minor style updates.
    Thursday, January 8, 2015 11:45 PM
  • Hi miesch1,

    Happy New Year!

    I think it should be a bug, I've reproduced your problem. you could submit a feedback in Microsoft Connect here:

    https://connect.microsoft.com/VisualStudio


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    Tuesday, January 13, 2015 9:59 AM
    Moderator
  • Hi Caillen,

    Thanks for taking time to reproduce this for me. I have submitted a bug for this issue here for those who stumble on this:

    https://connect.microsoft.com/VisualStudio/feedback/details/1099248/envdte-projectitem-open-will-not-open-non-code-files-in-the-text-editor-if-file-set-to-open-with-an-external-program


    • Edited by miesch1 Saturday, January 24, 2015 4:50 AM hyperlink
    Saturday, January 24, 2015 4:50 AM
  • I don't think that is a bug but a limitation of the automation model.

    As workaround, you can use the following method:

    IVsUIShellOpenDocument.OpenSpecificEditor

    If you want something somewhat more palatable you can use the following method:

    VsShellUtilities.OpenDocumentWithSpecificEditor

    Editor guids are stored in the registry entry HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\12.0_Config\Editors, but since you are only interested in the text editor guid, you are lucky because there is already a constant defined Microsoft.VisualStudio.VSConstants.GUID_TextEditorFactory. There is also a constant defined for the logical view: Microsoft.VisualStudio.VSConstants.LOGVIEWID.TextView_guid.

    So, even if text files are set to open with Notepad, this code should open them in the text editor:

             string fullPath;

             Guid editorGuid;
             Guid logicalViewGuid;

             IVsWindowFrame windowFrame;

             fullPath = projectItem.get_FileNames(0);

             editorGuid = Microsoft.VisualStudio.VSConstants.GUID_TextEditorFactory;
             logicalViewGuid = Microsoft.VisualStudio.VSConstants.LOGVIEWID.TextView_guid;

             windowFrame = Microsoft.VisualStudio.Shell.VsShellUtilities.OpenDocumentWithSpecificEditor(this, fullPath, editorGuid, logicalViewGuid);

             if (windowFrame != null)
             {
                windowFrame.Show();
             }
          }


    * My new blog about VSX: http://www.visualstudioextensibility.com * Twitter: https://twitter.com/VSExtensibility * MZ-Tools productivity extension for Visual Studio: http://www.mztools.com.

    Monday, January 26, 2015 3:55 PM
    Moderator
  • Yes!

    You are the man Carlos. Sorry for the delay, I am just getting back around to this issue. I knew there had to be a way. Thanks again,

    -Mike

    Thursday, March 12, 2015 4:42 PM