none
Deleted $destinationdirectory$ folder comes back after RunFinished is done

    Question

  • I have an IWizard that calls "AddFromTemplate" for my projects (so I can add them where I want).

    Because my IWizard runs on a ProjectGroup template, I get an extra folder that I don't want at the solution level.

    For the last line of IWizard.RunFinished() I delete that folder ($destinationdirectory$)

    As I step over it, I go and check the folder and it has deleted. :)

    But then I let the Wizard finish (basically returning control back to Visual Studio).  When I do that the folder is recreated! :(

    What can I do to actually delete this folder and keep it deleted?

    (NOTE: there is nothing in this folder before I delete it or after it is "Restored", but it is clutter that I don't want to have hanging around.)


    • Edited by Vaccanoll Monday, March 26, 2012 4:10 AM
    Monday, March 26, 2012 4:07 AM

Answers

  • Hi Vaccanoll,

    Sadly, we're running into a C# project type requirement here. Managed projects like C#, VB.NET both require a new folder. Neither project system handles collisions where files might already exist. So they basically ignore the CreateNewFolder tag in the .vstemplate.

    The problem is that the folder gets regenerated after the wizard exits, and I can't see any way around this, except perhaps by creating a project subtype (which is whole lot of effort to try and work around this behavior).

    One other suggestion though that I haven't tried. If you delete the directory from your RunFinished, you could then set up a FileSystemEventHandler on a static FileSystemWatcher, and look for the subsequent directory creation, and turn around and delete it again, and then remove the handler from the wizards static FileSytemWatcher. That might allow you to avoid instructing the user to remove the directory manually.

    Sincerely,


    Ed Dore

    Friday, March 30, 2012 10:48 PM
    Moderator
  • Here is my .vstemplate:

    <VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="ProjectGroup">
      <TemplateData>
        <Name>Prism Service</Name>
        <Description>Used to create a Prism service to run web services or client side business logic.</Description>
        <ProjectType>CSharp</ProjectType>
        <ProjectSubType>
    	</ProjectSubType>
        <SortOrder>1000</SortOrder>
        <CreateNewFolder>true</CreateNewFolder>
        <DefaultName>PrismService</DefaultName>
        <ProvideDefaultName>true</ProvideDefaultName>
        <LocationField>Enabled</LocationField>
        <EnableLocationBrowseButton>true</EnableLocationBrowseButton>
        <Icon>__TemplateIcon.ico</Icon>
      </TemplateData>
      <TemplateContent>
      </TemplateContent>
      <WizardExtension>
        <Assembly>ServiceWizard, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f604bcbedad09eca</Assembly>
        <FullClassName>ServiceWizard.PrismServiceWizard</FullClassName>
      </WizardExtension>
    </VSTemplate>

    The last line in my ServiceWizard.PrismServiceWizard's RunComplete method is
    Directory.Delete(originalDestinationDirectory);
    

    And in RunStarted this line is run:

    originalDestinationDirectory = replacementsDictionary["$destinationdirectory$"];
    

    Just as an FYI, I have temporally worked around this issue with this method:                  

    privatevoid DeleteDestinationDirectory() {     Directory.Delete(originalDestinationDirectory);     // For some reason visual studio likes to put the folder back after we delete it.
    //  Start a timer that will check 10 times for the folder and delete it.
    //  If it is back on the 11th try then tell the user to delete it manually
    Timer
     timer = newTimer {Interval = 5000};     int tickCount = 0;     timer.Tick += (x, y) =>      {         if (Directory.Exists(originalDestinationDirectory))         {             Directory.Delete(originalDestinationDirectory);             tickCount++;             if (tickCount > 10)             {                 timer.Enabled = false;                 timer.Dispose();                 MessageBox.Show("Unable to delete extra directory " + originalDestinationDirectory +                                 ".  Please delete it manually.");             }         }         else         {             timer.Enabled = false;             timer.Dispose();         }     };     timer.Enabled = true; }

    I consider this a hack and would like to have a cleaner way to delete this folder. However, I am fine to use this workaround if there is no way to fix this.

    (I have moved on the "SolutionFolder can't be inserted at solution level" bug/issue and would much rather have time spent looking at that than at this.)







    • Edited by Vaccanoll Thursday, March 29, 2012 8:35 PM
    • Marked as answer by Vaccanoll Friday, March 30, 2012 10:51 PM
    Thursday, March 29, 2012 8:15 PM

All replies

  • Hi Vaccanoll,

    I'm a little bit not clear about why you need to delete the folder " $destinationdirectory$",  based on my knowledge, this folder is about the location where the new project is saved. What I can image is that, Visual Studio will save the whole projects / solutions after the template full generated, then such folder is recreated.

    Regards,

    Yi


    Yi Feng Li [MSFT]
    MSDN Community Support | Feedback to us

    Tuesday, March 27, 2012 4:50 AM
    Moderator
  • As I said in the first line in my question, I manually add the projects I want. This is a common practice with projectgroup templates because that kind of template adds an extra folder between your projects and your solution.

    Also projectgroup templates cannot do parameter substitution on solution folders.

    I have my template and wizard all working great. Except that I can't keep the empty default directory deleted.
    • Edited by Vaccanoll Tuesday, March 27, 2012 2:30 PM
    Tuesday, March 27, 2012 2:24 PM
  • Hi Vaccanoll,

    I am trying to involve someone familiar with this topic to further look at this issue. There might be some time delay. Appreciate your patience.
    Thank you for your understanding and support.

    Yi


    Yi Feng Li [MSFT]
    MSDN Community Support | Feedback to us

    Thursday, March 29, 2012 8:24 AM
    Moderator
  • This could be due to the solution project type adding it back in, but I'm not entirely certain without being able to debug a repro case.

    Can you post some additional details?

    Is your wizard for a multi-project template (I'm guessing that's what you mean by a "ProjectGroup" template). Can you post the content of the .vstemplate for this projectgroup template? That should provide enough detail for me to create a repro.

    Thanks,


    Ed Dore

    Thursday, March 29, 2012 8:02 PM
    Moderator
  • Here is my .vstemplate:

    <VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="ProjectGroup">
      <TemplateData>
        <Name>Prism Service</Name>
        <Description>Used to create a Prism service to run web services or client side business logic.</Description>
        <ProjectType>CSharp</ProjectType>
        <ProjectSubType>
    	</ProjectSubType>
        <SortOrder>1000</SortOrder>
        <CreateNewFolder>true</CreateNewFolder>
        <DefaultName>PrismService</DefaultName>
        <ProvideDefaultName>true</ProvideDefaultName>
        <LocationField>Enabled</LocationField>
        <EnableLocationBrowseButton>true</EnableLocationBrowseButton>
        <Icon>__TemplateIcon.ico</Icon>
      </TemplateData>
      <TemplateContent>
      </TemplateContent>
      <WizardExtension>
        <Assembly>ServiceWizard, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f604bcbedad09eca</Assembly>
        <FullClassName>ServiceWizard.PrismServiceWizard</FullClassName>
      </WizardExtension>
    </VSTemplate>

    The last line in my ServiceWizard.PrismServiceWizard's RunComplete method is
    Directory.Delete(originalDestinationDirectory);
    

    And in RunStarted this line is run:

    originalDestinationDirectory = replacementsDictionary["$destinationdirectory$"];
    

    Just as an FYI, I have temporally worked around this issue with this method:                  

    privatevoid DeleteDestinationDirectory() {     Directory.Delete(originalDestinationDirectory);     // For some reason visual studio likes to put the folder back after we delete it.
    //  Start a timer that will check 10 times for the folder and delete it.
    //  If it is back on the 11th try then tell the user to delete it manually
    Timer
     timer = newTimer {Interval = 5000};     int tickCount = 0;     timer.Tick += (x, y) =>      {         if (Directory.Exists(originalDestinationDirectory))         {             Directory.Delete(originalDestinationDirectory);             tickCount++;             if (tickCount > 10)             {                 timer.Enabled = false;                 timer.Dispose();                 MessageBox.Show("Unable to delete extra directory " + originalDestinationDirectory +                                 ".  Please delete it manually.");             }         }         else         {             timer.Enabled = false;             timer.Dispose();         }     };     timer.Enabled = true; }

    I consider this a hack and would like to have a cleaner way to delete this folder. However, I am fine to use this workaround if there is no way to fix this.

    (I have moved on the "SolutionFolder can't be inserted at solution level" bug/issue and would much rather have time spent looking at that than at this.)







    • Edited by Vaccanoll Thursday, March 29, 2012 8:35 PM
    • Marked as answer by Vaccanoll Friday, March 30, 2012 10:51 PM
    Thursday, March 29, 2012 8:15 PM
  • Hi Vaccanoll,

    Sadly, we're running into a C# project type requirement here. Managed projects like C#, VB.NET both require a new folder. Neither project system handles collisions where files might already exist. So they basically ignore the CreateNewFolder tag in the .vstemplate.

    The problem is that the folder gets regenerated after the wizard exits, and I can't see any way around this, except perhaps by creating a project subtype (which is whole lot of effort to try and work around this behavior).

    One other suggestion though that I haven't tried. If you delete the directory from your RunFinished, you could then set up a FileSystemEventHandler on a static FileSystemWatcher, and look for the subsequent directory creation, and turn around and delete it again, and then remove the handler from the wizards static FileSytemWatcher. That might allow you to avoid instructing the user to remove the directory manually.

    Sincerely,


    Ed Dore

    Friday, March 30, 2012 10:48 PM
    Moderator