locked
How can I handle Build and Run events? RRS feed

  • Question

  • Hi there,

    I'm developing a custom package using MPF (VSSDK Sep 2006). I need to handle some usual events in VS:

    1. Build - when user presses CTRL+SHIFT+B or Build command in the menu

    2. Build & Run (aka F5) - when user presses F5 or Start Debugging command in the menu

    I want to handle these two events and ask my external compiler to just build the project or build it and if it's ok then run the compiled result. 

    Can anybody advice me the appropriate solution for my task? Maybe it will better to add my own menu near Debug and add 2 subitems to that menu? In this case - how can I catch the CTRL+SHIFT+B and F5 shortcuts?

    Thanks

    Wednesday, October 4, 2006 7:50 PM

Answers

  • If you do own the project then this is basic functionality in the MPF Project Sources, see e.g. IronPython sample. If you do not own the project you could very easily catch build events using DTE BuildEvents  http://msdn2.microsoft.com/en-us/library/envdte.buildeventsclass_members.aspx

    Ole

    Tuesday, October 10, 2006 4:30 PM
  • Hi again,

    I have found the way how to handle F5 in my case. Naybe this information will be interesting for everybody else.

    I’ve created anew class which is inherited from ProjectConfig class and have overridden the DebugLaunch method:

     

    [CLSCompliant(false)]

    [ComVisible(true)]

    public class MyProjectConfig : ProjectConfig

    {

           public MyProjectConfig(ProjectNode project, string configuration)

                 : base(project, configuration)

           {}

     

           public override int DebugLaunch(uint flags)

           {

                 // This is actually should be used for debugging purposes in the fu

                 try

                 {

                        string assemblyName = GetConfigurationProperty("AssemblyName", false);

                        string outputType = GetConfigurationProperty("OutputType", false);

                        string projectPath = GetConfigurationProperty("MSBuildProjectDirectory", false);

                        string outputPath = GetConfigurationProperty("OutputPath", false);

                        string fullPath = Path.Combine(projectPath, outputPath);

                        string outputFullName = string.Format("{0}{1}.{2}", fullPath, assemblyName, outputType);

     

                        if (outputFullName != null &&

                            outputFullName.Length > 0)

                        {

                               Process.Start(outputFullName);

                        }

                 }

                 catch(Exception e)

                 {

                        Trace.WriteLine("Exception : " + e.Message);

                        return Marshal.GetHRForException(e);

                 }

     

                 return VSConstants.S_OK;

           }

    }

     

    Then I’ve overridden the CreateProjectConfiguration method in my class which is inherited form ConfigProvider:

     

    protected override ProjectConfig CreateProjectConfiguration(string configName)

    {

           return new MyProjectConfig(project, configName);

    }

     

    MyConfigProvider instance is created in overridden method of ProjectNode class:

     

    protected override ConfigProvider CreateConfigProvider()

    {

           return new MyConfigProvider(this);

    }

     

    This way works well enough for me. But it looks like a hack and I think that solution where Run MSBuild target used instead will look more elegant. If anybody can explain me why overriding Run target in my teragets file doesn’t work that would be really great!

     

    Looking forward to hearing from you!

    Thursday, October 12, 2006 4:54 PM

All replies

  • If you do own the project then this is basic functionality in the MPF Project Sources, see e.g. IronPython sample. If you do not own the project you could very easily catch build events using DTE BuildEvents  http://msdn2.microsoft.com/en-us/library/envdte.buildeventsclass_members.aspx

    Ole

    Tuesday, October 10, 2006 4:30 PM
  • Hi Ole,

    Thank you for your response!

    I own my project - that is the custom package written using MPF. I'm not sure I understand how to get the solution for my problem using DTE BuildEvents you mentioned.

    There are some tasks are present in the IronPython sample.  For now I use 3 of them: Build, Rebuild and Clean. I need in something like Run task which is dependent from Build one and which is executed when user press F5.

    Any advice will be much appreciated!

    Tuesday, October 10, 2006 5:55 PM
  • Hi,

    I've found the Run target code in $(MSBuildBinPath)\Microsoft.Common.targets file:

    ============================================================

                                        Run

     

    Run the final build output if it is a .EXE

    ============================================================

    -->

    <PropertyGroup>

        <RunDependsOn></RunDependsOn>

    </PropertyGroup>

    <Target

        Name="Run"

        DependsOnTargets="$(RunDependsOn)">

     

        <Error Text="Cannot run '$(TargetPath)' because project output type is not '.exe'" Condition="'$(TargetExt)'!='.exe'"/>

        <Exec Command="$(TargetPath) $(StartArguments)" WorkingDirectory="$(OutDir)" Condition=" '$(StartWorkingDirectory)' == '' "/>

        <Exec Command="$(TargetPath) $(StartArguments)" WorkingDirectory="$(StartWorkingDirectory)" Condition=" '$(StartWorkingDirectory)' != '' "/>

     

    </Target>

    I've overridden this target in my own target file in following way:

    <UsingTask TaskName="MyTasks.RunTask" AssemblyFile="MyTasks.dll" />

     

    <Target Name="Run">

        <Message Text="Run" />

        <RunTask />

    </Target>

    In source code (RunTask.cs) I've put the following code:

    using Microsoft.Build.Framework;

    using Microsoft.Build.Utilities;

     

    namespace SharpStyle.ActionScriptBasics.Build.Tasks

    {

        public class RunTask : Task

        {

            public override bool Execute()

            {

                Log.LogMessage(MessageImportance.High, this.ToString());

                return false;

            }

        }

    }

    I expected to press F5 and see the message. But the Execute method stays untouched – I tried to set breakpoint inside it. Can anybody explain me how to override Run target properly?

    Thanks.

    Wednesday, October 11, 2006 7:33 PM
  • Hi again,

    I have found the way how to handle F5 in my case. Naybe this information will be interesting for everybody else.

    I’ve created anew class which is inherited from ProjectConfig class and have overridden the DebugLaunch method:

     

    [CLSCompliant(false)]

    [ComVisible(true)]

    public class MyProjectConfig : ProjectConfig

    {

           public MyProjectConfig(ProjectNode project, string configuration)

                 : base(project, configuration)

           {}

     

           public override int DebugLaunch(uint flags)

           {

                 // This is actually should be used for debugging purposes in the fu

                 try

                 {

                        string assemblyName = GetConfigurationProperty("AssemblyName", false);

                        string outputType = GetConfigurationProperty("OutputType", false);

                        string projectPath = GetConfigurationProperty("MSBuildProjectDirectory", false);

                        string outputPath = GetConfigurationProperty("OutputPath", false);

                        string fullPath = Path.Combine(projectPath, outputPath);

                        string outputFullName = string.Format("{0}{1}.{2}", fullPath, assemblyName, outputType);

     

                        if (outputFullName != null &&

                            outputFullName.Length > 0)

                        {

                               Process.Start(outputFullName);

                        }

                 }

                 catch(Exception e)

                 {

                        Trace.WriteLine("Exception : " + e.Message);

                        return Marshal.GetHRForException(e);

                 }

     

                 return VSConstants.S_OK;

           }

    }

     

    Then I’ve overridden the CreateProjectConfiguration method in my class which is inherited form ConfigProvider:

     

    protected override ProjectConfig CreateProjectConfiguration(string configName)

    {

           return new MyProjectConfig(project, configName);

    }

     

    MyConfigProvider instance is created in overridden method of ProjectNode class:

     

    protected override ConfigProvider CreateConfigProvider()

    {

           return new MyConfigProvider(this);

    }

     

    This way works well enough for me. But it looks like a hack and I think that solution where Run MSBuild target used instead will look more elegant. If anybody can explain me why overriding Run target in my teragets file doesn’t work that would be really great!

     

    Looking forward to hearing from you!

    Thursday, October 12, 2006 4:54 PM
  • Tuesday, March 20, 2007 4:45 PM
  • do you have complete all code ? worksfor vs 2008 ? where is ConfigProvider ? how call to ConfigProvider ?

    greetings


    Should "Hi", "Thanks" and taglines and salutations be removed from posts? http://meta.stackoverflow.com/questions/2950/should-hi-thanks-and-taglines-and-salutations-be-removed-from-posts
    Wednesday, September 21, 2011 9:21 AM