I keep having a situation where gets annoying (with TFS). I searched for "TFS" and "Recursive folder/files" but didn't find something similar in SOF and then good it but not exactly what I need.
I have checked out a project from TFS (#1) on my local machine and then after some modifications did update them on a new TFS (#2). Later noticed on TFS #2 have:
Solution folder
folder 1/folder 2/files
folder 2
folder 3/folder 3/files
I checked back on TFS #1 things were OK however, for a reason when it gets to my local drive it can get recursive. Anybody knows what I have done wrong? or any settings are involved?
One thing is that folders which go recursive are other developers projects.
Thank you!
Related
Ive been away from .Net web dev for a few years and am now coming back to it inorder to update a client project. I've installed VS Pro 2015(legit no cracks) and am now experiencings some odd behaviours both with the project/website files and VS.
The first 'issue' I need to tackle is that when adding a new master page or webform to the project, these new documents appear completely empty. There is no code or markup generated in the documents eg: 'docname.master', 'docname.master.cs', 'pagename.aspx', 'pagename.aspx.cs'.
I doubt this is the correct, behaviour since it wasn't in the past. So have things changed, and this is expected, and I need to get up to speed. Or, is there something wrong with my set-up -which I expect- ? If so, do you have any ideas what I'm doing wrong? What can I do to rectify this?
UPDATE
I've just done some testing on a different machine and it appears that this seems to be connected to the fact that the files I've been working with are located on a network file server. Is this a known issue, and are there any fixes/workarounds?
In my case it turns out that the cause of this and several other issues was purely down to the fact that the project files I was working with were located on a network drive.
It appears that this is a fairly common problem, especially when access to the network / remote drive is quite slow.
Simply switching the project files to a local drive fixed all the problem I was experiencing.
I'm trying to setup our CI build environment and having an issue.
First, I'm using VS and TFS 2012 so I can't use the *.12.xaml templates since those are for VS/TFS 2013.
Second, right now I'm configured to use just the defaulttemplate.11.xaml. Originally, I was using WebDeploy for the deployment method and that was working great. Since then, our web/server team has re-configured our test environment to use IIS Shared Configuration as well as DFS Replication to keep everything in sync.
Because of that, I'm no longer able to use WebDeploy (I passed this post over to the TFS admins, but they said no).
Is there a place where I can add some msbuild arguments, or a post-build event where I can send a *.cmd file with some arguments so I can get my code copied/deployed?
I've read Hanselman's (and everyone else that copied him) posts/blogs that say "if you're using xcopy, you're doing it wrong, etc...", but I believe in my case I CAN'T use Web Deploy.
Update:
So I thought I found my answer. Since the web deploy doesn't work for me, I found a workflow activity called CopyDirectory that sounded exactly like what I need.
I went through the process of updating my default template to add this additional step to the build process, which by the way, does NOT work very well. After adding the step, saving, etc, the step doesn't ever show up in my build output. I gave up for awhile to go see if I could do this on our Jenkins build server, got some different errors over there so I came back to TFS to make the changes and commit. Since the CI was still setup in TFS (granted, failing), I noticed that a build got kicked off when I made my commit. I decided to watch for awhile and IT FINISHED SUCCESSFULLY! Woah, all right. So I checked through the build logs, and find out that it threw a WARNING saying "failed to copy. Ensure the source directory exists and that you have the appropriate permissions".
Well, since I just entered this value incorrectly, no big deal, just change to the correct BuildDetail.DropLocation, and we should be golden.
WRONG, after building again with my changes to the source and destination values, I come to find out that since I'm trying to deploy my files to a different domain, it still fails.
Oh, and in addition to that, YOU CAN'T PASS CREDENTIALS TO THE COPYDIRECTORY STEP! REALLY! Phew, I found some documentation though, it says "give the tfs build service/account permissions on the domain that you want to copy to. Well, that would be great, if my server team would allow that, but they don't.
Back to square one...(this is going to turn into a blog about me complaining about TFS...)
I believe you can do it using robocopy. You will want to update your build template to include a new InvokeProcess activity. Set the activity's FileName to "RoboCopy" (include the quotes) and it's Arguments to something like the following:
String.Format(" ""{0}"" ""{1}"" /E /R:10 /W:10 /NFL /NDL ", BinariesDirectory, BuildDetail.DropLocation)
Of course changing the robocopy flags to your specific needs.
I don't think you can pass credentials into robocopy either though, so you might still be SOL there.
One possible alternative though is that because your admins won't give the TFS Build User (i.e. tfsservice) permissions on the destination box, you could change the TFS Builds to run as a different User that does have permissions on that box. To do this I believe you just have to log onto your TFS Build machine, go to the Services, find the Visual Studio Team Foundation Build Service Host 2012 (or something similar), and change the Log On As user from tfsservice to whatever user has permissions on the box that you want to publish to. Of course you will also need to give that user permissions to do everything else that the build system needs to do (download source code, etc.).
I am trying to create a custom build activity in C# that gets the list of files in the changesets from a build that was triggered by a check-in action in TFS 2010 and move those files from the SourcesDirectory to another location. The question is whether it is possible to retrieve the list of files that the user checks in to TFS 2010 that triggers a build so that I can loop through the files and move them to another location? So far, I have no luck.
Thanks much for any answers or help!
Thanks Loïc Faure-Lacroix for the comments. I guess my question was too broad so nobody answered my question.
It took me a while to get to where I am now and here’s what I’ve managed to do so far. I got the idea from the following links to take the Changesets as a parameter for my custom activity. I also took the SourcesDirectory as a param which I could obtain from inside the “Run On Agent” sequence.
http://blogs.msdn.com/b/codejunkie/archive/2010/09/02/custom-build-activity-for-tfs-2010-to-send-email-with-build-details-part-1.aspx
http://blogs.msdn.com/b/codejunkie/archive/2010/09/15/custom-build-activity-for-tfs-2010-to-send-email-with-build-details-part-2.aspx
[RequiredArgument]
[Browsable(true)]
public InArgument<IList<Changeset>> Changesets { get; set; }
[RequiredArgument] // The source directory to copy the files from
public InArgument<string> SourcesDirectory { get; set; }
I then needed to loop through the changeset to get the list of items that were checked in to TFS. However, the items I got from the changeset contain the server path, namely, something like “$/MainProj/SubProj/contactus/contact.htm” so I needed a way similar to the ConvertWorkspaceItem activity that can convert the server path to the real local build path on the build server. Does anyone know how the ConvertWorkspaceItem actually work? The SourcesDirectory has the path similar to this (which I am not sure whether always has the same format or will change based on projects or how build server was configured.): C:\Builds\1\SubProj\Sources\contactus
Since I could not find a proper way to convert the paths so I used an ugly way of basic substring search and replacement…
Once I looped through the changset, converted the server path to local source path, I was able to copy those files just checked in to TFS to another location such as a folder on our development server.
Then I ran into one big obstacle. I got the access denied error from the build when I tested with creating a new folder with a few new files in it and checking those in to trigger the build. It seemed that some process or thread that created the new folder in TFS and checked the files in still lock the folder when the build started to run, which I assumed is another thread… If the checked in files were in an existing folder, everything worked fine… Could anyone please share some insights?
Thanks!
I've put 3 especially large SQL queries within my Visual Studio project, under a folder "Queries" that is in the project directory (not the solution). Is there an eloquent way to access these files? I was hoping that something like #"Queries/firstSqlQuery.sql would work.
Specifying the full path, like with #"C:\\Users\John\Documents\VisualStudio2010\Projects\MySolution\MyProject\Queries\firstSqlQuery.sql
is something I'd really rather not do, since it requires me to go back into code and fix the path, should the application move.
EDIT: For some reason, the page is looking for the files in C:\\Program Files(x86)\Common Files\Microsoft Shared\DevServer\Queries\firstSqlQuery.sql. Why is it looking in this location, when the executable directory is different?
You can do something like this... if it's outside of project. (When I intitially read this-- I misread and thought it was in the solution directory which I was assuming contained the project)--
var pathToBin = Assembly.GetExecutingAssembly().Location;
var directoryInfoOfBin = new DirectoryInfo(pathToBin);
var solutionDirectory = directory.Parent().Parent();
var pathToSolution = solutionDirectory.FullName;
but this is much simpler if it's in the project
System.Web.HttpContext.Current.Server.MapPath("~/Queries/firstSqlQuery");
There are a number of ways to handle this, but there is a fundamental understanding you must gather first. Issuing something like #"Queries/..." isn't, by itself, isn't going to do anything. You need to leverage the System.IO namespace to perform IO operations.
With that part of the foundation, let's lay some more, when you issue a command like this:
File.ReadAllText("firstSqlQuery.sql");
the path that is implied is the Working Directory of the assembly that's executing the code. When debugging an application in Visual Studio, especially and ASP.NET Application, that's the bin directory that resides under the project directory, by default. So, if you did want to access the Queries folder, you would have to do something like this:
File.ReadAllText(#"..\Queries\firstSqlQuery.sql");
so, that's one way of handling it.
Another way of handling it would be to copy the file over into the bin folder every time the project is built by looking at the file properties (e.g. create a Post Build Event), but that's more work than I think you're looking for.
Again, the key here is to understand what directory you're starting in.
Finally, one thing worth noting, if you leverage the directory structure you'll need to ensure that the Queries folder gets deployed to the live site. That probably goes without saying, but I've seen people run into that exact problem before.
You could make sure your query files are copy to the output directory when you do a build and read the files from there without having to set a path.
I have the following situation.
I programmatically create a temporary workspace using TFS. I then map it to a spot on my local machine so that I can be able to checkin/checkout files. Since the mapping to the local drive through the workspace is what creates the file structure. What is the way to delete the mapping through the workspace object that I created?
Ive tried the following.
WorkingFolder tempFolder = workspace.getWorkingFolderForServerItem(serverItem);
workspace.DeleteMapping(tempFolder);
Stepping through in debug mode, the tempFolder Object I make holds the correct local mapping as well as the correct server mapping. I cant seem to get it to delete the local content though. Is this mostly correct or do you suggest something completely different?
In TFS, the trick to deleting files locally and telling the server that you do not have them anymore is to get the files at Changeset 1 (i.e. before they existed). In code that would be something like:
workspace.Get(
new string[] {"C:\\LocalPath"},
new ChangesetVersionSpec(1),
RecursionType.Full,
GetOptions.None);
See the following blog post where I explain this concept some more:
TFS Top Tip #11 - Removing source control files from your local file system
That said, if the workspace is just temporary and you do not need it anymore then doing a workspace.Delete() followed by a traditional file delete is a perfectly good way of doing things. If you were trying to keep the workspace around you could get into trouble though (because TFS thinks those files are still in your local workspace unless you tell it that they are not)
Since the mapping to the local drive through the workspace is what creates the file structure.
I think you have this wrong. The local folders (and files) are created only when you perform the get after the mapping is created (whether from the Team Explorer GUI, "tf.exe get", or otherwise).
After deleting the workspace mapping, you will need to create code to delete the files and folders yourself.
Thanks to Richard, I decided to not try and delete the file through the workspace.
Given:
WorkingFolder tempFolder = workspace.getWorkingFolderForServerItem(serverItem);
I ended up doing:
File.setAttributes(tempFolder.LocalItem, FileAttributes.normal)//Get rid of read-only
File.Delete(tempFolder.LocalItem);
Thanks for the help!