views:

908

answers:

2

Hi,

I would like use macros for publishing my webapplication project. The little problem is, DTE.ExecuteCommand run asynchronously, and I need to wait until the command is done.

Example:

    DTE.Windows.Item(Constants.vsWindowKindSolutionExplorer).Activate()
    DTE.ActiveWindow.Object.GetItem("04 - Products\04 - Products.WSS").Select(vsUISelectionType.vsUISelectionTypeSelect)
    DTE.ExecuteCommand("ClassViewContextMenus.ClassViewProject.Publish")
    '// now I want copy (and overwrite) some files, but AFTER the publish

Is there some synchronization object or information about state of executed command?

Thanks

+2  A: 

Hey guys, if you're still looking for an answer to this one try this.

Tie into the publish events and on a successful push call your external command. I'm doing a similar thing with building the solution and then firing the MSpec test runner (blog post).

To do this you need to add in a hook for PublishEvents_OnPublishDone. Do this by going to the EnvironmentEvents Module and addin the following:

<System.contextStaticAttribute()> Public WithEvents PublishEvents As EnvDTE80.PublishEvents

Private Sub PublishEvents_OnPublishDone(ByVal Success As Boolean) Handles PublishEvents.OnPublishDone
    'call custom module sub here.
End Sub

If you only want to run the external command sometimes do something like this. Create your macro like this:

Public runExternalCommandOnComplete As Boolean = False

Sub PublishAndRunExternalCommand()

    DTE.Windows.Item(Constants.vsWindowKindSolutionExplorer).Activate()
    DTE.ActiveWindow.Object.GetItem("04 - Products\04 - Products.WSS").Select(vsUISelectionType.vsUISelectionTypeSelect)
    DTE.ExecuteCommand("ClassViewContextMenus.ClassViewProject.Publish")

    runExternalCommandOnComplete = True

End Sub

Then in EnvironmentEvents add this: (Note: CustomMacros is the name of the module where you put the code above)

<System.contextStaticAttribute()> Public WithEvents PublishEvents As EnvDTE80.PublishEvents

Private Sub PublishEvents_OnPublishDone(ByVal Success As Boolean) Handles PublishEvents.OnPublishDone
   CustomMacros.runExternalCommandOnComplete = False
   'Where ExternalCommand1 matches the command you want to run
   DTE.ExecuteCommand("Tools.ExternalCommand1")  
End Sub

That should do it.

Cheers,

Kyle

Kyle Finley
It looks good, I will try it.
TcKs
Iw works for publish (+1), but it does not solve the other commands (I'm not sure, there is a solution).However, thans :)
TcKs
You could go ghetto with your other one and create some sort of file based mechanism for determining what to do. Basically call your external command using a batch file that does run synchronously and at the end drops a temp file somewhere. Back in VS create a sub that then watches for that file to exist. Once it does go ahead and fire off your other macro stuff and then clean up the file.Maybe a bit much but could work.
Kyle Finley
A: 

Here's how you can compile single file, and then link whole solution for example:

Dim WithEvents t As Timers.Timer

Sub test()
    DTE.ExecuteCommand("Build.Compile")
    t = New Timers.Timer
    t.Interval = 0.05
    t.Start()
End Sub

Sub t_Elapsed(ByVal ee As Object, ByVal dd As Timers.ElapsedEventArgs) Handles t.Elapsed

    If DTE.Solution.SolutionBuild.BuildState <> vsBuildState.vsBuildStateInProgress Then
        t.Stop()
        DTE.ExecuteCommand("Build.Link")
    End If

End Sub
AareP