Это решение с использованием 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
.
Here - это сообщение в блоге, объясняющее, почему этот страшный материал необходим.
И here - это еще одно, но на C#.
Еще одна вещь, которую стоит отметить. Я попытался использовать сборки EnvDTE, как и в .net, но я продолжал получать ошибку регистрации COM. Когда я начал использовать COM-объекты, все сработало. Я не знаю достаточно о COM, чтобы действительно рискнуть предположить, почему это так.
EDIT
Если вы получаете эту ошибку при попытке запустить скрипт из командной строки:
Затем вам нужно запустить этот первый (вы должны только бежать он когда-либо.)
powershell -command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned"
Here - хорошее, подробное объяснение того, что делает эта команда.
Что вы ищете что два ответа ниже не предлагают? –
@MarkRucker ~ еще несколько вариантов, я предпочитаю решение с C над одним с заменой конца csproj, потому что в большинстве проектов, над которыми я работал, есть всевозможные вещи, а последние не являются группами элементов. Но я думаю, что C в порядке, мне просто нужно больше описания от автора. – Roland
Хорошо, я дам drphrozen день, чтобы добавить подробную информацию, так как его ответ составляет 90% пути. Если он не отвечает, я постараюсь ответить более подробно (если кто-то еще не вскочит). –