65.9K
CodeProject 正在变化。 阅读更多。
Home

输出宏

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.36/5 (5投票s)

2005年4月13日

3分钟阅读

viewsIcon

33682

downloadIcon

176

用于打开当前配置的输出目录并复制当前配置的输出文件的宏。

引言

通常在编写代码时,我发现需要访问我正在处理的项目的输出目录,或者将输出文件复制到另一个位置。 当我修复错误并且需要将“已修复”的二进制文件复制到测试机器或测试目录以供他人访问时,尤其如此。

由于我处理的大多数项目都很复杂,所以我厌倦了不断地向下钻取目录来查找我想要的东西,所以我编写了两个宏来帮助我。 第一个宏,OpenOutputDir,在当前项目 (dsp) 文件中搜索当前配置的输出目录,并在资源管理器中打开它。 第二个宏,CopyOutputFile,执行类似的搜索以查找输出文件,然后将其复制到用户指定的目录。

使用代码

安装宏文件

  1. 在“工具”菜单上,单击“自定义”。
  2. 单击“加载项和宏文件”选项卡。 宏文件的名称应出现在窗口中。
  3. 如果宏文件的名称未出现,请单击“浏览”按钮以找到该文件。

    提示:为避免浏览,请将宏文件存储在 Visual Studio 目录的 Macros 子目录中(Visual Studio\Common\MSDEV98\Macros)。 Visual C++ 始终首先搜索 Macros 目录。

  4. 通过选中其名称旁边的复选框来加载相应的宏文件。 Visual C++ 添加一个复选标记,指示该文件已加载。 此复选标记还指示 Visual C++ 在您再次启动 Visual C++ 时自动加载该文件。

或者,您可以将下面的代码剪切并粘贴到您自己的宏文件中。

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

为了充分利用这些宏,您可能需要将它们分配给工具栏按钮或快捷键序列。 可以按如下方式完成

将宏分配给工具栏按钮

  1. 在“工具”菜单上,单击“自定义”。
  2. 单击“命令”选项卡。
  3. 在“类别”框中,单击“宏”。
  4. 从“命令”框中,将宏的名称拖到工具栏上,您希望放置宏的按钮的位置。
  5. 在“按钮外观”对话框中,选择工具栏按钮的图像,然后单击“确定”。 Visual C++ 将具有该图像的按钮添加到工具栏。

将宏分配给按键序列

  1. 在“工具”菜单上,单击“自定义”。
  2. 单击“键盘”选项卡。
  3. 在“类别”框中,单击“宏”。
  4. 在“命令”框中,选择要分配的宏。
  5. 单击“按下新快捷键”框。
  6. 按您要用于宏的按键序列。
  7. 单击“分配”按钮。 Visual C++ 将该按键序列分配给该宏。

关注点

我不太喜欢 CopyOutputFile 中的 InputBox,感觉很笨拙。 我想直接将文件复制到剪贴板,这样我就可以将其 CTRL+V 到我想要的任何目录中。 但是,我认为如果没有“剪贴板 ActiveX DLL”,就无法做到这一点(我懒得编写)。

历史

  • 2005 年 4 月 13 日 v1.0

    我不期望有更多版本了,除非你聪明的 CPians 知道我不知道的事情。

  • 2005 年 4 月 26 日 v1.1

    好的,我说谎了! 几个调整

    • 修复了两个搜索以处理相对路径 (..\..\Blah\Foo\Bar)。
    • 对于 CopyOutputFile,我发现了一个项目,其中项目文件中不存在“/out:”项。 在这种情况下,该函数使用项目名称和类型在输出目录中创建一个默认文件名(按照 OpenOutputDir 中的说明找到)。
© . All rights reserved.