Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Visual Studio.NET / Extensibility / April 2008

Tip: Looking for answers? Try searching our database.

VCProjectEngine reference

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
bmelt - 16 Apr 2008 16:07 GMT
I use following code to set VC++ directories programmatically (or similar
code in C#):
DTE^ dte =
(DTE^)System::Runtime::InteropServices::Marshal::GetActiveObject            
  ("VisualStudio.DTE.8.0");
Projects ^projects = (Projects^)dte->GetObject(L"VCProjects");
VCProjectEngine ^ projectengine = (VCProjectEngine
^)projects->Properties->Item(L"VCProjectEngine")->Object;
IVCCollection ^platforms = (IVCCollection^)projectengine ->Platforms;
VCPlatform ^p64 = (VCPlatform ^)platforms->Item("x64");
if(p64 !=nullptr)
p64->ExecutableDirectories += ";C:\\Temp";

How to write a program that would set VC++ directories for any of VS 2003,
2005 and 2008. It looks like for each version of Visual Studio I have to set
reference to correspondent version of  
Microsoft::VisualStudio::VCProjectEngine, otherwise following code fails:

VCProjectEngine ^ projectengine (VCProjectEngine ^)
projects->Properties->Item("VCProjectEngine")->Object;

As a workaround, I can probably create 3 separate dlls or exe's each of
which has a reference to one of versions of VCProjectEngine and call
correspondent one from the main program - is there a better way?

Also, there is CommitChanges method to save settings in .Net 2.0 or higher.
How to save settings with VS 2003?
Jialiang Ge [MSFT] - 17 Apr 2008 11:06 GMT
Hello bmelt,

From your post, my understanding on this issue is: you wonder how to write
automation code for multiple versions of Visual Studio and how to save
changes (CommitChanges) in VS2003. If I'm off base, please feel free to let
me know.

1.  For you first question about VS automation code that can be compatible
for multiple versions of VS:

If it were Office automation, I would recommend that we can either use late
binding, or reference the earliest version of Office application we intend
to automate. However, for Visual Studio automation, VS Core automation
model keeps good backward compatibility, but VC++ automation models do not.
That's why you get the error

"Could not load file or assembly 'Microsoft.VisualStudio.VCProjectEngine,
Version=8.0.0.0...'"

from the line:
VCProjectEngine ^ projectengine = (VCProjectEngine
^)projects->Properties->Item("VCProjectEngine")->Object;

when the program explicitly references VCProject assembly for 8.0 but is
run in VS2008 machine. Actually, if you check the public assemblies of
VS2008 (C:\Program Files\Microsoft Visual Studio
9.0\Common7\IDE\PublicAsemblies), you will find EnvDTE.dll, EnvDTE80.dll,
and EnvDTE90.dll, but for Microsoft.VisualStudio.VCProjectEngine.dll, it
has only one whose version is 9.0.

In conclusion, we can use late binding to automate multiple versions of
Visual Studio, but we cannot accomplish it with early binding. I write the
following C++/CLI and C# late binding sample code for your references. The
code has been tested in VS2003, 2005 and 2008.

C++/CLI:
Object^ dte = Marshal::GetActiveObject("VisualStudio.DTE");

Object^ projects = dte->GetType()->InvokeMember("GetObject",
System::Reflection::BindingFlags::InvokeMethod, nullptr, dte, gcnew
cli::array<Object^> { "VCProjects" });
Object^ properties = projects->GetType()->InvokeMember("Properties",
System::Reflection::BindingFlags::GetProperty, nullptr, projects, nullptr);
Object^ vcprojectItem = properties->GetType()->InvokeMember("Item",
System::Reflection::BindingFlags::InvokeMethod, nullptr, properties, gcnew
cli::array<Object^>  { "VCProjectEngine" });
Object^ projectengine = vcprojectItem->GetType()->InvokeMember("Object",
System::Reflection::BindingFlags::GetProperty, nullptr, vcprojectItem,
nullptr);
Object^ platforms = projectengine->GetType()->InvokeMember("Platforms",
System::Reflection::BindingFlags::GetProperty, nullptr, projectengine,
nullptr);
Object^ p64 = platforms->GetType()->InvokeMember("Item",
System::Reflection::BindingFlags::InvokeMethod, nullptr, platforms, gcnew
cli::array<Object^>  { "x64" });

String^ exedir;
if (p64 != nullptr)
{
       exedir =
(String^)p64->GetType()->InvokeMember("ExecutableDirectories",
System::Reflection::BindingFlags::GetProperty, nullptr, p64, nullptr);
       Console::WriteLine(exedir);
}

C#:
object dte = Marshal.GetActiveObject("VisualStudio.DTE");
object projects = dte.GetType().InvokeMember("GetObject",
System.Reflection.BindingFlags.InvokeMethod, null, dte, new object[] {
"VCProjects" });
object properties = projects.GetType().InvokeMember("Properties",
System.Reflection.BindingFlags.GetProperty, null, projects, null);
object vcprojectItem = properties.GetType().InvokeMember("Item",
System.Reflection.BindingFlags.InvokeMethod, null, properties, new object[]
{ "VCProjectEngine" });
object projectengine = vcprojectItem.GetType().InvokeMember("Object",
System.Reflection.BindingFlags.GetProperty, null, vcprojectItem, null);
object platforms = projectengine.GetType().InvokeMember("Platforms",
System.Reflection.BindingFlags.GetProperty, null, projectengine, null);
object p64 = platforms.GetType().InvokeMember("Item",
System.Reflection.BindingFlags.InvokeMethod, null, platforms, new object[]
{ "x64" });
string exedir;
if (p64 != null)
{
        exedir =
(string)p64.GetType().InvokeMember("ExecutableDirectories",
System.Reflection.BindingFlags.GetProperty, null, p64, null);
        Console.WriteLine(exedir);
}

2. For your second question about CommitChanges:

According to the MSDN article
http://msdn2.microsoft.com/en-us/library/microsoft.visualstudio.vcprojecteng
ine.vcplatform.commitchanges(VS.80).aspx,
the function is for internal use only, and is new to VS2005. In VS2003, as
far as I know, there is not an equivalent. Regarding how to save changes
for VS settings, please give me some time to discuss it with the Visual
Studio development team. I will get back to you as soon as possible.

Please let me know if you have any other concerns, or need anything else.

Regards,
Jialiang Ge (jialge@online.microsoft.com, remove ¡®online.¡¯)
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
msdnmg@microsoft.com.

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
ttp://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
bmelt - 18 Apr 2008 23:32 GMT
Hi Jialiang ,

Thank you for good explanation and code example, it workes fine. I could
build my program with your code on VS 2005 and then access VC++ Directories
on 2003, 2005 and 2008.
In addition to your code, I could also set new paths using code like
platforms->GetType()->InvokeMember("ExecutableDirectories",
System::Reflection::BindingFlags::SetProperty, nullptr, pPlatform, gcnew
cli::array<Object^>  { "NewPath" });

Also on VS 2005 and 2008 I could commit changes with code
pPlatform->GetType()->InvokeMember("CommitChanges",
System::Reflection::BindingFlags::InvokeMethod, nullptr, pPlatform, nullptr);
but on VS 2003 this code failed indeed (Unknown name), so I'm still waiting
for an alternative to CommitChanges.

Without CommitChanges I can not save changes that were done programmatically.

Now if IDE is open and Marshal::GetActiveObject is used to get dte, I do not
see changes in VC++Directories right after running my program that uses
CommitChanges, but can see them if I close-open IDE. Is it possible to make
changes visible without re-opening IDE?

Another problem looks strange: if CommitChanges is called, and later I
change paths manually in IDE, then again run the program that calls
CommitChanges - changes desappear that were done manually. I have a feel that
manual and programmatic changes are saved in different places.

How to save both manual and programmatic changes on 3 supported versions of
Visual Studio?

Regards,
Boris
Jialiang Ge [MSFT] - 21 Apr 2008 09:09 GMT
Hello Boris,

>Also on VS 2005 and 2008 I could commit changes with
> code pPlatform->GetType()->InvokeMember(
>"CommitChanges",System::Reflection::BindingFlags::
> InvokeMethod, nullptr, pPlatform, nullptr); but on VS 2003 this code
> failed indeed (Unknown name), so I'm still waiting for an alternative
> to CommitChanges.

The failure of CommitChanges in VS2003 is because the method was not
exposed to VS2003 automation interface. CommitChanges is brand new to
VS2005. According to the confirmation from the VS team, I have to let you
know that there is no equivalent to CommitChanges in VS2003. I agree it is
very weird that VS offers ways to make the changes, but does not allow
saving the changes. As a long-term resolution, I have submitted your
concerns to the VS designers, and you are also welcome to add your
supplements to make Microsoft products easier to use by submitting a ticket
in https://connect.microsoft.com/VisualStudio. As a short-term workaround
for the VS2003 issue, I think we can write an Visual Studio add-in.
Whenever VS is started, the add-in sets the VCProject ExecutableDirectories.

>Now if IDE is open and Marshal::GetActiveObject is used to get dte,
> I do not see changes in VC++Directories right after running my
> program that uses CommitChanges, but can see them if I close-open
> IDE. Is it possible to make changes visible without re-opening IDE?

Would you check if there is more than one instance of VS running when this
happens? Because based on my test when there is only one VS running, the
setting takes effects immediately after I run the program. I can see the
new path in VC executable directories. However, if multiple VS's are
running, only one of which will reflect the change and others need a
restart. The reason for this behavior is: from a COM standpoint, the DTE
object is registered in the system's RunningObject. The
IRunningObjectTable::GetObject will actually retrieve the last object
registered, when we have duplicate objects in the ROT. We may have to
enumerate the ROT instead, and set the VCProject executable directories for
all of them if we do not expect a restart of VS. Ed Dore from MSFT showed
some sample code in the post:
http://www.dotnet247.com/247reference/msgs/46/231613.aspx

>Another problem looks strange: if CommitChanges is called, and
> later I change paths manually in IDE, then again run the program
> that calls CommitChanges - changes desappear that were done
> manually. I have a feel that manual and programmatic changes
>are saved in different places.

Do you see the changes made by your program in VS IDE? If not, please refer
to my reply to your second question.
If we want to call CommitChanges, we should do it immediate after we
programmatically changes the VCProject settings. In fact, any manual
changes through VS IDE before CommitChanges will be discarded.

I understand that it is very difficult to automate Visual Studio, which is
more complicated than the automation of Office. As far as I know, the VS
team might rewrite its infrastructure while keeping backward compatibility.
Anyway, I will do my best to help you out the present problems.

Regards,
Jialiang Ge  (jialge@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

=================================================
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
msdnmg@microsoft.com.

This posting is provided "AS IS" with no warranties, and confers no rights.
=================================================
bmelt - 23 Apr 2008 17:43 GMT
Hi Jialiang,
Thank you for explanation, I decided use of CommitChange is not good for my
project: it does not work with VS 2003 and removes all manual changes between
two calls to this function. As a workaround, now I'm going to run VS instanse
with Process, then set paths with
platforms->GetType()->InvokeMember("ExecutableDirectories",
System::Reflection::BindingFlags::SetProperty, nullptr, pPlatform, gcnew
cli::array<Object^> { "NewPath" });
Changes are visualized in VC++ directories - it works with all 3 versions of
VS.
User will check if there are paths set correctly, then change something - it
is enough to type ";" after the last path, then save changes clicking OK on
Options dialog.
Now probably the last question: how to programmatically open Options dialog
and display VC++ directories window. I tried
dte->ExecuteCommand ("Tools.Options",nullptr);
but it did not work at all.

Regards,
Boris
Jialiang Ge [MSFT] - 24 Apr 2008 08:37 GMT
Hello Boris,

Executing the command "Tools.Options" can open the Tools->Options dialog,
but I don't find interfaces/paramerters exposed by VS to programmatically
switch to the VC++ Directories window. A possible workaround is to find the
Options window's handle, and use SendMessage to turn to the target page.
(See: http://msdn2.microsoft.com/en-us/library/ms996405.aspx). I am still
contacting the VS team, to see if they have any suggestions. I will get
back to you soon.

Regards,
Jialiang Ge  (jialge@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

=================================================
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
msdnmg@microsoft.com.

This posting is provided "AS IS" with no warranties, and confers no rights.
=================================================
Jialiang Ge [MSFT] - 28 Apr 2008 12:03 GMT
Hello Boris,

I get back with a good news. We can pass the options page GUID (which you
can look up under
HKLM\Software\Microsoft\VisualStudio\10.0\ToolsOptionsPages) as a parameter
to dte ExecuteCommand method: dte.ExecuteCommand("Tools.Options",
"3284355C-AA45-11D2-835C-00C04F796961").

If you have any other concerns or questions, feel free to let me know.

Regards,
Jialiang Ge (jialge@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

=================================================
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
msdnmg@microsoft.com.

This posting is provided "AS IS" with no warranties, and confers no rights.
=================================================
bmelt - 28 Apr 2008 17:50 GMT
Hi Jialiang,

Finally you've answered on all my difficult questions and now I can
accomplish my project.

Thanks a lot for your great assistance - it was really knowlegable and
creative.

Best regards,
Boris
Jialiang Ge [MSFT] - 29 Apr 2008 02:57 GMT
Glad to help.

Regards,
Jialiang Ge  (jialge@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

=================================================
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
msdnmg@microsoft.com.

This posting is provided "AS IS" with no warranties, and confers no rights.
=================================================

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.