Building a Visual Studio Package based on another one
Asked Answered
M

3

6

I want to add my own project type based on IronStudio. So,

  • I downloaded the source for and compiled the latest version of IronPython, then
  • I created a new Visual Studio Package.
  • I added the Templates\Projects\MyProject folders, and added a file to it, and set its property "Include in VSIX" to true.

Then modified the main Package class to be derived from IronStudio's PythonProjectPackage instead, and set the ProvideProjectFactory property:

[ProvideProjectFactory(
    typeof(PythonProjectFactory),
    "Django Project",
    "Django Project Files (*.myproj);*.myproj",
    "myproj", "myproj",
    @"Templates\Projects\MyProject",
    LanguageVsTemplate="MyProject")]
public sealed class MyPackage : PythonProjectPackage

And ran it. But MyProject isn't showing up in the project templates. Why not?

The generated .pkgdef file looks like this:

[$RootKey$\InstalledProducts\VSPackage3Package]
@="#110"
"Package"="{5cd7435c-7461-459f-80bc-c0c79e9d462f}"
"PID"="1.0"
"ProductDetails"="#112"
"LogoID"="#400"
[$RootKey$\Packages\{5cd7435c-7461-459f-80bc-c0c79e9d462f}]
@="Microsoft.VSPackage3.VSPackage3Package, VSPackage3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a4f1577d825253f8"
"InprocServer32"="$WinDir$\SYSTEM32\MSCOREE.DLL"
"Class"="Microsoft.VSPackage3.VSPackage3Package"
"CodeBase"="$PackageFolder$\VSPackage3.dll"
[$RootKey$\Editors\{888888c4-36f9-4453-90aa-29fa4d2e5706}]
"Package"="{5cd7435c-7461-459f-80bc-c0c79e9d462f}"
[$RootKey$\Editors\{888888c4-36f9-4453-90aa-29fa4d2e5706}\Extensions]
"py"=dword:00000020
[$RootKey$\Editors\{888888c4-36f9-4453-90aa-29fa4d2e5706}\LogicalViews]
"{7651a701-06e5-11d1-8ebd-00a0c90f26ea}"=""
[$RootKey$\Editors\{888888c4-36f9-4453-90aa-29fa4d2e5706}\LogicalViews]
"{7651a702-06e5-11d1-8ebd-00a0c90f26ea}"=""
[$RootKey$\Editors\{888888c4-36f9-4453-90aa-29fa4d2e5706}\LogicalViews]
"{7651a703-06e5-11d1-8ebd-00a0c90f26ea}"=""
[$RootKey$\CLSID\{888888fd-3c4a-40da-aefb-5ac10f5e8b30}]
@="Microsoft.IronPythonTools.Project.PythonGeneralPropertyPage"
"InprocServer32"="$WinDir$\SYSTEM32\MSCOREE.DLL"
"Class"="Microsoft.IronPythonTools.Project.PythonGeneralPropertyPage"
"CodeBase"="$PackageFolder$\VSPackage3.dll"
"ThreadingModel"="Both"
[$RootKey$\Projects\{888888a0-9f3d-457c-b088-3a5042f75d52}]
@="PythonProjectFactory"
"DisplayName"="My Project"
"DisplayProjectFileExtensions"="My Project Files (*.myproj);*.myproj"
"Package"="{5cd7435c-7461-459f-80bc-c0c79e9d462f}"
"DefaultProjectExtension"="myproj"
"PossibleProjectExtensions"="myproj"
"ProjectTemplatesDir"="$PackageFolder$\Templates\Projects\MyProject"
"Language(VsTemplate)"="MyProject"
[$RootKey$\NewProjectTemplates\TemplateDirs\{5cd7435c-7461-459f-80bc-c0c79e9d462f}\/1]
@="My Project"
"SortPriority"=dword:00000064
"TemplatesDir"="$PackageFolder$\Templates\Projects\MyProject"
[$RootKey$\Projects\{888888a0-9f3d-457c-b088-3a5042f75d52}]
@="PythonProjectFactory"
"DisplayName"="IronPython"
"DisplayProjectFileExtensions"="IronPython Project Files (*.pyproj);*.pyproj"
"Package"="{5cd7435c-7461-459f-80bc-c0c79e9d462f}"
"DefaultProjectExtension"="pyproj"
"PossibleProjectExtensions"="pyproj"
"ProjectTemplatesDir"="$PackageFolder$\.\NullPath"
"Language(VsTemplate)"="IronPython"
[$RootKey$\NewProjectTemplates\TemplateDirs\{5cd7435c-7461-459f-80bc-c0c79e9d462f}\/1]
@="IronPython"
"SortPriority"=dword:00000064
"TemplatesDir"="$PackageFolder$\.\NullPath"
[$RootKey$\Services\{b98e41c4-581e-3532-beee-06829b683d39}]
@="{5cd7435c-7461-459f-80bc-c0c79e9d462f}"
"Name"="IPythonStarter"

I just want to get the bare bones up and running so I can start overriding some functionality (like the Add New Item dialog).

Might answered 22/9, 2010 at 3:13 Comment(2)
Just noticed that PythonProjectFactory appears in there twice... probably not the way it should be.Might
Indeed - please note that there are more duplicated lines like e.g. the preceding GUID, see my answer for more on this.Congou
C
5

Update:

Reading my initial analysis once again increases my impression that some of the required components are missing (e.g. a dedicated ProjectFactory) and/or wired up incorrectly - from the MSDN documentation of the ProvideProjectFactoryAttribute Class:

ProvideProjectFactoryAttribute declares that a package provides a project factory.

And further:

If a VSPackage declares that it provides a project factory, it should create the factory and offer it to Visual Studio in the Initialize method of the Package-derived class.

You package is declaring to provide PythonProjectFactory, but (likely) doesn't offer it to VS, rather it is offered by the IronPython package. In turn you are providing arguments within the ProvideProjectFactory attribute list which PythonProjectFactory won't know about when asked for by VS.

Consequently you should at least provide a dedicated ProjectFactory yourself as per the walkthrough, wire up the classes accordingly and see how this turns out regarding the issues outlined below.


Initial analysis:

There appear to be several issues here at first sight - have you followed any tutorial on how to do this? In case, please note that some of those easily discoverable via search engines are outdated still. Either way I'd try working through and/or comparing your result with Walkthrough: Part 1 - Creating a Basic Project System from the MSDN documentation for VS 2010; please note that even this one is claimed to be outdated a bit according to the Community Content section on the bottom of the page.

Here is what I'd look into myself given the code you present, comparing with the walkthrough on the fly for more insights:

  • You realized already that the duplicate fragment starting with the GUID above PythonProjectFactory doesn't make sense - this is essentially trying to register two packages at once, which, even if allowed at all syntactically (which I doubt), can't possibly work like so due to both being registered with the same GUID [cross checking with the sample file in section Examining the Template Registration confirms this suspicion, as expected there is only one such fragment].

    • Please note that the GUID in question is the one identifying PythonProjectFactory (as per the respective source code), see below for more on this.
        [Guid(PythonConstants.ProjectFactoryGuid)]
        public class PythonProjectFactory : ProjectFactory {
  • Given .pkgdef is a generated file the next question is where this duplication/violation stems from. When two generated artifacts end up with the same GUID the respective definition in the sources is most likely messed up somehow, usually due to copy&paste duplication. Consequently you should verify whether {5cd7435c-7461-459f-80bc-c0c79e9d462f} is defined and referenced as intended, though here might be one or two other causes as well for this, see below.

  • A Package class needs to be identified by a GUID and the VS wizard generates some already in Guids.cs and references it accordingly on the class definition, however, the following is missing in your fragment [cross checking with the sample fragment in section To register the project template confirms this omission as well]:

    [Guid(GuidList.guidMyPackagePkgString)]
    public sealed class MyPackage : Package
  • Likewise it appears incorrect to derive MyPackage from PythonProjectPackage but reference PythonProjectFactory still rather than providing MyFactory as well (including a dedicated GUID), because the latter tells Visual Studio the location of your project template folder [see section Creating a Skeletal Project Factory]:

    • While it might well be possible to simply reuse all functionality from the base class PythonProjectFactory, inheriting is likely required simply because the factory must have a dedicated GUID too (as outlined in the walkthrough) in order to properly wire up the attribute specified data.

  • Likely unrelated, but still suspicious is that your two code blocks don't relate, as the Package class definition specifies Django Project Files (*.myproj);*.myproj, yet the result shows My Project Files (*.myproj);*.myproj.

    • Have you by chance mixed this from different builds or is this really a result of a clean one?

Good luck!

Congou answered 30/9, 2010 at 20:12 Comment(1)
This answer sounds like it has some merit, but I'm too exhausted to go through it right now. Will have to investigate this when I have some time. Thanks!Might
L
1

This stackoverflow posting might be helpful: VS2010: VSIX installation doesn't deploy item templates inside it

If this is not what you're looking for, try to see if you're missing something around the creation of custom project templates, I believe that's where the "missing link" is:

Hope this helps

Launderette answered 30/9, 2010 at 17:59 Comment(6)
Most of those links look like they describe how to create new project templates... I've done that already, piece of cake. I need more power than that though, I need to modify the build and run process, and add items to the right-click menu. For that, I'm pretty sure I need to create a VSPackage. Which I also figured out how to do (#3714003), the part I'm struggling with specifically, is extending IronPython. Your first link is a little more relevant (as its at least a step in the right direction),Might
but the answer was basically "look again", which... I did... several times.Might
A "new item template" is one of the bigger features I want to implement... except it needs to add a file, modify two others, so it's a bit more complicated. That, and be context aware ("create a new view template for the highlighted function").Might
Yeah, I know that one, the "look again"... And even if you look again, it might not help if you look again when you already looked again at 3AM and didn't see anything. So.. Should I post an answer: "Look again later"? :)Launderette
Oh, one more thing, the question didn't exactly signify why your IronPython problem was different from a generic "I can't add my template to Visual Studio" problem. :(Launderette
Fair enough. The problems could be related. But getting the template installed is only half the problem. I can successfully get the template installed thru a VSIX package, but just not when I try to extend IronPython. Basically, I'm looking for a tutorial to get me started. All the ones I've found explain how to extend C# or VB, but I haven't the faintest idea how to extend IronPython or another 3rd party language addon.Might
T
0

$PackageFolder$.\NullPath may have something to do with it.

Tanagra answered 30/9, 2010 at 18:2 Comment(1)
That file is auto-generated; I'm sure there are many flaws with it, but seeing as that I can't edit that file directly, it doesn't really help.Might

© 2022 - 2024 — McMap. All rights reserved.