visual varios valido studio solucion seleccione proyectos proyecto linea limpiar inicio iconos elemento correctamente configurar compilar como code cargaron ajuste c# visual-studio-2012 envdte

c# - varios - ¿Cómo obtener la lista de proyectos en la solución actual de Visual Studio?



uno o varios proyectos de la solucion no se cargaron correctamente visual studio (3)

Aquí hay varios conjuntos de funciones que le permiten enumerar proyectos en una solución dada. Así es como lo usarías con la solución actual:

// get current solution IVsSolution solution = (IVsSolution)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(IVsSolution)); foreach(Project project in GetProjects(solution)) { .... } .... public static IEnumerable<EnvDTE.Project> GetProjects(IVsSolution solution) { foreach (IVsHierarchy hier in GetProjectsInSolution(solution)) { EnvDTE.Project project = GetDTEProject(hier); if (project != null) yield return project; } } public static IEnumerable<IVsHierarchy> GetProjectsInSolution(IVsSolution solution) { return GetProjectsInSolution(solution, __VSENUMPROJFLAGS.EPF_LOADEDINSOLUTION); } public static IEnumerable<IVsHierarchy> GetProjectsInSolution(IVsSolution solution, __VSENUMPROJFLAGS flags) { if (solution == null) yield break; IEnumHierarchies enumHierarchies; Guid guid = Guid.Empty; solution.GetProjectEnum((uint)flags, ref guid, out enumHierarchies); if (enumHierarchies == null) yield break; IVsHierarchy[] hierarchy = new IVsHierarchy[1]; uint fetched; while (enumHierarchies.Next(1, hierarchy, out fetched) == VSConstants.S_OK && fetched == 1) { if (hierarchy.Length > 0 && hierarchy[0] != null) yield return hierarchy[0]; } } public static EnvDTE.Project GetDTEProject(IVsHierarchy hierarchy) { if (hierarchy == null) throw new ArgumentNullException("hierarchy"); object obj; hierarchy.GetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ExtObject, out obj); return obj as EnvDTE.Project; }

Cuando abrimos la Consola del administrador de paquetes en cualquier solución abierta, muestra todos los proyectos de esa solución. Cómo está cargando todos los proyectos de la misma solución. Cuando probé con el código que se muestra a continuación, me está buscando proyectos de la primera solución que he abierto.

private List<Project> GetProjects() { var dte = (DTE)Marshal.GetActiveObject(string.Format(CultureInfo.InvariantCulture, "VisualStudio.DTE.{0}.0", targetVsVersion)); var projects = dte.Solution.OfType<Project>().ToList(); return projects; }


Creo que puedes usar algo como esto:

var dte = (EnvDTE.DTE)GetService(typeof(EnvDTE.DTE)); if (dte != null) { var solution = dte.Solution; if (solution != null) { // get your projects here } }


Puede haber una forma mejor, pero tuve una rápida idea de esto y encontré que esto funciona (asume que tienes una forma de saber el nombre de la solución). Según esta publicación , GetActiveObject no garantiza la instancia actual de VS por lo que está obteniendo resultados de otra instancia. En su lugar, puede utilizar el método GetDTE que se muestra allí:

[DllImport("ole32.dll")] private static extern int CreateBindCtx(uint reserved, out IBindCtx ppbc); public static DTE GetDTE(int processId) { string progId = "!VisualStudio.DTE.10.0:" + processId.ToString(); object runningObject = null; IBindCtx bindCtx = null; IRunningObjectTable rot = null; IEnumMoniker enumMonikers = null; try { Marshal.ThrowExceptionForHR(CreateBindCtx(reserved: 0, ppbc: out bindCtx)); bindCtx.GetRunningObjectTable(out rot); rot.EnumRunning(out enumMonikers); IMoniker[] moniker = new IMoniker[1]; IntPtr numberFetched = IntPtr.Zero; while (enumMonikers.Next(1, moniker, numberFetched) == 0) { IMoniker runningObjectMoniker = moniker[0]; string name = null; try { if (runningObjectMoniker != null) { runningObjectMoniker.GetDisplayName(bindCtx, null, out name); } } catch (UnauthorizedAccessException) { // Do nothing, there is something in the ROT that we do not have access to. } if (!string.IsNullOrEmpty(name) && string.Equals(name, progId, StringComparison.Ordinal)) { Marshal.ThrowExceptionForHR(rot.GetObject(runningObjectMoniker, out runningObject)); break; } } } finally { if (enumMonikers != null) { Marshal.ReleaseComObject(enumMonikers); } if (rot != null) { Marshal.ReleaseComObject(rot); } if (bindCtx != null) { Marshal.ReleaseComObject(bindCtx); } } return (DTE)runningObject; }

Si conoce el nombre de la solución de antemano, puede encontrarlo en la propiedad MainWindowTitle de Process y pasar el ProcessID al método anterior.

var dte = GetDTE(System.Diagnostics.Process.GetProcesses().Where(x => x.MainWindowTitle.StartsWith("SolutionName") && x.ProcessName.Contains("devenv")).FirstOrDefault().Id);

Mientras que el código anterior funcionó, encontré un error de COM que solucioné utilizando la clase MessageFilter muestra aquí .

Desde esa publicación, así es como se ve la clase MessageFilter

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); }

Entonces puedes acceder a los nombres de proyectos como este

var dte = GetDTE(System.Diagnostics.Process.GetProcesses().Where(x => x.MainWindowTitle.StartsWith("SolutionName") && x.ProcessName.Contains("devenv")).FirstOrDefault().Id); MessageFilter.Register(); var projects = dte.Solution.OfType<Project>().ToList(); MessageFilter.Revoke(); foreach (var proj in projects) { Debug.WriteLine(proj.Name); } Marshal.ReleaseComObject(dte);