How to create a F# based Visual Studio Add-In? - visual-studio

Even with F# installed, Visual Studio 2008 (and probably 2010) only provides Add-In project templates for C#, VB.NET and C++.
So, how to create a F# based Add-In?
I have tried to create a F# class library project with a new class implementing IDTExtensibility2, setting the correct references (EnvDTE, Extensibility, ...), copying a few project attributes from the C# Add-In (mainly the command line for debugging), and creating the .AddIn manifest file by hand, but no success. When VS is launched, my Add-In is not listed in the available ones.
What are the missing steps? Some kind of COM registration somewhere?

I've not tried this exact scenario, but the general strategy I've had the best luck with is: start with the C# template, rename the .csproj to .fsproj and change the <Import>s for F# and replace the <Compile> of C# code with F# code, and go from there.
The templates often have various important logic in them for build/deployment, so start with a working template for C# and tweak it for F#.

I finally found what went wrong: I simply forgot to put the .AddIn file in the AddIn directory (the C# wizard is doing this automatically).
So, to create a F# based Add-In for Visual Studio:
Create a new F# class library project
Add a few reference assemblies to the project (mainly EnvDTE, EnvDTE80, EnvDTE90, Extensibility)
Create a new class implementing IDTExtensibility2
Copy the debugging properties of a C# based Add-In project into your F# project
Copy the .AddIn manifest file, and modify it according to your F# project
*.. and don't forget to copy that new file in the AddIn directory for the user session
enjoy!

Related

F# VS2019 Windows Forms

I'm learning F# and I'm just trying to build Animate a pendulum program.
Here's the code:
https://rosettacode.org/wiki/Animate_a_pendulum#F.23
As far as I understand, VS 2019 doesn't support WinForms in F# (maybe, I'm wrong), so I have error messages, trying to copy/paste that code:
What should I do?
Thanks a lot !
If you're looking to use Winforms on .NET core, you'll need to do the following in your project:
Open the project file (double-click on the node in Visual Studio)
Change the Sdk to Microsoft.NET.Sdk.WindowsDesktop
Ensure you have this OutputType: <OutputType>WinExe</OutputType>
Add the following property to the top-level PropertyGroup: <UseWindowsForms>true</UseWindowsForms>
There won't be a visual designer to use, but you should have access to the APIs.
Unfortunately, there is no Winforms designer in Visual Studio 2019 for F# projects of any type, and Winforms can only be easily accessed (as far as I know) in .Net Framework (NOT .NET Core) projects they can be accessed as per #Phillip Carter's answer.
However you can still make Winforms programs easily by manually adding the references to your .NET Framework project, or (more easily) by manually compiling with the F# compiler, fsc.
The Fast Way
The easiest way to do this is simply compile the source code with the F# compiler from a single source file with fsc.exe. The F# compiler will automatically resolve dependencies for things like System.Windows.Forms and a lot of other commonly used namespaces. You can also provide lots of compiler directives for requiring other resources as well.
Example using VSCode, with various extensions:
Another Way
Start a new F# console .NET Framework project (don't pick .NET Core).
Right click on "References" in the Solution Explorer and click "Add Reference..."
Under assemblies, look for "System.Windows.Forms," select it...
And also select "System.Drawing" and then hit OK
Now you have access to both of those namespaces.
Before you run the project in Visual Studio, you should replace
[<STAThread>]
Application.Run( new PendulumForm( Visible=true ) )
with
[<STAThread;EntryPoint>]
let main _ =
Application.Run( new PendulumForm( Visible=true ) )
0
This way you (and VS) know where main actually is. It's not necessary for this small of a program to actually run it, but as your projects get larger VS will complain more about where things are located in your project.

How to associate item templates with Project Type in Visual Studio 2019?

I would like to create a new F# Web ASPNET (not Core) Application using the MSBuild based legacy project format, not the SDK project. In Visual Studio 2019, the only available option for this project type is C#. I've attempted to reverse engineer the project setup by creating a new F# class library and modify the ProjectTypeGuids.
The C# Web Application uses the following project type GUIDs
349c5851-65df-11da-9384-00065b846f21 - ASP.NET MVC 5
fae04ec0-301f-11d3-bf4b-00c04f79efbc - C#
On a basic F# .NET Framework class library, I attempted to add the ASP.NET and F# project type guids to the project.
<ProjectTypeGuids>{349C5851-65DF-11DA-9384-00065B846F21};{F2A71F9B-5D33-465A-A702-920D77279786}</ProjectTypeGuids>
This succeeded in adding the web configuration to the project properties, but now I am unable to add any items to the project at all. It looks like in the past you needed to associate the right language templates with the project guid in the registry editor (see this link)
These entries don't appear to be anywhere that I can see in the registry, for any installed version of VS (which at this point is just 2017 and 2019). How can I enable F# item templates for my F# web application?
While not exactly an answer to the question, I think the pain of trying to do this is likely proof that you SHOULDN'T do this. In the end my approach will be to simply implement the Web Application in C#, while keeping as much code as possible in F# targeting netstandard.

Code generation in Visual Studio based on all files with a given extension

I have the following task: Make a visual editor in Visual Studio (not the core of today's question) which results in a text file, on a custom format. This file will then be used as input for code generation resulting in C# code. For this, I've been looking at:
T4
Visual Studio Extensions
Visual Studio Project Templates
Visual Studio Item Templates
I feel the solution is there somewhere, but I can't quite figure out how best to do it. As I see it, the main problem is somehow to automatically generate code for all files with a given extension. Does anyone know of any tutorials or descriptions on how to do this?
Thanks in advance!
To automatically associate a code generator with all files of a given extension, you need to
Create a Visual Studio package
Implement a custom IVsSingleFileGenerator. The easiest option is to subclass the BaseTemplatedCodeGenerator and override its GenerateCode method to supply your own T4 template as the "inputFileContent".
Use the ProvideCodeGeneratorAttribute to register the generator.
Use the ProvideCodeGeneratorExtensionAttribute to associate the generator with a file extension.
Create a VSIX with your package and generator and have your users install it.

VS Workflow designer not expanding activities

I can't figure out why some activities in the WF designer do not expand.
Looking at the sample documentation for the WizardActivityPack activities:
But when I try to open the same file in Visual Studio 2010's WF designer:
If I look at the file using the XML editor I can see all the activities are in the file, but the designer only shows me the one box and I cannot click into or expand it.
You have to place the *.design.dll somewhere that visual studio can find it. Like in the %programfiles(x86)%\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies.
VS looks for designers by convention; if the activities are in an assembly called Activity.dll, VS looks for its design classes in an assembly called Activity.Design.dll under VS' codebase (and subdirectories) or (I believe) in the GAC.
This fact is important to know when creating your own activities/designers! The reason behind this is so that your Activity assembly doesn't need to reference the Designers dll; you can deliver the Activity assembly by itself to production while leaving the Designers dll on the design machine.
(If you reference the *.Design.dll from your Activities assembly, or if they exist in the same assembly, this doesn't apply. The recommended pattern is to separate the two and allow VS to load them via convention. For an example of this, see this sample.)
add this line
new DesignerMetadata().Register();
to WPF presentation

What type of extension for VS (and how) to make, to generate C# or C++ code from some text [more so a model]?

I am new to Visual Studio Extensibility and want to make an addin/extension which shall do the following:
It should read all the files with a specific file extension (assume "*.ump").
It should process the text/code/whatever in the files.
It should create new Class/Code file with some code in it. [The code will be produced in step 2, just need to know how to do it?]
Yet, I have been racking my brains through extensibility, saw the single file generators .... and addins which go through ProjectItems and can detect the file extension,
BUT I HAVE NOT BEEN ABLE TO FIND a complete tutorial, guide or explanation as to how or what to do!!
Please help...
You don't want to read all files with a specific file extension in Visual C++ project nor standard Visual C# project. You may do that with hand-made MSBuild project (included in the solution).
In Visual C++ projects, there is a way to define custom tools. They are run as separate processes, so you can implement them in anything you want. Studio will ask you whether you want to define a tool (they are defined in special xml files; studio has dialog for editing them) when you add a file with extension unknown to it. In Visual C# projects, just manually write a MSBuild tasks and insert them into the project.
Do whatever you want. IIRC the generated files will have to be included in the project though. Well, for MSBuild, just tweak the project to your heart's desire, but in Visual C++ they have to.
You can combine MSBuild (csproj,vbproj) and VisualC++ projects in a single solution, so I recommend using separate.
If you ever find out you need to compile for different target where you can't use Visual Studio, you'll be glad that you have stand-alone tool you were just calling from Studio and not something that embeds in it.

Resources