Working with XSLT in Visual Studio - visual-studio

In my C# client application, I use XSLT to transform XML into HTML.
I would like to be able to edit these files in place, without having to recompile the entire solution. I'm having trouble working out how to set up Visual Studio 2008 to allow this.
The problem is that the XSLT files must get copied to the output directory somehow. Currently this happens during the build process. (My XSLT files are set to "copy if newer".) The build process can take a few minutes, which seems excessive for making small tweaks to the HTML.
I could make my XSLT edits in the output directory itself, but the output directory is not under source control. I have accidentally wiped out my quick edits several times by building my solution.
I'd like to reduce the cycle time for debugging XSLT, while keeping my XSLT files under source control and preventing accidental overwrites.
Summary of Responses: It appears that the most practical approach for solving this problem -- given that Visual Studio doesn't have a nice way of doing it out of the box -- is to create a separate project that contains the content files. These files get copied to the output location when the project gets built. That way I don't have to compile the whole solution, just the one project with all the static information like XSLT, CSS, images, etc.
Several folks suggested using sync or batch copy tools, but while this would work for me personally, setting it up for the other members of the team too would be a lot of extra work.

I am not entirely clear about your question, but you can instruct Visual Studio to copy the file from the solution to the output folder every time that you build.
Let me try to understand your scenario:
You have the XSLT files checked into source control along with your C# code. For example, if your project is in a folder called MyProj, then the XSLT files reside in MyProj/Templates
You want to be able to edit the xslt files in the Templates folder and submit those changes to source control just like you do with .cs or other files in your project.
You want a copy of your xslt files in the bin/Debug or bin/Release folder along with your executable.
If that is the case, add the XSLT files to your Visual Studio project. Then right click on them, open Properties, and set "Build Action" = "Content" and "Copy to Output Directory" = "Always". Whenever you build your project, the latest copy of the XSLT files will be placed in your bin/Debug or bin/Release directory.

One approach is to include a C# Preprocessor Directive to point my XSLT load function to the solution directory when in debug mode, but the output directory when doing a release build.
Something like:
string viewFolder = AppDomain.CurrentDomain.BaseDirectory;
#if DEBUG
// Move up from /bin/debug
viewFolder = viewFolder + #"..\..\";
#endif
But that feels like a hack.

Apparently you're managing two concerns in one project. The first concern is your business logic (instantiating an XSLT transform, calling it to transform some XML content, outputting the HTML result....). The second concern is the Transformation itself.
So why not create a separate project for your xslt sheets? "Building" this project would consist of copying the sheets to the output folder. Changing xslt will not influence the other project, hence reduce the build time.
Separation of Concerns at project level, that is :)

You can edit the file directly in the output folder.
On another note, a lot of people don't know that rich tools are built into VS to allow debugging xslts.
http://msdn.microsoft.com/en-us/library/ms255605(VS.80).aspx

One solution that might work for you is to setup a junction to your Templates in your output folder. This would allow you to use the XSLTs directly without copying them to the output folder. A good idea is to ensure (create) the junction as a build action.
Prerequisites:
NTFS
A tool to create junctions (e.g. junction)

Create a batch file that copies your xslt's from their source-controlled location to all your bin directories (bin/debug bin/release or whatever ones you have defined)
Add the batch file as an External Tool, optionally assigning a keystroke (or chord) to execute the batch file
Edit, run tool (I'd assign a keystroke to this to make this easy), then check your webpage.

Could you use a file synchronization program (e.g. Microsoft SyncToy "is a free application that synchronizes files and folders between locations") to copy the files? This would allow you to avoid the "copy on build" step because the files are automatically copied after saved. Also, if you edited them in the output directory, the changes could be copied back into your source controled directory. Not what the best real time sync program is for this scenario is, but that could be another question.

I have exactly the same issue. I have bought a program called ViceVersa (http://www.tgrmn.com/) in which I have setup sync profiles so that my css, layout and xslt folders are synced from my machine to my dev server as soon as any changes are made. If I make any code changes then I just publish as normal.

I understand this is an older post but I found a different solution to basically the same problem.
Visual Studio allows you to 'link' files.
Right click on the folder in the solution where you want the file link to be located.
Click
'Add'
'Existing Item..'
(select the file)
Go the 'Add' Drop down and select 'Add as Link'

Related

Create Visual Studio Project for building using command

I have a solution where there is a dependency on 7zip's sfx. Out of desire to keep the entire solution (plus the sfx) managed and coordinated, I want to create a new project to house all the source files that is used by sfx, and when building, execute a command line that tells 7zip to build a sfx from the source files, and place into the output so that it can be then referenced by actual Visual Studio projects within the same solution.
I think I can figure the command line by using Build events and providing the appropriate macros to ensure that the 7zip's output is placed into the target folder with appropriate name so that it can be then correctly referenced by other VS projects. But what I am not sure about is what Visual Studio project I need to use or steps to take to tell Visual Studio that there isn't going to be any code to be compiled in this project and it just has to execute this script I give it.
The closest thing I can come up with is VS's Make project but I don't know if that is the right thing since this has nothing to do with Make at all.
So, what is the Visual Studio project template I need to use? If empty, then what configuration do I need to perform so that it won't try and look for some code files to compile but instead just execute scripts as part of the solution's build?
For now, it seems that using C++ Makefile Project works. I had to make few configurations:
1) I had to specify the project's "Configuration Type" as "Utility"
2) I used Pre-Build event and provided a command to invoke a batch file included in the project. The batch file then takes care of everything.
3) Normally, non C++ files are not considered for determining whether build is needed or if it's already up to date. To ensure that a new build is perform if the batch file or other key files are edited, I set the file's "File Type" to "MakeFile". Even though it isn't actually a Make file, it ensures that any edits made to the file will cause a new build.
The downsides I've found so far are:
1) C++ uses "Filters", not folders. Therefore, keeping the files in same directory structure is a big PITA. One can "include" files and get a one-to-one mapping between "Filters" and the actual directory structure on disk but it's annoying and tedious. Wish it was a C# project
2) I'm a bit wary about how it will detect new files or other changes for files that I didn't explicitly set to "MakeFile". I expect the source to be stable but I worry that when I realize I need a new file and add it, I might forget and not notice that the build is not correctly including the new file.
I'm not sure if this is the best method but this works for my purpose - having a project to manage external tools as part of bigger build process.

Creating a build process template which does nothing but copy all files to another directory

I would like to create a Build Definition inside TFS 2012 Express which will simply copy all files within my project source tree to another folder on my drive. Just to underline - I do not want the build output to go to another directory - I want the source files themselves to. The reason for this is I have IIS pointed at a specific folder, and I want the build to copy the latest asp and aspx files to the IIS hosted folder.
I am not sure of the intricacies of doing this, I did find : http://toadcode.blogspot.co.uk/2008/06/copy-multiple-files-via-tfs-build.html articles like this but I simply need a more direct list of what I need to do from somebody who understands this area.
Basically - when the build is queued, all I want is to copy my project source files to another directory :). I think this can be done by editing some Build.xml file...but when making a build definition I dont seem to be given the freedom to do what I would like to!
I think what I am looking for to alter my DefaultTemplate.11.1.xaml file to alter the build process which will let me run this / or a batch file after the build process completes?
My TFS build process edit screen looks like this:
Using this post as a guide on how to start editing TFS Build Templates (or the Wrox TFS 2012 book), you need to make the following changes:
Locate the Copy to Drop Folder Activity:
Drag in a "CopyDirectory" activity under the "Drop Files to Drop Location" (from the Toolbox under Team Foundation Build Activities):
Goto the Properties Window for the new Activity and set Source and Destination as follows:
Destination: Path.Combine(BuildDetail.DropLocation, "MyOutputFolder")
Source: Path.Combine(SourcesDirectory, "MyFileFolder")
You may need to repeat this if you don't have all your files in one folder.
I actually put something together for TFS2010 and 2013 (not 2012, unfortunately) a few weeks ago that does exactly that. Basically, anything in the workspace you define for your build just gets shoved over to the drop location.
Here's a link to the blog post where you can download them:
http://www.incyclesoftware.com/2014/06/deploying-uncompiled-resources-release-management/
For the record, I strongly recommend against using a build process template to deploy software. Don't try to overextend the build... its job is taking stuff from source control and compiling/packaging it for deployment. Use a real release management solution to actually handle deploying software.
Add a bat file to your source folder. within the batch file add an xcopy %1*.* TargetLocation.
Add an invoke process activity to your workflow, somewhere near the end. call the bat file and pass it the SourcesDirectory.

How to include all of a project's output in the installer project?

I need to include all the output from some of the programs projects in the installer... my question is similar to the one in this post: How to add a whole directory or project output to WiX package
However, I am afraid I don't really understand the answer given in this link. From all the reading I have done, I think I need to use Paraffin to do this. But is there a "start from the very beginning, how-to" resource for using paraffin?
I have read this page: http://www.wintellect.com/CS/blogs/jrobbins/archive/2008/12/22/paraffin-3-0-now-with-full-wix-3-0-support.aspx
and one of the posts mentions calling paraffin from a bat file. Is this how one would "use paraffin" in their installer? If it makes a difference, I have been using Visual Studio to work on this project, and am also not sure how to use command line from within Visual Studio. Does anyone have any resources for a very new beginner? Thanks.
I ended up including each .dll and .exe manually, since they don't change very often. It was fairly easy to format them in this style:
`<File Id="WhateverId" Name="NameToDisplayAfterInstall" Source="$(var.ProjectName.TargetDir)Filename.ext" />`
I used Excel to format a list of files quickly and easily. I put all of these File tags in the <DirectoryRef Id="INSTALLLOCATION">
tag.
I did figure out how to scrape all the dlls and exes from the project output by using Heat (not paraffin) and harvesting a directory, not a project. Harvesting a project yields only the main exe and dlls. The problem with harvesting a directory, at least in my case, is that I ended up with a lot of excess files, (like .pdb and .xml) that I didn't want.

Why do vcxproj.filters files exist?

Shouldn't vcxproj.filters be embedded in the .vcxproj? As it stands I have to check this in to source control so others can see the folder structuring in the solution.
According to what Dan Moseley says in this question, they also wanted to separate the tree structure from the build specific information because changing the tree structure would cause an update to be made to the project file, and that in turn would trigger a rebuild. By moving the logical view of the project to a separate file this is avoided.
They were embedded in fact, in previous versions of Visual Studio. The extension was still .vcproj and the filters were stored inside the project file. However, as of 2010 it was decided to pull the .filter information into a separate file.
It is really up to the design teams now to decide whether to add this source control or not. If you want all the developers to have the same structure (for reasons of communication) it might be wise to check them in. If you want to allow each developer to use their own logical view, then don't.
The vcxproj file contains the commands for the msbuild environment. So it contains the files that should be built and the arguments for the compiler how to build/link etc. the source files.
Due to this, the development team decided that the 'view' of the files in the solution explorer should not be contained in the msbuild file, but in another file.
So this was done to separate the build settings from the view you have.

How can I exclude files from being harvested with heat (WiX 3.5)?

I would like to harvest a folder with a lot of files by using heat.exe. But instead of harvesting all files, I would like to exclude specific file extensions like "*.txt" or something like that.
How can I do this?
I think the only option for now is to harvest the entire folder and apply a transform to the resulting .wxs file (see -t:<xsl> switch) to exclude what is not required (txt files in your case). However, I didn't try the 3.5 version of heat (judging based on the 3.0), but I don't think there are changes in this area.
I'm not a huge proponent of this pattern. How do you ensure change control when using a non-deterministic process? How do you know a file that appeared in a directory really should ship in a product and how do you know a file that vanished from the directory shouldn't break a build? How do you know you are breaking the component rules and creating servicability issues?
I used to do dynamic file linking in the 1990's because it was "easy" but I can remember it biting me many times and I haven't done it ever since.
I know Bob Arnson used to agree with this view point:
http://www.mail-archive.com/wix-users#lists.sourceforge.net/msg03420.html
But now in WiX 3.5 I'm starting to see capabilities that support dynamic linking and I just don't understand why they would go that way. I'd much rather update a WXS file and check it back into source control then risk putting my deployment process on autopilot.
Instead of trying to figure out how to harvest selected files from of a folder, I use a before build action to populate a folder with just the files that I want harvested. The following workflow has been working for me:
Delete a "files" if it exists
Create a "files" folder
Copy the files to the "files" folder. I use the robocopy build action, that gives me enough control to specify which files to include or exclude.
Harvest the entire folder.
I have it set to run the harvest action conditionally, just for debug builds. Release builds are generated from our TFS server and use the generated .wxs from source control. It should be OK to run harvest on the build server, but it's an extra step and not having it run eliminates the "non-deterministic process" problem described by Christopher Painter. Other than that one step, the same steps execute on the build server as they do on my dev machine.

Resources