Does it use modification timestamp or/and does it check whether the actual content has changed (e.g. by comparing the checksum)?
Edit: I need to know this since I use Git for source control and often change branches. It appears that sometimes even if I change the branch back and force (e.g. from develop to master and then back to develop), the VS rebuilds half of the sources files. I wonder why this happens and why does it happen sometimes and does not happen the other times.
Since Visual Studio is a closed-source project, I bet only developers would be able to give a definite answer on how exactly does it work. However, for my purposes it is enough to test some scenarios.
I have tested it with a small solution and a couple of files in it (one header and two source files). Test results bring to the following conclusion. Visual Studio looks for modification date and time. Even if the file content is the same - it compiles this file and also any other files that include it. If the modification date and time are the same - it won't recompile it even if the content is different. Visual Studio ignores creation and access dates and times.
I'm guessing it uses FileSystemWatcher on the project directories and linked files (if any), just because it's the right way to do this kind of thing.
Some googling finds for more about this class (or just look it up yourself):
http://www.techrepublic.com/article/use-the-net-filesystemwatcher-object-to-monitor-directory-changes-in-c/6165137
http://www.dotnetperls.com/filesystemwatcher
Of course when the source file is open, it's content by the time of editing, as wel as any user changes (even not saved) are loaded in the RAM, but it doesn't compare it to disk content (that'd be too slow), it listens to a system event when the system tells it the file changed.
Update:
Probably not that class itslf, but the Win32 version of it, you know most of the system related .NET functionality classes are just Win32 wrappers.
From this StackOverflow answer: How does FileSystemWatcher work on another computers directory?
I think it wraps this API (not sure): http://msdn.microsoft.com/en-us/library/aa365465.aspx
Update 2:
This is Microsoft's approach to monitor file changes:
http://msdn.microsoft.com/en-us/library/chzww271(v=vs.80).aspx
Update 3
This is an old answer, and it was mentioned above that it was a guess, as Visual Studio is closed source as mentioned in other answers. It's worth mentioning that the accepted answer suggests Visual Studio looks for file modification dates instead, which suggests it doesn't use the approach guessed in this very answer, and that it was wrong.
I hope the reader didn't mind the effort given to rationalize possibilities in this answer (causing reader discomfort or down votes). Keeping it for archival reason only.
Related
In most .NET project I can use folder to organise the code files. In C++, I can't, but filters end up playing the same role. However, in F# with Visual Studio 2010, I can't. Every code file is shown directly in the project dir. Why is this feature not available?
And what is the optimal strategy for organizing a project with a lot of files?
Actually, you can add folders to F# projects but it's not supported directly through Visual Studio (you have to edit the project file yourself): http://fsprojectextender.codeplex.com/ (edit: old link was broken, updated to F# Project Extender home page which has links to the original blog posts which were moved) (which I found in this answer).
I do this myself, but it is cumbersome and you end up avoiding it until keeping sanity really demands it. I think the feature simply slipped, or perhaps there wasn't as much a culture for folder organization with the F# designers in the first place. You can see in the F# source code that they favor huge source files with no directories, with separate projects as an organization boundary.
I imagine the F# project template could be modified to support this, and it is certainly something I'd like to see happen. At the same time the linear compilation order F# enforces causes your code to be somewhat self-organized, and so folder grouping plays a less significant role.
Manually editing the .fsproj file as described in Stephen's answer is one option (and I used it when I wanted to organize one larger project).
However, you have to be a bit careful and I think you cannot add new files to the folders (creating a file by hand and then adding an existing file works). However, if you like to keep things organized (like I do), then it should work for you.
Additionally, there is also a tool called F# Project Extender that should make things a bit easier for you . I have not tried it yet, but it looks like it supports adding folders (and perhaps other useful things). See for example this blog post by the project author.
Most of the time I am doing several distinct developments on the same project and, in order to have some logical separation between them, I use a personal version control system on a project (namely fossil but this is mabye too much detail).
This allows me to commit my work in different branches in order to merge them afterwards. Meanwhile I maintain a trunk branch in which I commit work by coworkers.
But when I switch from a branch to another one (in order to perform some merge action for instance) and go back to where I came from, Visual studio will detect timestamp modifications and rebuild files that have not really be modified.
Is there a way to ask Visual Studio to consider that a source file has changed when only some hash of its contents has changed?
As the answer seems to be “no” here is another way of achieving what I would like, for which I am starting a bounty. Still read the above please.
Do you know of a simple way to have a snapshot of the timestamps and MD5 hashes of my source files, and then, for every file of which the timestamp changed, compare MD5 and rollback timestamp modification if MD5 has not changed?
Thank you for your answers.
I'm afraid this is not really possible.
The issue here is that this is not just a thing for VS but actually for the entire build system which is quite separate from the actual IDE.
In order to decide if and .obj should be compiled, VS compares its timestamp to that of the source file. Doing what you suggest will require the .obj file to include the MD5 of the file. This also goes for .exe and .dll files. Changing the binary format of these files and unlikely to happen for such a rarely needed feature.
Edit - I take it back, this is probably is possible in theory. One way to go is to write a VS plugin. The plugin would save the MD5s to some file in the output directory and the just before the build starts will update the modified dates of the appropriate files.
Thinking further, this might be possible using a pre-build step..?
A simple workaround may be to write a script which looks at a file that Visual Studio isn't aware of and, if it has changed, copies it to overwrite the file that Visual Studio is aware of. The file Visual Studio sees is then excluded from source control, so it's timestamps shouldn't get touched.
The copying decision might be based on a hash, but it could just as easily compare the source and destination files directly.
Visual Studio definitely has the ability to include code generators in the build - which is what this script would be, in Visual Studios eyes. I don't know the details though - I get cmake to manage these things for me.
I've written a basic LanguageService extension for Visual Studio 2008 for my studio's proprietary scripting language. It works perfectly fine, and I've implemented a basic symbol table to keep track of script definitions and calls allowing for goto definition functionality.
The problem I've run into is that I only know how to parse the current active view, and I'd like to scan the entire solution's contents so that the user can goto the definition of a script defined in a file they have yet to open and have parsed. I've figured out how to generate a list of all files in the solution, but now I need to create a new Microsoft.VisualStudio.Package.Source which requires a Microsoft.VisualStudio.TextManager.Interop.IVsTextLines and I have no idea how to create a new one based off of the file I have.
Maybe I'm going about the problem the wrong way and someone can point me towards a better way to cause a file to be parsed by the LanguageService.
Regards,
Colin
Poking around I found that the reason Visual Studio needs a new Source is that it's keeping an internal list of them, and they're like the view into the text file held by the editor.
I came to the conclusion that files that are closed do not need IVsTextLines or to be entered into the VS internal list of Source files because I'm not doing any operations directly on them, all I care about in this case is to build a table of symbols and their corresponding TextSpan. So instead I created a new API for my parser that just took in a string and built my AST instead of grabbing the text from a ParseRequest, and only worried about specific types of symbols I needed to record. I then pushed this into a BackgroundWorker.
So I guess I was going about the problem in the wrong way. Although it does seem weird I can't just trigger a file to be opened into the Source list.
Interestingly I asked this question to Microsoft on their support forums and they advised me I had to purchase some service and support plan for them to answer my question.
I've got a relatively simple project that is under source control (svn), and I wanted to create an installer. I know that I could (should) use WiX, but as I'm new to creating installers I thought it'd be easier to just use the built-in Visual Studio (2010) Setup and Deployment Wizard.
Unfortunately, it seems that files including external (non-project maintained) documentation, configuration files, and "Content" files are added with absolute paths. This, of course, is suboptimal. I searched the web, but found only the same question, without an answer. Another stackoverflow user seems to have asked a similar question, but the only answer, which suggests ClickOnce, seems off-base (I'd like to have an MSI that I distribute not a web-based installation).
Does anyone know how (or whether) this can be fixed?
With VS2005, sometimes the paths stored in the vdproj file were absolutes, and sometimes relatives. In my case, it seemed to be related to whether the files were accessed via the canonical path or not. Here's a concrete example:
Source is on C:\Views\builddir, open solution C:\Views\builddir\solution.sln and add files from C:\Views\builddir\.. and VS2005 would add relative paths into the vdproj file. However, if you map that builddir to a letter drive, for example, make a subst from C:\Views\builddir to s:, open the solution via S:\solution.sln, and then add files by navigating to S:\.., VS2005 would insert absolute paths into the vdproj files. Whether VS2005 displayed paths as absolutes or relatives had no relation to what it stored in the vdproj files.
So, it may well be that the problem comes down to what path you're using to open that solution.. opening \\server\shareddir\solution.sln might get different behavior than mapping \\server\shareddir to W: and opening w:\solution.sln.
You can always add the files, then use a text editor (e.g. notepad) to change the absolute paths in the vdproj file to relative ones. You'll be fine until you change that project again.
MS doesn't seem to really fix minor bugs like this so much as rewrite the code to introduce an entirely different set of bugs, so VS2010 might still act this way.
FYI, why would one want to map an absolute path to your builddir? It was a holdover from the bad old days when VS didn't do anything correct with relative paths.
As tzerb mentioned, the main source of confusion might be that paths show up as absolute under the property window inside VS, but when you look into the actual VDPROJ file you should see the paths show up as relative. However, as patbob mentioned, I believe the paths ARE stored as absolute when they come from a different letter drive.
It might be easier now but when you start bumping into the limitations of the tool it's going to get real hard. Let's not even talk about the bad practices it will encourage which could end up being real hard for the poor end user installing your product. You've got Visual Studio 2010 so InstallShield LE ( free ) would be a better choice.
Otherwise, to answer your question, it will only use absolute paths if it can't caculate a relative path. ( for example c:\foo\foo.vdproj consuming d:\foo.txt consuming c:\test\foo.txt should automatically be ....\test\foo.txt )
BTW, if you decide to check out WiX and want some "easy" check out my IsWiX project on CodePlex. I'm trying to bridge the feature gap between InstallShield and WiX.
I have MANY small "Test Projects" where I put together just enough code to prove or disprove some idea I'm working on. Some time (sometimes several months) later, I need to use some of this code. It can take hours searching through poorly named folders to find the gem of code I'm looking for.
It's not enough to be worth a Blog or wiki entry. I'd just like to have something that includes a description, maybe a screen shot and the zip file of the project (or pointer to version control)
Is there a feature I'm missing in Visual Studio to track projects? Is there a template that can be used to search based on project comments etc?
Has anyone come across something like this?
How long before this question gets closed?
Yes, there is such a feature: it's in the "New Project" dialog, and it is called "Name". This will allow you to give your project a meaningful name, that will aid in your finding it later.
There's a related feature, borrowed from the operating system, called "Folders". This allows you to group various projects that are conceptually related, and put them together into a "folder", which you can give a meaningful name related to the conceptual grouping.
The combination of these two will serve all of your needs. The trick is to avoid the mentality which leads to "poorly named folders". Good working habits will save an absurd amount of time in the future, and it really doesn't take that much longer to come up with a meaningful name, rather than TestProject426
Why not use a version control system (like subversion) for that purpose?
You can put your test projects under version control, and by using a log message you have something you can later search for keywords and check out a project in case you need it again.
Once you have put a project under version control, you can remove it from your local disk (so you have less stuff lying around).
If a wiki is really to much hassle, why not search the root of your project folders with something like
findstr /I /S "nifty comment" *.cs
This would just require you to leave a comment with some keywords inside your code.