Как добавить System.Windows.Forms в консольное приложение c# .NET Framework?
Пробовал добавить в .csproj файл <UseWindowsForms>true</UseWindowsForms>
но ничего не получилось
Вот полный код:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{8FB8E7FB-7C5A-4137-953A-8D5DEF40DE5D}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>PcController</RootNamespace>
<AssemblyName>PcController</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<UseWindowsForms>true</UseWindowsForms>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Functions.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
Трансферное обучение с предобученными моделями в Keras с Python
AI_Generated 06.05.2025
Суть трансферного обучения проста: взять модель, которая уже научилась решать одну задачу, и адаптировать её для решения другой, похожей задачи. Мозг человека работает по схожему принципу. Изучив. . .
Циклические зависимости в C#: методы управления и устранения
stackOverflow 06.05.2025
Если вы хоть раз работали над не самым тривиальным проектом на C#, то наверняка сталкивались с той ситуацией, когда компилятор вдруг начинает сыпать странными ошибками о невозможности разрешить. . .
Как перейти от Waterfall к Agile
EggHead 06.05.2025
Каскадная модель разработки Waterfall — классический пример того, как благие намерения превращаются в организационный кошмар. Изначально созданная для упорядочивания хаоса и внесения предсказуемости. . .
Оптимизация SQL запросов — Продвинутые техники
Codd 06.05.2025
Интересно наблюдать эволюцию подходов к оптимизации. Двадцать лет назад всё сводилось к нескольким простым правилам: «Избегайте SELECT *», «Используйте индексы», «Не джойните слишком много таблиц». . . .
Создание микросервисов с gRPC и Protobuf в C++
bytestream 06.05.2025
Монолитные приложения, которые ещё недавно считались стандартом индустрии, уступают место микросервисной архитектуре — подходу, при котором система разбивается на небольшие автономные сервисы, каждый. . .
Многопоточность и параллелизм в Python: потоки, процессы и гринлеты
py-thonny 06.05.2025
Параллелизм и конкурентность — две стороны многопоточной медали, которые постоянно путают даже бывалые разработчики.
Конкурентность (concurrency) — это когда ваша программа умеет жонглировать. . .
Распределенное обучение с TensorFlow и Python
AI_Generated 05.05.2025
В машинном обучении размер имеет значение. С ростом сложности моделей и объема данных одиночный процессор или даже мощная видеокарта уже не справляются с задачей обучения за разумное время. Когда. . .
CRUD API на C# и GraphQL
stackOverflow 05.05.2025
В бэкенд-разработке постоянно возникают новые технологии, призванные решить актуальные проблемы и упростить жизнь программистам. Одной из таких технологий стал GraphQL — язык запросов для API,. . .
Распознавание голоса и речи на C#
UnmanagedCoder 05.05.2025
Интеграция голосового управления в приложения на C# стала намного доступнее благодаря развитию специализированных библиотек и API. При этом многие разработчики до сих пор считают голосовое управление. . .
Реализация своих итераторов в C++
NullReferenced 05.05.2025
Итераторы в C++ — это абстракция, которая связывает весь экосистему Стандартной Библиотеки Шаблонов (STL) в единое целое, позволяя алгоритмам работать с разнородными структурами данных без знания их. . .
Posting Permissions
Forum Rules |
|
PowerShell is an advanced shell with integration of .NET objects. It’s more than just a replacement for the older cmd.exe
. It can work with .NET assemblies, process large datasets and even interact with web services.
Because of the .NET assemblies support, it can work with WinForms (or even WPF), making it possible to create scripts with GUIs.
Requirements
This has been tested to work with Windows PowerShell verion 5.1. It’s likely going to work with older versions as well, but it’s not going to work with the new cross-platform PowerShell (there are no WinForms on Linux/macOS). You can check the version with
Get-Host | Select-Object version
Enter fullscreen mode
Exit fullscreen mode
Setting up the environment
Before we can start, let’s check a few things.
The first one is the script execution policy. It controls which scripts can be run. By default, Windows blocks execution of all scripts (more on that here). We have to allow it to run local scripts that are not digitally signed. It’s possible to do this this either by going through Windows Settings > Updates & Security > For developers, checking the Change execution policy… checkbox and clicking Apply, or just executing
Set-ExecutionPolicy RemoteSigned
Enter fullscreen mode
Exit fullscreen mode
from administrator PowerShell.
Another (less important) thing is the code editor. Even though we could just write the entire script directly in PowerShell, it’s easier to use a full-featured editor with error checking and syntax highlighting. Windows already comes with PowerShell ISE (Integrated Scripting Environment), but you can use Visual Studio Code with the PowerShell extension.
Writing our script
Let’s start!
Importing the assemblies
We have to import both System.Windows.Forms
and System.Drawing
assemblies. It’s possible to only include the first one but we also need the 2nd to specify control sizes.
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
Enter fullscreen mode
Exit fullscreen mode
You can test it by creating a blank form:
$form = New-Object System.Windows.Forms.Form
$form.ShowDialog()
Enter fullscreen mode
Exit fullscreen mode
Adding controls
Let’s make a «Hello World» form. First, we create a top-level Form
object:
$form = New-Object System.Windows.Forms.Form
$form.Text = "Some form"
$form.Size = New-Object System.Drawing.Size(150, 145)
$form.AutoSize = $true
Enter fullscreen mode
Exit fullscreen mode
In PowerShell, objects are created using New-Object
. You can also pass parameters to constructors, similar to the new
keyword in C#. Values are assigned to properties directly. Another difference is using $true
instead of just true
.
Let’s add a label and a button:
$lbl1 = New-Object System.Windows.Forms.Label
$lbl1.Text = "Hello World!"
$lbl1.Location = New-Object System.Drawing.Point(30, 20);
$btn = New-Object System.Windows.Forms.Button
$btn.Text = "Close"
$btn.location = New-Object System.Drawing.Point(30, 60);
$btn.DialogResult = [System.Windows.Forms.DialogResult]::OK
Enter fullscreen mode
Exit fullscreen mode
The $btn.DialogResult
line tells the form what to return when the button is clicked. You can use this to figure out whether the user clicked OK or Cancel. We also make $btn
the default button and lay controls onto the form:
$form.AcceptButton = $btn
$form.controls.Add($lbl1)
$form.controls.Add($btn)
Enter fullscreen mode
Exit fullscreen mode
All that’s left is showing the form itself:
$form.ShowDialog()
Enter fullscreen mode
Exit fullscreen mode
Event handlers
In our form, $btn
is the default OK button which just terminates the form. But we can use non-terminating event handlers as well. For example, let’s make it possible to click on the label:
$lbl1.Add_Click({
[System.Windows.Forms.MessageBox]::Show("Hey!")
})
Enter fullscreen mode
Exit fullscreen mode
You can call functions from event handlers as you normally would.
Visual Styles
Something I’ve noticed with these GUI scripts is that different control styles are used when the script is run from the PowerShell console instead of VSCode. The console uses legacy rendering which falls back to using Windows 95-style controls. We need to enable Visual Styles to fix that:
[System.Windows.Forms.Application]::EnableVisualStyles()
Enter fullscreen mode
Exit fullscreen mode
From here on, you can add more controls and event handlers. If you’ve used C#/VB.NET before you can reuse large parts of that knowledge to create nicer and more powerful scripts.
That’s it for now 😉
The full script:
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
[System.Windows.Forms.Application]::EnableVisualStyles()
$form = New-Object System.Windows.Forms.Form
$form.Text = "Some form"
$form.Size = New-Object System.Drawing.Size(150, 145)
$form.AutoSize = $true
$lbl1 = New-Object System.Windows.Forms.Label
$lbl1.Text = "Hello World!"
$lbl1.Location = New-Object System.Drawing.Point(30, 20);
$lbl1.Add_Click({
[System.Windows.Forms.MessageBox]::Show("Hey!")
})
$btn = New-Object System.Windows.Forms.Button
$btn.Text = "Close"
$btn.location = New-Object System.Drawing.Point(30, 60);
$btn.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $btn
$form.controls.Add($lbl1)
$form.controls.Add($btn)
$Null = $form.ShowDialog()
Enter fullscreen mode
Exit fullscreen mode
-
#1
I’m converting to Net5. I have 40 out of 41 projects converted OK
The remaining project will not let me reference System.WindowsForms.
There are two versions of System.WindowsForms, I’ve been using 2.4 routinely (I hope that’s what I should be doing).
I tried them both in the troublesome procedure.
What happens is: I select Project/Add COM Reference and then check System.WindowsForms.
Close the dialog and reopen it and see that the check is gone.
I did this because checking it did not have any effect on the error I was trying to fix.
I’m using System.Windows.Forms.StatusBarPanel. Could that be a problem in Net5?
BTW. I also tried including:
<ItemGroup>
<Import Include="Microsoft.VisualBasic" />
<Import Include="System" />
<Import Include="System.Collections" />
<Import Include="System.Collections.Generic" />
<Import Include="System.Data" />
<Import Include="System.Drawing" />
<Import Include="System.Diagnostics" />
<Import Include="System.Windows.Forms" />
<Import Include="System.Linq" />
<Import Include="System.Xml.Linq" />
<Import Include="System.Threading.Tasks" />
</ItemGroup>
In that case I also checked System.WindowsForms (I’m not sure it would show checked) but it was not checked.
Last edited:
-
JohnH
I’m using System.Windows.Forms.StatusBarPanel. Could that be a problem in Net5?
StatusBarPanel Class (System.Windows.Forms)
Represents a panel in a StatusBar control. This class is not available in .NET 5 and later versions. Use the ToolStripStatusLabel control instead, which replaces and extends the StatusBarPanel control.
docs.microsoft.com
This class is not available in .NET 5.0 and later versions. Use the StatusStrip control instead, which replaces and extends the StatusBar control.
MenuStrip/ToolStrip/StatusStrip were introduced as replacements for Menu/ToolBar/StatusBar in .Net 2.0.
JohnH
VB.NET Forum Moderator
-
#2
I’m using System.Windows.Forms.StatusBarPanel. Could that be a problem in Net5?
StatusBarPanel Class (System.Windows.Forms)
Represents a panel in a StatusBar control. This class is not available in .NET 5 and later versions. Use the ToolStripStatusLabel control instead, which replaces and extends the StatusBarPanel control.
docs.microsoft.com
This class is not available in .NET 5.0 and later versions. Use the StatusStrip control instead, which replaces and extends the StatusBar control.
MenuStrip/ToolStrip/StatusStrip were introduced as replacements for Menu/ToolBar/StatusBar in .Net 2.0.
JohnH
VB.NET Forum Moderator
-
#3
The remaining project will not let me reference System.WindowsForms.
There are two versions of System.WindowsForms, I’ve been using 2.4 routinely (I hope that’s what I should be doing).
I tried them both in the troublesome procedure.
What happens is: I select Project/Add COM Reference and then check System.WindowsForms.
No, you shouldn’t. When <UseWindowsForms> is added to SDK project file the Microsoft.WindowsDesktop.App.WindowsForms framework dependency is added, this includes .Net 5 version of System.Windows.Forms.dll. Expand Dependencies in Solution Explorer and you’ll see it.
JohnH
VB.NET Forum Moderator
-
#4
The Import Includes in project file is for importing namespaces (at project level) for existing referenced assemblies by the way.
-
#5
It should just be «Import System.Windows.Forms» less the quotation marks and remebering the «.» period(s).
-
#6
It should just be «Import System.Windows.Forms» less the quotation marks and remebering the «.» period(s).
Nope. That’s just importing a namespace at the file level. It’s only tangentially related to referencing an assembly.
-
#7
Nope. That’s just importing a namespace at the file level. It’s only tangentially related to referencing an assembly.
Ah well he/she did state in their first post that:
There are two versions of System.WindowsForms, I’ve been using 2.4 routinely (I hope that’s what I should be doing).
and I just seen they missed a period, so ty for correcting me .
ProtekNickz xD
-
#8
Microsoft.Common.CurrentVersion.targets(2701,5): warning MSB3290: Failed to create the wrapper assembly for type library «{215d64d2-031c-33c7-96e3-61794cd1ee61}». Type library ‘System_Windows_Forms’ was exported from a CLR assembly and cannot be re-imported as a CLR assembly.
No, you shouldn’t. When <UseWindowsForms> is added to SDK project file the Microsoft.WindowsDesktop.App.WindowsForms framework dependency is added, this includes .Net 5 version of System.Windows.Forms.dll. Expand Dependencies in Solution Explorer and you’ll see it.
Thanks for the above. I’m getting use to looking at the Dependencies!
If I understand what you told me I have duplicates WindowsForms entries in the code below.
I think this {215d64d2-031c-33c7-96e3-61794cd1ee61} related to windowsforms (where is there a list of such Guids?)
And I think it is there because I added the reference to remove an error message.
If I now remove it I get many WindowsForms error messages again.
Like: MessageBox is not declared.
I’d appreciate any suggestions related to fixing the below.
BTW. It works as is but I want to take you reply seriously.
I’m still working on the other’s replies!
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>Cag.TextEditor</RootNamespace>
<TargetFramework>net5.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<MyType>WindowsForms</MyType>
</PropertyGroup>
<ItemGroup>
<COMReference Include="{215d64d2-031c-33c7-96e3-61794cd1ee61}">
<WrapperTool>tlbimp</WrapperTool>
<VersionMinor>4</VersionMinor>
<VersionMajor>2</VersionMajor>
<Guid>215d64d2-031c-33c7-96e3-61794cd1ee61</Guid>
</COMReference>
<COMReference Include="tom.dll">
<WrapperTool>tlbimp</WrapperTool>
<VersionMinor>0</VersionMinor>
<VersionMajor>1</VersionMajor>
<Guid>8cc497c9-a1df-11ce-8098-00aa0047be5d</Guid>
<Lcid>0</Lcid>
<Isolated>false</Isolated>
</COMReference>
<COMReference Include="{bee4bfec-6683-3e67-9167-3c0cbc68f40a}">
<WrapperTool>tlbimp</WrapperTool>
<VersionMinor>4</VersionMinor>
<VersionMajor>2</VersionMajor>
<Guid>bee4bfec-6683-3e67-9167-3c0cbc68f40a</Guid>
</COMReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BitmapEditor\BitmapEditor.vbproj" />
<ProjectReference Include="..\ColorUtilities\ColorUtilities.vbproj" />
<ProjectReference Include="..\FractionUpDown\FractionUpDown.vbproj" />
<ProjectReference Include="..\LibraryCs2\LibraryCs2.csproj" />
<ProjectReference Include="..\LibraryDisk1\LibraryDisk1.vbproj" />
<ProjectReference Include="..\LibraryGraphic2\LibraryGraphic2.vbproj" />
<ProjectReference Include="..\LibraryNative0\LibraryNative0.vbproj" />
<ProjectReference Include="..\LibraryPrinter1\LibraryPrinter1.vbproj" />
<ProjectReference Include="..\LibraryTextEditor2\LibraryTextEditor2.vbproj" />
<ProjectReference Include="..\LibraryVb0\LibraryVb0.vbproj" />
<ProjectReference Include="..\LibraryVb1\LibraryVb1.vbproj" />
<ProjectReference Include="..\LibraryVb3\LibraryVb3.vbproj" />
<ProjectReference Include="..\UpDowns\UpDowns.vbproj" />
</ItemGroup>
</Project>
JohnH
VB.NET Forum Moderator
-
#9
You’re missing the namespace imports at project level. (the Import Include)
In case you didn’t know, you add references to assemblies (dll libraries) which in this case is part of single huge dependency package so that they can be loaded when your app loads, and import namespaces in order to use classes within those libraries. One dll can have many classes/types organized into namespaces. Some namespaces are imported at project project level because they are used all over the place, for example the System.Windows.Forms namespace, others that you use more occationally in a single code file you import with the Imports statement at top of the code file.
-
#10
You’re missing the namespace imports at project level. (the Import Include)
1)Are you refering to
<OutputType>WinExe</OutputType>
What I should have included but didn’t is the fact that in the file that works under Dependencies / Frameworks there is
MicrosoftWindowsDesktop.App.WindoesForms and, in the project file I have 215d64d2-031c-33c7-96e3-61794cd1ee61
I think I shouldn’t need nor want two references to WindowsForms.
2)If I now remove {215d64d2-031c-33c7-96e3-61794cd1ee61} I get many WindowsForms error messages again.
Like: MessageBox is not declared.
I may have misinterpreted your earlier message but I thought MicrosoftWindowsDesktop.App.WindoesForms was what I needed.
JohnH
VB.NET Forum Moderator
-
#11
No I said
Import Include
. As explained to be able to use a library it must be referenced that is that <UseWindowsForms> does, it add a bunch of libraries. Then you must import the namespaces, if not every type used in code must be qualified with the namespace, for example you can’t write MessageBox
, it must be System.Windows.Forms.MessageBox
. Obviously a form with lots of Forms types in generated code will not compile.
This is also explained in point 3 of VB extras in the migration guide that I posted before: Migrate a Windows Forms app to .NET 5 — Windows Forms .NET