== vccompile written in perl ==

I have written a perl script which can compile all versions of Visual
Studio from VS6 to VS2008 (AKA VS9). It requires no hacking of lisp
code, the default compile mode will do the job.

The trick is to make the devenv or msdev (for VS6) output look like the output from make(1). 

Caveat: you must be using cygwin version of Emacs, not the native
win32 Emacs (that will require you to change the script, for the
filename is converted to posix format, no longer win32 format). That
said, you'd also need the cygwin (1.7 is preferred, which is in beta
now), and perl and emacs23 is included in it.

Also, you need make the different versions of devenv.com/msdev.com
availabe in your ##PATH##, by the name of vcN.com, where N is the
version number; a softlink will do, as this is my setup:

<pre>
$l ~/bin/windows/vc*.com
lrwxrwxrwx 1 bhj None 78 2009-10-11 10:04 /q/bin/windows/vc6.com -> /cygdrive/c/Program Files/Microsoft Visual Studio/Common/MSDev98/Bin/MSDEV.COM*
lrwxrwxrwx 1 bhj None 82 2009-10-11 10:04 /q/bin/windows/vc7.com -> /cygdrive/c/Program Files/Microsoft Visual Studio .NET 2003/Common7/IDE/devenv.com
lrwxrwxrwx 1 bhj None 74 2009-10-11 10:04 /q/bin/windows/vc8.com -> /cygdrive/c/Program Files/Microsoft Visual Studio 8/Common7/IDE/devenv.com*
lrwxrwxrwx 1 bhj None 76 2009-10-11 10:04 /q/bin/windows/vc9.com -> /cygdrive/c/Program Files/Microsoft Visual Studio 9.0/Common7/IDE/devenv.com*
</pre>

(<code>~/bin/windows</code> is in my PATH).
=== Where to download it ===

[[http://windows-config.googlecode.com/svn/trunk/bin/windows/vccompile]]

There are other stuff in [[http://windows-config.googlecode.com]], you
might find interesting. For e.g., you can also find my .emacs file,
and msdn-help from Emacs, etc. Essentially it's everything from my
.bashrc/.inputrc to everything. For e.g., those <code>vcN.com</code>
softlinks are also in the svn, so that I don't need to <code>ln
-s</code> on a new computer, I only need make sure the Visual Studio
is installed at its default location.

=== Usage: ===

<code>M-x compile <Enter> vccompile all all <Enter> </code>

The above will compile all the projects (.dsp/.vcproj/.csproj) in your solution (.sln/.dsw) with both ##release## and ##debug## configuations.

It will seek for .dsw/.sln file in the pwd, if not found, look in the
parent folder, and so on, so you don't need to worry about the correct
.dsw/.sln file most of the time, because you currect buffer most
likely will be already editting the correct .c/.cpp/.cs etc. file,
which means the path is also already correct.

<pre>
vccompile project/all/'' release/debug/OTHER-CONFIG/all/'' (/clean) 
</pre>

The above is the whole SYNOPSIS for invoking ##vccompile##. The first argument is the project name, you can also specify /all/ to mean all projects, or <code>''</code> (empty) to mean the first project listed in the .sln/.dsw. The second is what configuration to do the compile. The optional 3rd argument will allow you to do what is like <code>make clean</code>.

Contact information can be found on the googlecode page.

-- BaoHaojun 

== Working with MS Visual Studio devenv command line. ==

The environment has to be set up before devenv will build from the command line. Here's the code I have in my .emacs for this (the cmd-shell function needs [[EmacsW32]]), and this is for VisualStudio 2005 - obviously for 2003 and VS6 it will be different (look for your vcvars32.bat for clues).

<pre>
(defun vc-x86-env ()
  (interactive)
  (setenv "VSINSTALLDIR" "C:\\Program Files (x86)\\Microsoft Visual Studio 8")
  (setenv "VCINSTALLDIR" "C:\\Program Files (x86)\\Microsoft Visual Studio 8\\VC")
  (setenv "FrameworkDir" "C:\\WINDOWS\\Microsoft.NET\\Framework")
  (setenv "FrameworkVersion" "v2.0.50727")
  (setenv "FrameworkSDKDir" "C:\\Program Files (x86)\\Microsoft Visual Studio 8\\SDK\\v2.0")
  (setenv "CommonDevEnvDir" "C:\\Program Files (x86)\\Microsoft Visual Studio 8\\Common7")
  (setenv "DevEnvDir" 
	  (concat (getenv "CommonDevEnvDir") "\\IDE")) ;; "C:\\Program\ Files\ (x86)\\Microsoft\ Visual\ Studio\ 8\\Common7\\IDE")
  (setenv "PATH" 
	  (concat (getenv "DevEnvDir") ;;"C:\\Program\ Files\ (x86)\\Microsoft\ Visual\ Studio\ 8\\Common7\\IDE"
		  path-separator
		   (concat (getenv "VCINSTALLDIR") "\\BIN") ;;"C:\\Program\ Files (x86)\\Microsoft\ Visual\ Studio 8\\VC\\BIN"
		   path-separator
		   (concat (getenv "CommonDevEnvDir") "\\Tools") ;;  "C:\\Program\ Files\ (x86)\\Microsoft\ Visual\ Studio\ 8\\Common7\\Tools"
		   path-separator
		   (concat (getenv "CommonDevEnvDir") "\\Tools\\bin") ;;   "C:\\Program\ Files\ (x86)\\Microsoft\ Visual\ Studio\ 8\\Common7\\Tools\\bin"
		   path-separator
		   (concat (getenv "VCINSTALLDIR") "\\PlatformSDK\\bin") ;;  "C:\\Program\ Files\ (x86)\\Microsoft\ Visual\ Studio\ 8\\VC\\PlatformSDK\\bin"
		   path-separator
		   (concat (getenv "FrameworkSDKDir") "\\bin") ;; "C:\\Program\ Files\ (x86)\\Microsoft\ Visual\ Studio\ 8\\SDK\\v2.0\\bin"
		   path-separator
		   (concat (getenv "FrameworkDir") "\\" (getenv "FrameworkVersion")) ;;  "C:\\WINDOWS\\Microsoft.NET\\Framework\\v2.0.50727"
		   path-separator
		   (concat (getenv "VCINSTALLDIR") "\\VCPackages") ;;  "C:\\Program\ Files\ (x86)\\Microsoft\ Visual\ Studio\ 8\VC\VCPackages"
		   path-separator
		   (getenv "PATH")))
  (setenv "INCLUDE"
	  (concat 
	   (concat (getenv "VCINSTALLDIR") "\\ATLMFC\\INCLUDE")
	   path-separator
	   (concat (getenv "VCINSTALLDIR") "\\INCLUDE")
	   path-separator
	   (concat (getenv "VCINSTALLDIR") "\\PlatformSDK\\include")
	   path-separator
	   (concat (getenv "VSINSTALLDIR") "\\SDK\\v2.0\\include")
	   path-separator 
	   (getenv "INCLUDE")))
  (setenv "LIB" (concat 
		 (concat (getenv "VCINSTALLDIR") "\\ATLMFC\\LIB")
		 path-separator
		 (concat (getenv "VCINSTALLDIR") "\\LIB")
		 path-separator
		 (concat (getenv "VCINSTALLDIR") "\\PlatformSDK\\lib")
		 path-separator
		 (concat (getenv "VSINSTALLDIR") "\\SDK\\v2.0\lib")
		 path-separator 
		 (getenv "LIB")))
  (setenv  "LIBPATH" 
	   (concat
	    (concat (getenv "FrameworkDir") "\\" (getenv "FrameworkVersion")) ;;  "C:\\WINDOWS\\Microsoft.NET\\Framework\\v2.0.50727"
	    path-separator
	    (concat (getenv "VCINSTALLDIR") "\\ATLMFC\\LIB")))
  (cmd-shell))
</pre>

Commands like..

<pre>
devenv Projects/MyProgram/Solution.sln /project Projects/MyProgram/Project.vcproj /Config "Debug|x86" /Clean
</pre>

..can then be used in the shell buffer that is started by the command vc-x86-env. Obviously, paths may
haye to change for different install locations, etc. And also for an x86/x64 setup. See devenv /help
or MSDN for the full explanation!

For actually invoking devenv, here is a handy interactive function..

<pre>
(defun is-devstudio-solution (filename)
  (or 
   (null (file-name-extension filename))
   (string= (file-name-extension filename) "sln")))

(read-file-name "Solution: " nil nil t nil 'is-devstudio-solution) 

(defun extract-projects (sln-file)
  (save-excursion
    (with-temp-buffer
      (insert-file sln-file)
      (goto-char (point-min))
      (let ((result nil)
	    (index 0))
	(while
	    (re-search-forward
	     "Project(\"{[-A-Z0-9]+}\")[ 	]+=[ 	]+\"\\([A-Za-z0-9_]+\\)\"[ 	]*,[ 	]+\"\\([\\A-Za-z0-9_.]+\\)\""
	     (point-max)
	 t) 
    (add-to-list 'result (cons (match-string-no-properties 1) (match-string-no-properties 2))))
    result))))

(defun dev-studio-build ()
  (interactive)
  (let*
      ((solution-name
	(read-file-name "Solution: " nil nil t))
       (projects
	(extract-projects solution-name))
       (action
	(completing-read "Action: " '(("Build" . 0) ("Clean" . 1) ("Run" . 2) ("RunExit" . 3))
			 nil t "Build"))
       (configuration
	(completing-read "Configuration: " '(("Debug" . 0) ("Release" . 1) ("Hybrid" . 2))
			 nil t "Debug"))
       (platform
	(completing-read "Platform: " '(("Win32" .0) ("x86" . 1))
			 nil t "Win32"))
       (project
	(completing-read "Project " projects
			 nil t (caar projects))))
    (compile
     (concat "Devenv \"" solution-name "\" /" action " \""  (concat configuration "|" platform) "\" /project \"" (cdr (assoc project projects)) "\""))))
</pre>

A  better longer term solution is to migrate away from microsofts platform specific solution building system towards something more platform neutral like make or scons or bjam or whatever, but if the pointy-haired-boss insists on Microsoft, this is at least, a useful band-aid. [[johnfredcee]]

== Sending current file to Emacs from Visual Studio ==

If you use gnuserv, try VisEmacs.

If you use [[EmacsW32]] which comes with emacsclient instead of gnuserv you can use the following macro in Visual Studio:

    Sub OpenInEmacs()
        Dim filename As String
        Dim linenumber As Integer
        Dim column As Integer

        linenumber = DTE.ActiveDocument.Selection.ActivePoint.Line
        column = DTE.ActiveDocument.Selection.ActivePoint.VirtualDisplayColumn
        filename = DTE.ActiveDocument.FullName

        DTE.StatusBar.Text = "Opening " + filename + ":" + linenumber.ToString + " in Emacs"

        Shell("emacsclientw.exe" + " -n +" + linenumber.ToString + ":" + column.ToString + " " + filename)
    End Sub

Simply bind it to a key or menu command and it will open the current file in Emacs at the current line.

=== Another way to do this, without a macro... ===

In visual Studio, Configure external tools.  Add a tool with the following configuration:
<pre>
Name: Emacs (for example)
Location: c:\path-to\emacsclientw.exe
Arguments: -n +$(CurLine):$(CurCol) $(ItemFileName)$(ItemFileExt) 
*note there is a variable button that will help you with the shortcuts like $(CurLine)
WorkingDirectory: $(ItemDirectory)
</pre>

Sample for VS2010
<pre>
Name: Emacs 
Location: c:\path-to\emacsclientw.exe
Arguments: -n +$(CurLine):$(CurCol) $(ItemPath)
*note there is a variable button that will help you with the shortcuts like $(CurLine)
WorkingDirectory: $(ItemDirectory)
</pre>


Then bind whatever keys you prefer to the external tools (Will be called something like Tools.ExternalCommandn, with n depending on your tool order) in your keyboard preferences (I use Ctl-Alt-E).
== See Also ==

Opening a visual studio solution in emacs:
* SlnMode

For Visual Studio-style bookmarking:

* [[BookmarkPlus#HighlightingBookmarkLocations|Bookmark+]]
* VisibleBookmarks

