locked
Change in behaviour of IVsSccProject2.GetSccFiles in Visual Studio 2010 RRS feed

  • Question

  • We have an issue in detecting files for source control.     Generated files such as _i.c _i.h should not be candidates.     The example source control integrations in the VS2008 SDK and VS2010 SDK both use IVsSccProject2.GetSccFiles and debugging these in VS2008 and VS2010 gives the following results.  I used a new ATL project in each case which contains "Generated Files" in Solution Explorer they are shown with the red circle / white bar "no entry" sign.   Properties in both versions of Visual Studio  sho SccFiles=False but in VS2010 the generated files appear as a result of using IVsSccProject2.GetSccFiles 

     

    Vs2008  result of GetProjectFiles in example SC provider

     

    -                              projectFiles        Count = 13          System.Collections.Generic.IList<string> {System.Collections.Generic.List<string>}

                                    [0]          "C:\\Users\\XXXX\\Documents\\Visual Studio 2008\\Projects\\atl2008\\atl2008\\atl2008.vcproj"           string

                                    [1]          "c:\\Users\\XXXX\\Documents\\Visual Studio 2008\\Projects\\atl2008\\atl2008\\ReadMe.txt"               string

                                    [2]          "c:\\Users\\XXXX\\Documents\\Visual Studio 2008\\Projects\\atl2008\\atl2008\\dllmain.h"     string

                                    [3]          "c:\\Users\\XXXX\\Documents\\Visual Studio 2008\\Projects\\atl2008\\atl2008\\Resource.h"                string

                                    [4]          "c:\\Users\\XXXX\\Documents\\Visual Studio 2008\\Projects\\atl2008\\atl2008\\stdafx.h"                string

                                    [5]          "c:\\Users\\XXXX\\Documents\\Visual Studio 2008\\Projects\\atl2008\\atl2008\\targetver.h"                string

                                    [6]          "c:\\Users\\XXXX\\Documents\\Visual Studio 2008\\Projects\\atl2008\\atl2008\\atl2008.rc"    string

                                    [7]          "c:\\Users\\XXXX\\Documents\\Visual Studio 2008\\Projects\\atl2008\\atl2008\\atl2008.rgs"  string

                                    [8]          "c:\\Users\\XXXX\\Documents\\Visual Studio 2008\\Projects\\atl2008\\atl2008\\atl2008.cpp"                string

                                    [9]          "c:\\Users\\XXXX\\Documents\\Visual Studio 2008\\Projects\\atl2008\\atl2008\\atl2008.def" string

                                    [10]        "c:\\Users\\XXXX\\Documents\\Visual Studio 2008\\Projects\\atl2008\\atl2008\\atl2008.idl"   string

                                    [11]        "c:\\Users\\XXXX\\Documents\\Visual Studio 2008\\Projects\\atl2008\\atl2008\\dllmain.cpp"                string

                                    [12]        "c:\\Users\\XXXX\\Documents\\Visual Studio 2008\\Projects\\atl2008\\atl2008\\stdafx.cpp"  string

    +                             Raw View                           

     

    VS2010 result from GetProjectFiles in example

     

    -                              projectFiles        Count = 16          System.Collections.Generic.IList<string> {System.Collections.Generic.List<string>}

                                    [0]          "C:\\Users\\XXXX\\documents\\visual studio 2010\\Projects\\atlxx\\atlxx\\atlxx.vcxproj"                string

                                    [1]          "C:\\Users\\XXXX\\documents\\visual studio 2010\\Projects\\atlxx\\atlxx\\atlxx.vcxproj.filters"          string

                                    [2]          "C:\\Users\\XXXX\\documents\\visual studio 2010\\Projects\\atlxx\\atlxx\\ReadMe.txt"                string

                                    [3]          "C:\\Users\\XXXX\\documents\\visual studio 2010\\Projects\\atlxx\\atlxx\\atlxx_i.c"                string

                                    [4]          "C:\\Users\\XXXX\\documents\\visual studio 2010\\Projects\\atlxx\\atlxx\\atlxx_i.h"                string

                                    [5]          "C:\\Users\\XXXX\\documents\\visual studio 2010\\Projects\\atlxx\\atlxx\\dllmain.h"                string

                                    [6]          "C:\\Users\\XXXX\\documents\\visual studio 2010\\Projects\\atlxx\\atlxx\\Resource.h"                string

                                    [7]          "C:\\Users\\XXXX\\documents\\visual studio 2010\\Projects\\atlxx\\atlxx\\stdafx.h"                string

                                    [8]          "C:\\Users\\XXXX\\documents\\visual studio 2010\\Projects\\atlxx\\atlxx\\targetver.h"                string

                                    [9]          "C:\\Users\\XXXX\\documents\\visual studio 2010\\Projects\\atlxx\\atlxx\\atlxx.rc"                string

                                    [10]        "C:\\Users\\XXXX\\documents\\visual studio 2010\\Projects\\atlxx\\atlxx\\atlxx.rgs"                string

                                    [11]        "C:\\Users\\XXXX\\documents\\visual studio 2010\\Projects\\atlxx\\atlxx\\atlxx.cpp"                string

                                    [12]        "C:\\Users\\XXXX\\documents\\visual studio 2010\\Projects\\atlxx\\atlxx\\atlxx.def"                string

                                    [13]        "C:\\Users\\XXXX\\documents\\visual studio 2010\\Projects\\atlxx\\atlxx\\atlxx.idl"                string

                                    [14]        "C:\\Users\\XXXX\\documents\\visual studio 2010\\Projects\\atlxx\\atlxx\\dllmain.cpp"                string

                                    [15]        "C:\\Users\\XXXX\\documents\\visual studio 2010\\Projects\\atlxx\\atlxx\\stdafx.cpp"                string

    What is required to stop these appearing under Visual Studio 2010 - there does not appear to be any obvious method from the SDK documentation and GetSccFiles is only supposed to return candidates for source control.

    Thanks in advance

    Tuesday, February 1, 2011 10:54 AM

Answers

  • Someone in VC (Olga?) should confirm if this is the case for the 2 atlxx files, but as far as I remember for ATL projects, VC used to return from GetSccFiles()/GetSccSpecialFiles() items that were build outputs (like xxxxx_i.c and xxxxx_i.h that resulted from compiling idl files). Then, to make sure those files did not end up in scc database, it then called DTE2.SourceControl2.ExcludeItem/ExcludeItems when the project was opened.

    If I'm right and VC does the same for the 2 files you're asking about, your scc provider should implement the SourceControl/SourceControl2 interface (http://msdn.microsoft.com/en-us/library/envdte80.sourcecontrol2(VS.80).aspx) on the class that exposes scci interfaces like IVsSccManager2, IVsSccGlyphs, IVsQueryEditQuerySave, etc. Accumulate the files you are called with to be excluded from source control, and use those lists of excluded files in scc operations (after you accumulate controllable files by iterating the project's hierarchy with GetSccFiles/GetSccSpecialFiles, exclude from those files the files that are excluded from source control).

    You should also implement UndoExcludeItem/UndoExcludeItems on the same DTE2.SourceControl2 interface in case projects call you to include back in source control some of the items that may be excluded before.

    Alin

    • Marked as answer by bs1958 Monday, February 7, 2011 8:40 AM
    Thursday, February 3, 2011 7:03 PM

All replies

  • What is your source control provider?  The shell itself doesn't implement IVsSccProject2 as far as I know, I believe it would be the specific source control bindings (i.e. TFS, Subversion, Git, etc...) that are responsible for this, though if it is one we own (like TFS, or SourceSafe) I can point someone from that team to this thread for more info.

    Ryan

    Tuesday, February 1, 2011 6:41 PM
  • Thanks Ryan

    The source control provider is our own.    I believe IVsSccProject2 is implemented by the project system and in VS2010 it returns Generated Files in VC++ projects as if they were controllable files.    These are shown in solution explorer under a Filter "Generated Files" which in the VC++ ATL project has a property "SCC Files" set to "false".   Based on this we would expect GetSccFiles implemented by the new VC++ project system in VS2010 to not return filenames for these files.   In the documentation for GetSccFiles "This method is called to determine which files should be placed under source control for a given VSITEMID within this hierarchy".   It gets the filename(s) and flag(s) for a VSITEMID passed in.   In the example SourceControl Providers the code traverses the hierarchy calling GetSccFiles to see if the item id represents a file that should be placed under source control  and if that file has "special" files - code behind / .designer.cs etc.  Both the VS2008 and VS2010 Sample SC providers implement similar approaches but in the VS2008 no filename is produced for the vsitemid representing the "Generated" files so it is not added as a candidate for control.   In VS2010 it does get a filename filled in for the Generated Files.   This causes issues with readonly controlled files that will be regenerated.   I noted that in the VS2010 MSSCCI provider they are not considered for Source Control.   It would be appreciated if  you could pass this question on to someone either in th VC++ project or Source Control area.

       

    Tuesday, February 1, 2011 7:40 PM
  • Hmm, looks like we have a bug there. To workaround you can use vc project engine interfaces (interop assembly Microsoft.VisualStudio.VCProjectEngine.dll). If you are walking a project hierarchy check if a node is a filter (VCFilter) and if it has SourceControlFiles property set to false skip its children. If you just have a file node you need to find if it has a filter parent (or grandparent) node and check it.

    To get a vc object interface (VCFile, VCFilter, etc) from IVSHierarchy you need to call something like this (not sure about syntax):

    vsHierarchy.GetProperty(vsitemid, VSHPROPID_ExtObject).Object as VCFile

    Hope this helps.

    Olga 

    Wednesday, February 2, 2011 6:50 PM
  • Thanks Olga

    Do you know if this approach will work for a common codebase that works with VS2005/8 or is it specific to VS2010.

    Wednesday, February 2, 2011 7:03 PM
  • Well, logically it should. But the interfaces (VCFile, VCFilter, etc) were reguided (for some reason vc automation never supported backward compat) so you'll have to use different interop there.

    I also just found that the Dev10 change causing you the troble was made to fix some other SCC related problems, so it might be a different way to deal with it. I'll try to find people who have more context there.

     

    Wednesday, February 2, 2011 7:20 PM
  • Thanks for the quick response - we need to review our implementation and see what we can do.  I look forward to any more information/assistance with this issue.
    Wednesday, February 2, 2011 7:24 PM
  • OK,  here is an advice I've got: looks like Dev10 VC projects return all project items from GetSccFiles(), but make extra calls into the scc provider on ExcludeItem/UndoExcludeItem, which scc provider supposed to be paying attention to when accumulating project files with GetSccFiles/GetSccSpecialFiles. Check if your scc provider does that. If not, implementing that would be a better fix for the problem.

    Olga

     

    Wednesday, February 2, 2011 9:43 PM
  • Thanks for the advice.   Is it possible to let us know the particular Interface and method that will be called.    The ExcludeItem/UndoExclude item are methods to call on the project to exclude / unexclude files from source control.     From what you are saying the source control package will receive a call when this happens.  Will this hold for existing projects or only when the Exclude/UndoExclude methods are called either from the UI or programmatically.  I cannot immediately see what method gives us this information.   Are there any code samples that you could provide that would show how to accomplish this.   
    Thursday, February 3, 2011 9:23 AM
  • Someone in VC (Olga?) should confirm if this is the case for the 2 atlxx files, but as far as I remember for ATL projects, VC used to return from GetSccFiles()/GetSccSpecialFiles() items that were build outputs (like xxxxx_i.c and xxxxx_i.h that resulted from compiling idl files). Then, to make sure those files did not end up in scc database, it then called DTE2.SourceControl2.ExcludeItem/ExcludeItems when the project was opened.

    If I'm right and VC does the same for the 2 files you're asking about, your scc provider should implement the SourceControl/SourceControl2 interface (http://msdn.microsoft.com/en-us/library/envdte80.sourcecontrol2(VS.80).aspx) on the class that exposes scci interfaces like IVsSccManager2, IVsSccGlyphs, IVsQueryEditQuerySave, etc. Accumulate the files you are called with to be excluded from source control, and use those lists of excluded files in scc operations (after you accumulate controllable files by iterating the project's hierarchy with GetSccFiles/GetSccSpecialFiles, exclude from those files the files that are excluded from source control).

    You should also implement UndoExcludeItem/UndoExcludeItems on the same DTE2.SourceControl2 interface in case projects call you to include back in source control some of the items that may be excluded before.

    Alin

    • Marked as answer by bs1958 Monday, February 7, 2011 8:40 AM
    Thursday, February 3, 2011 7:03 PM
  • Thanks Alin

    Our Source Control Provider implements  the IVsSccManager2 interface and the other interfaces  but there is nothing here that tells us that files are excluded from source control.  

    The issue we have is that VS2008 and  did not return the generated files the _i.c / _i.h did not appear in the list produced using hierarchy traversal and the GetSccFiles - you can see this using the VS2008 sample SccProvider, debugging it with an ATL project loaded and  looking at the return from

     

    public IList<string> GetProjectFiles(IVsSccProject2 pscp2Project, uint startItemId)

    This traverses the hierarchy and then calls GetSccFiles / GetSccSpecial files if GetSccFiles flagged the presence of special files.   The VS2010 sample does return them from the equivalent method and as has been said this is a change in behaviour in VS2010.  We had to do nothing special in VS2008 to ignore  these files as they never appeared in our lists of files  to operate on.    Our code is similar to the sample in traversing the hierarchy then calling GetSccFiles on the itemids derived from the traversal.     

    So we have to implement DTE.SourceControl2 interface ourselves and accumulate files that the environment calls us on with ExcludeItem(s) /UndoExcludeItem(s).    Do you think it would be possible to add this into the sample Source Control package to test the solution.  

       

    Thursday, February 3, 2011 7:57 PM
  • >The issue we have is that VS2008 and  did not return the generated files the _i.c / _i.h did not appear in the list produced using hierarchy traversal and the GetSccFiles 

    Yes, this change in behavior was to fix a bug.

    >So we have to implement DTE.SourceControl2 interface ourselves and accumulate files that the environment calls us on with ExcludeItem(s) /UndoExcludeItem(s).

    It sounds like that is the proper technique.

    >Do you think it would be possible to add this into the sample Source Control package to test the solution.  

    I can certainly file a bug, but most people are rather heads down on Dev11 at the moment, so I don't know how quickly the sample will be updated.

    Ryan

     

    Monday, February 7, 2011 8:35 PM
  • Thanks Ryan - I think the documentation for GetSccFiles "This method is called to determine which files should be placed under source control for a given VSITEMID within this hierarchy"  may need clarification.   As it  now considers "Excluded" items as candidates for source control which are files that should not be put under source control.  It discusses using GetSccSpecialFiles to get any associated special files but not that it now needs to be filtered using the SourceContol2.ExcludeItem(s) aproach. 

    As to the sample code  - this was more of a question as to the possibility of implementing this solution here to test it.   I have tried the approach as a proof of concept and by filtering the return list from GetProjectFiles can exclude the "Generated Files" from being added to source control using the Sample provider. 

     

    Monday, February 7, 2011 8:48 PM
  • The sample you're talking about is something I wrote back in 2005.

    It doesn't deal with many cases:

    - files excluded from source control (either by the user or implicitly via DTE by ATL C++ projects)

    - web projects with enlistment choice and folder-based websites

    - FrontPage web projects

    - project migration/conversions when opening a project created by older VS versions, and preserving the scci connection (web projects do a change like this almost with every VS version, VC projects changed extensions from vcproj->vcxproj)

    - delay instantiating projects, etc, etc.

    The sample only provided a basic way to get you started implementing an scci provider, from there it's up to you to support all these cases if you went through the path of creating full-integration with VS instead of implemeting a MSSCCI provider... We'll contact the team that owns now the samples, but I wouldn't raise my hopes someone will add this kind of functionality in the samples.

    Alin

    Monday, February 7, 2011 9:00 PM
  • The documentation for GetSccFiles() is correct. It returns what the project "thinks" there should be placed under scci for a specific node. There are similar files returned from GetSccSpecialFiles().

    What the provider does with this (and what eventually ends up in the scci database) depends ultimately on the provider - on the capabilities and the features supported.

    E.g. a provider like SourceSafe won't be able to add to the scci database files with '$' in the name, even if the projects wants to control them and returns them from GetSccFiles.

    Speaking of excluded items, functions like DTE.SourceControl.ExcludeItems can be invoked by the user (e.g. via macros), so you need to account for that. It's just a convenience for VC ATL that they chose to reuse this mechanism to exclude from scci project outputs that are also part of the project (like the _i.h files) - they have been doing this at least since 2005. The provider may also have it's own methods of excluding items (e.g. MSSCCI Host allows it via File/SourceControl/ExcludeFromSourceControl). You will also need to consider whether the same file linked by 2 projects in the same solution (and excluded from scci only in/by one of the projects) really ends up in the scci database or not. For instance, MSSCCI Host uses "master exclusion lists" per-solution, and a file is considered excluded if it's excluded by any of the projects in the solution. Your scc provider could generalize and store per-machine exclusion lists, etc.

    Alin

    Monday, February 7, 2011 9:17 PM
  • Hi all, Thanks for the information but i tried to implement the solution proposed but i could not fix the problem. I am also searching for the same problem for long time to support 2010 studio. If i am correct the answer you proposed is to implement DTE80.Sourcecontrol2 interface and have a skip list in ExcludeItem function. I tried it but it is just a skip list but how to identify the dynamically generated files in Visual studio 2010 ? The behaviour of IVsSccProject2.GetSccFiles is to get the list of files that can be added to source control(Excluding dynamic file). But here in VS2010 this is changed and we are getting dynamically generated files of Midl. Can any one suggest the way to identify the file in the solution explorer is a dynamic file or not so that based on that we can have the Excludeitem. With regards Sundar
    Tuesday, April 5, 2011 1:10 PM