Asp.net

從命令行在項目中包含文件

  • November 21, 2016

有沒有辦法在 vs2012 的命令行中將文件包含在項目中?

我問的原因是因為每當我使用其他一些 IDE(如 ST3)或從 Photoshop 保存文件等時,包含我添加到項目文件夾中的任何新文件都非常令人沮喪。

我正在使用 Grunt 進行大量縮小、連接、在我的角度腳本上執行 ngmin 等。有一個 grunt-shell 外掛允許 grunt 任務執行 shell 命令(我已經使用它來解鎖 TFS 鎖定的文件)。所以我想我可以創建一個任務,為我添加的任何新文件(通過使用 grunt-watch 觀察某個文件夾)執行包含在項目中。

這是使用 PowerShell 的解決方案。它有點長,但我保證它有效。我測試了很多。

首先,簡單的部分。以下是從命令提示符執行腳本的方式。

powershell -File C:\AddExistingItem.ps1 -solutionPath "C:\Test.sln" -projectName "TestAddItem" -item "C:\Test.txt"

現在是可怕的部分,AddExistingItem.ps1:

param([String]$solutionPath, [String]$projectName, [String]$item)

#BEGIN: section can be removed if executing from within a PowerShell window
$source = @" 

namespace EnvDteUtils
{ 
   using System; 
   using System.Runtime.InteropServices; 

   public class MessageFilter : IOleMessageFilter 
   { 
       // 
       // Class containing the IOleMessageFilter 
       // thread error-handling functions. 

       // Start the filter. 
       public static void Register() 
       { 
           IOleMessageFilter newFilter = new MessageFilter();  
           IOleMessageFilter oldFilter = null;  
           CoRegisterMessageFilter(newFilter, out oldFilter); 
       } 

       // Done with the filter, close it. 
       public static void Revoke() 
       { 
           IOleMessageFilter oldFilter = null;  
           CoRegisterMessageFilter(null, out oldFilter); 
       } 

       // 
       // IOleMessageFilter functions. 
       // Handle incoming thread requests. 
       int IOleMessageFilter.HandleInComingCall(int dwCallType,  
         System.IntPtr hTaskCaller, int dwTickCount, System.IntPtr  
         lpInterfaceInfo)  
       { 
           //Return the flag SERVERCALL_ISHANDLED. 
           return 0; 
       } 

       // Thread call was rejected, so try again. 
       int IOleMessageFilter.RetryRejectedCall(System.IntPtr  
         hTaskCallee, int dwTickCount, int dwRejectType) 
       { 
           if (dwRejectType == 2) 
           // flag = SERVERCALL_RETRYLATER. 
           { 
               // Retry the thread call immediately if return >=0 &  
               // <100. 
               return 99; 
           } 
           // Too busy; cancel call. 
           return -1; 
       } 

       int IOleMessageFilter.MessagePending(System.IntPtr hTaskCallee,  
         int dwTickCount, int dwPendingType) 
       { 
           //Return the flag PENDINGMSG_WAITDEFPROCESS. 
           return 2;  
       } 

       // Implement the IOleMessageFilter interface. 
       [DllImport("Ole32.dll")] 
       private static extern int  
         CoRegisterMessageFilter(IOleMessageFilter newFilter, out  
         IOleMessageFilter oldFilter); 
   } 

   [ComImport(), Guid("00000016-0000-0000-C000-000000000046"),  
   InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
   interface IOleMessageFilter  
   { 
       [PreserveSig] 
       int HandleInComingCall(  
           int dwCallType,  
           IntPtr hTaskCaller,  
           int dwTickCount,  
           IntPtr lpInterfaceInfo); 

       [PreserveSig] 
       int RetryRejectedCall(  
           IntPtr hTaskCallee,  
           int dwTickCount, 
           int dwRejectType); 

       [PreserveSig] 
       int MessagePending(  
           IntPtr hTaskCallee,  
           int dwTickCount, 
           int dwPendingType); 
   } 
} 
"@ 

Add-Type -TypeDefinition $source      

[EnvDTEUtils.MessageFilter]::Register()
#END: section can be removed if executing from within a PowerShell window

$IDE = New-Object -ComObject VisualStudio.DTE

$IDE.Solution.Open("$solutionPath")

$project = $IDE.Solution.Projects | ? { $_.Name -eq "$projectName" }
$project.ProjectItems.AddFromFile("$item") | Out-Null
$project.Save()

$IDE.Quit()

#BEGIN: section can be removed if executing from within a PowerShell window
[EnvDTEUtils.MessageFilter]::Revoke()
#END: section can be removed if executing from within a PowerShell window

95% 的程式碼只是為了讓您從命令提示符執行。如果您是直接在 PowerShell 中編寫和執行程式碼,您可以將其排除在外,直接轉到$IDE = New-Object -ComObject VisualStudio.DTE.

是一篇部落格文章,解釋了為什麼需要這些可怕的東西。

這是另一個關於同一件事的,但在 C# 中

還有一點值得注意。我嘗試使用 EnvDTE 程序集,就像在 .net 中一樣,但我一直收到 COM 註冊錯誤。一旦我開始直接使用 COM 對象,一切正常。我對 COM 的了解還不夠,無法真正冒險猜測這是為什麼。

編輯

如果您在嘗試從命令提示符執行腳本時收到此錯誤:

執行策略錯誤

然後你需要先執行它(你應該只需要執行一次。)

powershell -command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned"

是對該命令的作用的一個很好的、深入的解釋。

引用自:https://stackoverflow.com/questions/17382308