Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Output Macros

0.00/5 (No votes)
26 Apr 2005 1  
Macros to open the output directory of your current configuration and to copy the output file of your current configuration.

Introduction

Often as I'm coding, I find it necessary to access the output directory of the project I'm working on, or to copy the output file to another location. This is especially true when I'm fixing bugs and need to copy the 'fixed' binary to a test machine or test directory for access by others.

Since most of the projects I work on are convoluted, I get tired of constantly drilling down directories to find what I'm after, so I wrote two macros to help. The first, OpenOutputDir, searches the current project (dsp) file for the output directory of the current configuration and opens it in Explorer. The second, CopyOutputFile, does a similar search for the output file and then copies it to a user specified directory.

Using the code

To install the macro file:

  1. On the Tools menu, click Customize.
  2. Click the Add-ins and Macro Files tab. The name of the macro file should appear in the window.
  3. If the name of the macro file does not appear, click the Browse button to locate the file.

    Tip: To avoid browsing, store macro files in the Macros subdirectory of the Visual Studio directory (Visual Studio\Common\MSDEV98\Macros). Visual C++ always searches the Macros directory first.

  4. Load the appropriate macro file by selecting the check box next to its name. Visual C++ adds a check mark, indicating that the file is loaded. This check mark also directs Visual C++ to automatically load the file when you start Visual C++ again.

Alternatively, you can cut and paste the code below into your own macro file.

OpenOutputDir

Sub OpenOutputDir()
'DESCRIPTION: Open the folder into which the current configuration builds.


   '----------

   ' Variables

   '----------


   Dim strProjFile, strConfigName, strOutputDir, strLine
   Dim oFSO, oFile, oShell
   Dim bFound, bFoundConfig
   Dim nRelativeSteps, nStep

   '----------

   ' Constants

   '----------


   Const ForReading = 1
   Const CONFIG_STR = """$(CFG)"" == "
   Const OUTPUT_STR = "# PROP Output_Dir "

   '-----------------------------------------------------------

   '----------------------------------------------

   ' Get some information from the current project

   '----------------------------------------------


   strProjFile = ActiveProject.FullName
   strConfigName = CONFIG_STR + """" + ActiveConfiguration.Name + """"

   '----------------------

   ' Read the project file

   '----------------------


   Set oFSO = CreateObject("Scripting.FileSystemObject")
   Set oFile = oFSO.OpenTextFile(strProjFile, ForReading)

   '------------------------------

   ' Look for the output directory

   '------------------------------


   bFound = FALSE
   bFoundConfig = FALSE
   Do While ((oFile.AtEndOfStream <> True) And (Not bFound))
      strLine = oFile.ReadLine
      If (Not bFoundConfig) Then
         If (Instr(strLine, strConfigName) > 0) Then
            bFoundConfig = TRUE
         End If
      Else
         If (Instr(strLine, OUTPUT_STR) > 0) Then
            bFound = TRUE
         End If
      End If
   Loop

   '-----------------------------------------

   ' Trim the line down to the important bits

   '-----------------------------------------


   strLine = Replace(strLine, OUTPUT_STR, "")
   strLine = Replace(strLine, """", "")

   nRelativeSteps = 0
   While (Left(strLine, 3) = "..\")
      strLine = Mid(strLine, 4)
      nRelativeSteps = nRelativeSteps + 1
   WEnd

   While (Left(strLine, 1) = ".")
      strLine = Mid(strLine, 2)
   WEnd

   strLine = Replace(strLine, "/", "\")

   If (Left(strLine, 1) <> "\") Then
      strLine = "\" + strLine
   End If

   '-------------------------------------------

   ' Construct the path to the output directory

   '-------------------------------------------


   For nStep = 0 To nRelativeSteps
      strProjFile = Left(strProjFile, InStrRev(strProjFile, "\") - 1)
   Next

   strOutputDir = strProjFile + strLine

   If (oFSO.FolderExists(strOutputDir)) Then
      Application.PrintToOutputWindow "Opening folder... " + strOutputDir
      Set oShell = CreateObject("WScript.Shell")
      oShell.Run("""" + strOutputDir  + """")
   Else
      MsgBox "I couldn't find the output folder!" + vbCrlf _
                      + strOutputDir, vbOKOnly, "Macro Error"
   End If

End Sub

CopyOutputFile

Sub CopyOutputFile()
'DESCRIPTION: Copy the output file which the current configuration builds.


   '----------

   ' Variables

   '----------


   Dim strProjFile, strConfigName, strOutputFile, strLine, strDestination
   Dim oFSO, oFile, oShell
   Dim bFound, bFoundConfig
   Dim nStart, nEnd
   Dim nRelativeSteps, nStep, nTargType

   '----------

   ' Constants

   '----------


   Const ForReading = 1
   Const CONFIG_STR = """$(CFG)"" == "
   Const OUT_FILE_STR = "/out:"
   Const OUTPUT_STR = "# PROP Output_Dir "

   Const TARG_TYPE = "# TARGTYPE "
   Const TARG_TYPE_EXE = "Win32 (x86) Application"
   Const TARG_TYPE_DLL = "Win32 (x86) Dynamic-Link Library"
   Const TARGE_TYPE_LIB = "Win32 (x86) Static Library"

   Const TT_EXE = 1
   Const TT_DLL = 2
   Const TT_LIB = 4

   '---------------------------------------------------------------

   '----------------------------------------------

   ' Get some information from the current project

   '----------------------------------------------


   strProjFile = ActiveProject.FullName
   strConfigName = CONFIG_STR + """" + ActiveConfiguration.Name + """"

   '----------------------

   ' Read the project file

   '----------------------


   Set oFSO = CreateObject("Scripting.FileSystemObject")
   Set oFile = oFSO.OpenTextFile(strProjFile, ForReading)

   '------------------------------

   ' Look for the output directory

   '------------------------------


   bFound = FALSE
   bFoundConfig = FALSE
   Do While ((oFile.AtEndOfStream <> True) And (Not bFound))
      strLine = oFile.ReadLine
      If (Not bFoundConfig) Then
         If (Instr(strLine, strConfigName) > 0) Then
            bFoundConfig = TRUE
         End If
      Else
         If (Instr(strLine, OUT_FILE_STR) > 0) Then
            bFound = TRUE
         End If
      End If
   Loop

   '------------------------------------------------------------------------------

   ' If we didn't find it, construct the 'default' name using the output directory

   '------------------------------------------------------------------------------


   If (Not bFound) Then
      oFile.Close
      Set oFile = oFSO.OpenTextFile(strProjFile, ForReading)
      bFound = FALSE
      bFoundConfig = FALSE
      nTargType = 0
      Do While ((oFile.AtEndOfStream <> True) And (Not bFound))
         strLine = oFile.ReadLine

         If (InStr(strLine, TARG_TYPE) > 0) Then
            If (InStr(strLine, TARG_TYPE_EXE) > 0) Then
               nTargType = TT_EXE
            ElseIf (InStr(strLine, TARG_TYPE_DLL) > 0) Then
               nTargType = TT_DLL
            ElseIf (InStr(strLine, TARG_TYPE_LIB) > 0) Then
               nTargType = TT_LIB
            End If
         End If

         If (Not bFoundConfig) Then
            If (Instr(strLine, strConfigName) > 0) Then
               bFoundConfig = TRUE
            End If
         Else
            If (Instr(strLine, OUTPUT_STR) > 0) Then
               bFound = TRUE
            End If
         End If
      Loop

      '-----------------------------------------

      ' Trim the line down to the important bits

      '-----------------------------------------


      strLine = Replace(strLine, OUTPUT_STR, "")
      strLine = Replace(strLine, """", "")

      If (bFound) Then
         Select Case (nTargType)
            Case (TT_EXE)
               strLine = strLine + "\" + ActiveProject.Name + ".exe"
            Case (TT_DLL)
               strLine = strLine + "\" + ActiveProject.Name + ".dll"
            Case (TT_LIB)
               strLine = strLine + "\" + ActiveProject.Name + ".lib"
         End Select
      End If
   Else
      '-----------------------------------------

      ' Trim the line down to the important bits

      '-----------------------------------------


        nStart = InStr(strLine, OUT_FILE_STR)
      nStart = InStr(nStart + 1, strLine, """")
      nEnd = InStr(nStart + 1, strLine, """")
      strLine = Mid(strLine, nStart + 1, nEnd - nStart - 1)
   End If

   nRelativeSteps = 0
   While (Left(strLine, 3) = "..\")
      strLine = Mid(strLine, 4)
      nRelativeSteps = nRelativeSteps + 1
   WEnd

   While (Left(strLine, 1) = ".")
      strLine = Mid(strLine, 2)
   WEnd

   strLine = Replace(strLine, "/", "\")

   If (Left(strLine, 1) <> "\") Then
      strLine = "\" + strLine
   End If

   '--------------------------------------

   ' Construct the path to the output file

   '--------------------------------------


   For nStep = 0 To nRelativeSteps
      strProjFile = Left(strProjFile, InStrRev(strProjFile, "\") - 1)
   Next

   strOutputFile = strProjFile + strLine

   '----------------------

   ' Ask for a destination

   '----------------------


   strDestination = InputBox("Copy file:" + vbCrLf + vbCrLf _
                    + strOutputFile + vbCrLf + vbCrLf + "to", "Copy File")

   If (strDestination = "") Then ' User clicked 'Cancel'

      Exit Sub
   End If

   '----------------

   ' Check it exists

   '----------------


   If (oFSO.FolderExists(strDestination)) Then
      If (Right(strDestination, 1) <> "\") Then
         strDestination = strDestination + "\"
      End If
      Application.PrintToOutputWindow "Copying file... " + strOutputFile
      Application.PrintToOutputWindow "to... " + strDestination
      oFSO.CopyFile strOutputFile, strDestination, True
   Else
      MsgBox "I couldn't find the destination folder!" + vbCrlf _ 
                   + vbCrlf + strDestination, vbOKOnly, "Macro Error"
   End If

End Sub

To make best use of these macros, you'll probably want to assign them to a toolbar button, or shortcut key sequence. This can be done as follows:

To assign a macro to a toolbar button:

  1. On the Tools menu, click Customize.
  2. Click the Commands tab.
  3. In the Category box, click Macros.
  4. From the Commands box, drag the macro's name to the toolbar where you want a button for the macro.
  5. In the Button Appearance dialog box, select an image for the toolbar button, and then click OK. Visual C++ adds a button with that image to the toolbar.

To assign a macro to a key sequence:

  1. On the Tools menu, click Customize.
  2. Click the Keyboard tab.
  3. In the Category box, click Macros.
  4. In the Commands box, select the macro you want to assign.
  5. Click in the Press new shortcut key box.
  6. Press the key sequence you want to use for the macro.
  7. Click the Assign button. Visual C++ assigns that key sequence to the macro.

Points of Interest

I don't much like the InputBox in CopyOutputFile, it feels clumsy. I wanted to just copy the file to the clipboard so that I could CTRL+V it into any directory I wanted. However, I don't think this can be done without a 'clipboard ActiveX DLL' (which I couldn't be bothered to write).

History

  • 13-Apr-2005 v1.0

    I don't anticipate anymore versions, unless you clever CPians know something I don't.

  • 26-Apr-2005 v1.1

    OK, I lied! A couple of tweaks:

    • Fixed both searches to account for relative paths (..\..\Blah\Foo\Bar).
    • For CopyOutputFile, I found a project where the "/out:" item wasn't present in the project file. In that case, the function uses the project name and type to create a default file name in the output directory (found as per OpenOutputDir).

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here