I’m a WSPBuilder fan. I like the way it works, and i really like the Visual Studio extensions.
As everything else WSPBuilder is not perfect, it has at least one major drawback. It can’t handle visual studio linked files. This is a major problem for me, because i like to have my pages and user controls on a Web application and use a different project for the WSP.
To solve this problem I've created a simple command line application that reads the WSP project, and copies the linked files to the expected location. Now i use this tool as a PreBuild step for my WSP project, and that’s it… Linked files now work like a charm.
1: #region Revision history
2: // 6/12/2009 7:14:58 AM, Pedro M.V.Gomes -
3: // Initial version.
4: #endregion
5:
6: #region Using directives
7: using System;
8: using System.IO;
9: using System.Xml;
10: #endregion
11:
12: namespace PedroMVGomes.CopyVsLinkedFiles { 13: /// <summary>
14: /// </summary>
15: public class Program { 16: public static int Main(string[] args) { 17: // check arguments
18: if (args.Length != 1) { 19: Console.Out.WriteLine("syntax error"); 20: Console.Out.WriteLine("usage: CopyVsLinkedFiles.exe VSProject"); 21: return -1;
22: }
23:
24: // output welcome message
25: Console.Out.WriteLine("Visual Studio Linked Files Copy Tool"); 26: Console.Out.WriteLine("Version: 0.1.0.0"); 27: Console.Out.WriteLine("Created by Pedro M.V.Gomes, All rights reserved"); 28: Console.Out.WriteLine("http://wiggythoughts.blogspot.com/"); 29: Console.Out.WriteLine();
30:
31: // file must exist
32: string file = args[0];
33: if (!File.Exists(file)) { 34: Console.Out.WriteLine("project file not found"); 35: return -2;
36: }
37:
38: // get folder name, will use later to combine with linked relative path
39: string projectFolder = Path.GetDirectoryName(file);
40:
41: // load project XML
42: XmlDocument projectFile = new XmlDocument();
43: projectFile.Load(file);
44:
45: // add msbuild namespace
46: XmlNamespaceManager nsManager = new XmlNamespaceManager(projectFile.NameTable);
47: nsManager.AddNamespace("mns", "http://schemas.microsoft.com/developer/msbuild/2003"); 48:
49: // search linked nodes
50: XmlNodeList nodes = projectFile.DocumentElement.SelectNodes(@"//mns:Content/mns:Link", nsManager);
51: foreach (XmlNode node in nodes) { 52:
53: // compute source and target path
54: string linkFile = node.FirstChild.Value;
55: string linkedFile = node.ParentNode.Attributes["Include"].Value;
56: string source = Path.Combine(projectFolder, linkedFile);
57: string target = Path.Combine(projectFolder, linkFile);
58:
59: if (File.Exists(target)) { 60: // compare file modified dates and decide if we need to copy the files
61: FileInfo sourceFileInfo = new FileInfo(source);
62: FileInfo targetFileInfo = new FileInfo(target);
63: if (targetFileInfo.LastWriteTimeUtc == sourceFileInfo.LastWriteTimeUtc) { 64: continue;
65: }
66: }
67:
68: // copy files
69: Console.Out.WriteLine("Copying file {0} to {1}", source, target); 70: File.Copy(source, target, true);
71: }
72:
73: // done
74: return 0;
75: }
76: }
77: }