* Move and consolidate overview

The previous "index" article was an old landing page that had only an introductory paragraph and then links to the additional articles in the section. Consolidate the opening paragraph with the overview.

* Move office How to article

Snippets haven't moved until I get clarity on sample story.

* Move indexed properties article

* move how to play a wave file

* Split and move the office programming walkthrough

Split this article in 2 while moving it. This will make it easier to find for VB developers looking for the VB version. And, the C# version reads more cleanly.

* Move example COM class

* remove duplicate redirection

* build warnings

* one more build warning

* move sample for example COM class

* move office walkthrough sample

* add PInvoke samples

Move the PInvoke sample to the new folder.

* move indexed sample

* fix the folder

* update for expected errors

* move final sample

* fix a build warning

* Move Office article on named / optional arguments.

* fix warnings

* more build issues

* one more build issue

* one more build error

* move using type dynamic

* move and duplicate dynamic walkthrough

* fix build error

* fix build warnings

* fix relative links to moved files.

* code review

* proofread and style updates.

* fix build warnings

* restore missing snippet

* respond to feedback

* ignore one more error

* test
This commit is contained in:
Bill Wagner 2023-02-24 13:02:43 -05:00 коммит произвёл GitHub
Родитель 3ab77f9dc6
Коммит df74cc5b2b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
89 изменённых файлов: 1664 добавлений и 1312 удалений

1
.gitignore поставляемый
Просмотреть файл

@ -57,3 +57,4 @@ docs/core/extensions/snippets/workers/cloud-service/Properties/PublishProfiles/c
docs/csharp/language-reference/xmldoc/snippets/xmldoc/xmldoc.xml
BenchmarkDotNet.Artifacts
*.pfx

Просмотреть файл

@ -1140,6 +1140,10 @@
"source_path_from_root": "/docs/csharp/programming-guide/classes-and-structs/how-to-know-the-difference-passing-a-struct-and-passing-a-class-to-a-method.md",
"redirect_url": "/dotnet/csharp/language-reference/keywords/method-parameters"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/classes-and-structs/how-to-use-named-and-optional-arguments-in-office-programming.md",
"redirect_url": "/dotnet/csharp/advanced-topics/interop/how-to-use-named-and-optional-arguments-in-office-programming"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/classes-and-structs/index.md",
"redirect_url": "/dotnet/csharp/fundamentals/object-oriented"
@ -2262,8 +2266,32 @@
"redirect_url": "/dotnet/csharp/fundamentals/types/interfaces"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/interop/interoperability.md",
"redirect_url": "/dotnet/csharp/programming-guide/interop/index"
"source_path_from_root": "/docs/csharp/programming-guide/interop/example-com-class.md",
"redirect_url": "/dotnet/csharp/advanced-topics/interop/example-com-class"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/interop/how-to-access-office-onterop-objects.md",
"redirect_url": "/dotnet/csharp/advanced-topics/interop/how-to-access-office-interop-objects"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/interop/how-to-use-indexed-properties-in-com-interop-rogramming.md",
"redirect_url": "/dotnet/csharp/advanced-topics/interop/how-to-use-indexed-properties-in-com-interop-programming"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/interop/how-to-use-platform-invoke-to-play-a-wave-file.md",
"redirect_url": "/dotnet/csharp/advanced-topics/interop/how-to-use-platform-invoke-to-play-a-wave-file"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/interop/index.md",
"redirect_url": "/dotnet/csharp/advanced-topics/interop/index"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/interop/interoperability-overview.md",
"redirect_url": "/dotnet/csharp/advanced-topics/interop/index"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/interop/walkthrough-office-programming.md",
"redirect_url": "/dotnet/csharp/advanced-topics/interop/walkthrough-office-programming"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/linq-query-expressions/how-to-create-a-nested-group.md",
@ -2505,6 +2533,14 @@
"source_path_from_root": "/docs/csharp/programming-guide/types/index.md",
"redirect_url": "/dotnet/csharp/fundamentals/types"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/types/using-type-dynamic.md",
"redirect_url": "/dotnet/csharp/advanced-topics/interop/using-type-dynamic"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/types/walkthrough-creating-and-using-dynamic-objects.md",
"redirect_url": "/dotnet/csharp/advanced-topics/interop/walkthrough-creating-and-using-dynamic-objects"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/unsafe-code-pointers/arithmetic-operations-on-pointers.md",
"redirect_url": "/dotnet/csharp/language-reference/operators/pointer-related-operators#pointer-arithmetic-operators"

Просмотреть файл

@ -508,7 +508,6 @@
"docs/csharp/programming-guide/strings/**/**.md": "csharp-fundamentals",
"docs/csharp/programming-guide/types/**/**.md": "csharp-fundamentals",
"docs/csharp/programming-guide/statements-expressions-operators/**/**.md": "csharp-fundamentals",
"docs/csharp/programming-guide/interop/**/**.md": "csharp-advanced-concepts",
"docs/csharp/programming-guide/exceptions/**/**.md": "csharp-fundamentals",
"docs/csharp/programming-guide/namespaces/**/**.md": "csharp-fundamentals",
"docs/csharp/programming-guide/arrays/**/**.md": "csharp-fundamentals",

Просмотреть файл

@ -286,6 +286,10 @@ items:
- name: Asynchronous programming
tocHref: /dotnet/csharp/asynchronous-programming
topicHref: /dotnet/csharp/asynchronous-programming/index
- name: Advanced concepts
tocHref: /dotnet/csharp/advanced-topics
topicHref: /dotnet/csharp/advanced-topics/index
- name: Tutorials
tocHref: /dotnet/csharp/tutorials/
topicHref: /dotnet/csharp/tutorials/index

Просмотреть файл

@ -0,0 +1,32 @@
---
title: "Example COM Class"
description: Learn how to expose a class as a COM object in C#. This example adds code in a .cs file to a project and sets the Register for COM Interop property.
ms.date: 02/15/2023
ms.topic: how-to
helpviewer_keywords:
- "examples [C#], COM classes"
- "COM, exposing C# objects to"
---
# Example COM Class
The following code is an example of a class that you would expose as a COM object. After you place this code in a .cs file added to your project, set the **Register for COM Interop** property to **True**. For more information, see [How to: Register a Component for COM Interop](/previous-versions/visualstudio/visual-studio-2010/w29wacsy(v=vs.100)).
Exposing C# objects to COM requires declaring a class interface, an "events interface" if necessary, and the class itself. Class members must follow these rules to be visible to COM:
- The class must be public.
- Properties, methods, and events must be public.
- Properties and methods must be declared on the class interface.
- Events must be declared in the event interface.
Other public members in the class that you don't declare in these interfaces aren't visible to COM, but they're visible to other .NET objects. To expose properties and methods to COM, you must declare them on the class interface and mark them with a `DispId` attribute, and implement them in the class. The order in which you declare the members in the interface is the order used for the COM vtable. To expose events from your class, you must declare them on the events interface and mark them with a `DispId` attribute. The class shouldn't implement this interface.
The class implements the class interface; it can implement more than one interface, but the first implementation is the default class interface. Implement the methods and properties exposed to COM here. They must be public and must match the declarations in the class interface. Also, declare the events raised by the class here. They must be public and must match the declarations in the events interface.
## Example
:::code language="csharp" source="./snippets/ExampleCOMClass/ExampleCOM.cs":::
## See also
- [Interoperability](./index.md)
- [Build Page, Project Designer (C#)](/visualstudio/ide/reference/build-page-project-designer-csharp)

Просмотреть файл

@ -0,0 +1,145 @@
---
title: "How to access Office interop objects - C# Programming Guide"
description: Learn about C# features that simplify access to Office API objects. Use the new features to write code that creates and displays an Excel worksheet.
ms.topic: how-to
ms.date: 02/15/2023
helpviewer_keywords:
- "optional parameters [C#], Office programming"
- "named and optional arguments [C#], Office programming"
- "dynamic [C#], Office programming"
- "optional arguments [C#], Office programming"
- "named arguments [C#], Office programming"
- "Office programming [C#]"
---
# How to access Office interop objects
C# has features that simplify access to Office API objects. The new features include named and optional arguments, a new type called `dynamic`, and the ability to pass arguments to reference parameters in COM methods as if they were value parameters.
In this article, you use the new features to write code that creates and displays a Microsoft Office Excel worksheet. You write code to add an Office Word document that contains an icon that is linked to the Excel worksheet.
To complete this walkthrough, you must have Microsoft Office Excel 2007 and Microsoft Office Word 2007, or later versions, installed on your computer.
[!INCLUDE[note_settings_general](~/includes/note-settings-general-md.md)]
## To create a new console application
1. Start Visual Studio.
1. On the **File** menu, point to **New**, and then select **Project**. The **New Project** dialog box appears.
1. In the **Installed Templates** pane, expand **C#**, and then select **Windows**.
1. Look at the top of the **New Project** dialog box to make sure to select **.NET Framework 4** (or later version) as a target framework.
1. In the **Templates** pane, select **Console Application**.
1. Type a name for your project in the **Name** field.
1. Select **OK**.
The new project appears in **Solution Explorer**.
## To add references
1. In **Solution Explorer**, right-click your project's name and then select **Add Reference**. The **Add Reference** dialog box appears.
1. On the **Assemblies** page, select **Microsoft.Office.Interop.Word** in the **Component Name** list, and then hold down the CTRL key and select **Microsoft.Office.Interop.Excel**. If you don't see the assemblies, you may need to install them. See [How to: Install Office Primary Interop Assemblies](/visualstudio/vsto/how-to-install-office-primary-interop-assemblies).
1. Select **OK**.
## To add necessary using directives
In **Solution Explorer**, right-click the *Program.cs* file and then select **View Code**. Add the following `using` directives to the top of the code file:
:::code language="csharp" source="./snippets/OfficeInterop/program.cs" id="Snippet1":::
## To create a list of bank accounts
Paste the following class definition into **Program.cs**, under the `Program` class.
:::code language="csharp" source="./snippets/OfficeInterop/program.cs" id="Snippet2":::
Add the following code to the `Main` method to create a `bankAccounts` list that contains two accounts.
:::code language="csharp" source="./snippets/OfficeInterop/program.cs" id="Snippet3":::
## To declare a method that exports account information to Excel
1. Add the following method to the `Program` class to set up an Excel worksheet. Method <xref:Microsoft.Office.Interop.Excel.Workbooks.Add%2A> has an optional parameter for specifying a particular template. Optional parameters enable you to omit the argument for that parameter if you want to use the parameter's default value. Because you didn't supply an argument, `Add` uses the default template and creates a new workbook. The equivalent statement in earlier versions of C# requires a placeholder argument: `ExcelApp.Workbooks.Add(Type.Missing)`.
:::code language="csharp" source="./snippets/OfficeInterop/program.cs" id="Snippet4":::
Add the following code at the end of `DisplayInExcel`. The code inserts values into the first two columns of the first row of the worksheet.
:::code language="csharp" source="./snippets/OfficeInterop/program.cs" id="Snippet5":::
Add the following code at the end of `DisplayInExcel`. The `foreach` loop puts the information from the list of accounts into the first two columns of successive rows of the worksheet.
:::code language="csharp" source="./snippets/OfficeInterop/program.cs" id="Snippet7":::
Add the following code at the end of `DisplayInExcel` to adjust the column widths to fit the content.
:::code language="csharp" source="./snippets/OfficeInterop/program.cs" id="Snippet13":::
Earlier versions of C# require explicit casting for these operations because `ExcelApp.Columns[1]` returns an `Object`, and `AutoFit` is an Excel <xref:Microsoft.Office.Interop.Excel.Range> method. The following lines show the casting.
:::code language="csharp" source="./snippets/OfficeInterop/program.cs" id="Snippet14":::
C# converts the returned `Object` to `dynamic` automatically if the assembly is referenced by the [**EmbedInteropTypes**](../../language-reference/compiler-options/inputs.md#embedinteroptypes) compiler option or, equivalently, if the Excel **Embed Interop Types** property is true. True is the default value for this property.
## To run the project
Add the following line at the end of `Main`.
:::code language="csharp" source="./snippets/OfficeInterop/program.cs" id="Snippet8":::
Press CTRL+F5. An Excel worksheet appears that contains the data from the two accounts.
## To add a Word document
The following code opens a Word application and creates an icon that links to the Excel worksheet. Paste method `CreateIconInWordDoc`, provided later in this step, into the `Program` class. `CreateIconInWordDoc` uses named and optional arguments to reduce the complexity of the method calls to <xref:Microsoft.Office.Interop.Word.Documents.Add%2A> and <xref:Microsoft.Office.Interop.Word.Selection.PasteSpecial%2A>. These calls incorporate two other features that simplify calls to COM methods that have reference parameters. First, you can send arguments to the reference parameters as if they were value parameters. That is, you can send values directly, without creating a variable for each reference parameter. The compiler generates temporary variables to hold the argument values, and discards the variables when you return from the call. Second, you can omit the `ref` keyword in the argument list.
The `Add` method has four reference parameters, all of which are optional. You can omit arguments for any or all of the parameters if you want to use their default values.
The `PasteSpecial` method inserts the contents of the Clipboard. The method has seven reference parameters, all of which are optional. The following code specifies arguments for two of them: `Link`, to create a link to the source of the Clipboard contents, and `DisplayAsIcon`, to display the link as an icon. You can use named arguments for those two arguments and omit the others. Although these arguments are reference parameters, you don't have to use the `ref` keyword, or to create variables to send in as arguments. You can send the values directly.
:::code language="csharp" source="./snippets/OfficeInterop/program.cs" id="Snippet9":::
Add the following statement at the end of `Main`.
:::code language="csharp" source="./snippets/OfficeInterop/program.cs" id="Snippet11":::
Add the following statement at the end of `DisplayInExcel`. The `Copy` method adds the worksheet to the Clipboard.
:::code language="csharp" source="./snippets/OfficeInterop/program.cs" id="Snippet12":::
Press CTRL+F5. A Word document appears that contains an icon. Double-click the icon to bring the worksheet to the foreground.
## To set the Embed Interop Types property
More enhancements are possible when you call a COM type that doesn't require a primary interop assembly (PIA) at run time. Removing the dependency on PIAs results in version independence and easier deployment. For more information about the advantages of programming without PIAs, see [Walkthrough: Embedding Types from Managed Assemblies](../../../standard/assembly/embed-types-visual-studio.md).
In addition, programming is easier because the `dynamic` type represents the required and returned types declared in COM methods. Variables that have type `dynamic` aren't evaluated until run time, which eliminates the need for explicit casting. For more information, see [Using Type dynamic](using-type-dynamic.md).
Embedding type information instead of using PIAs is default behavior. Because of that default, several of the previous examples are simplified. You don't need any explicit casting. For example, the declaration of `worksheet` in `DisplayInExcel` is written as `Excel._Worksheet workSheet = excelApp.ActiveSheet` rather than `Excel._Worksheet workSheet = (Excel.Worksheet)excelApp.ActiveSheet`. The calls to `AutoFit` in the same method also would require explicit casting without the default, because `ExcelApp.Columns[1]` returns an `Object`, and `AutoFit` is an Excel method. The following code shows the casting.
:::code language="csharp" source="./snippets/OfficeInterop/program.cs" id="Snippet14":::
To change the default and use PIAs instead of embedding type information, expand the References node in Solution Explorer, and then select **Microsoft.Office.Interop.Excel** or **Microsoft.Office.Interop.Word**. If you can't see the **Properties** window, press **F4**. Find **Embed Interop Types** in the list of properties, and change its value to **False**. Equivalently, you can compile by using the [**References**](../../language-reference/compiler-options/inputs.md#references) compiler option instead of [**EmbedInteropTypes**](../../language-reference/compiler-options/inputs.md#embedinteroptypes) at a command prompt.
## To add additional formatting to the table
Replace the two calls to `AutoFit` in `DisplayInExcel` with the following statement.
:::code language="csharp" source="./snippets/OfficeInterop/program.cs" id="Snippet15":::
The <xref:Microsoft.Office.Interop.Excel.Range.AutoFormat%2A> method has seven value parameters, all of which are optional. Named and optional arguments enable you to provide arguments for none, some, or all of them. In the previous statement, you supply an argument for only one of the parameters, `Format`. Because `Format` is the first parameter in the parameter list, you don't have to provide the parameter name. However, the statement might be easier to understand if you include the parameter name, as shown in the following code.
:::code language="csharp" source="./snippets/OfficeInterop/program.cs" id="Snippet16":::
Press CTRL+F5 to see the result. You can find other formats in the listed in the <xref:Microsoft.Office.Interop.Excel.XlRangeAutoFormat> enumeration.
## Example
The following code shows the complete example.
:::code language="csharp" source="./snippets/OfficeInterop/walkthrough.cs" id="Snippet18":::
## See also
- <xref:System.Type.Missing?displayProperty=nameWithType>
- [dynamic](../../language-reference/builtin-types/reference-types.md)
- [Named and Optional Arguments](../../programming-guide/classes-and-structs/named-and-optional-arguments.md)
- [How to use named and optional arguments in Office programming](how-to-use-named-and-optional-arguments-in-office-programming.md)

Просмотреть файл

@ -0,0 +1,41 @@
---
title: "How to use indexed properties in COM interop programming"
description: Learn how indexed properties improve the way C# objects consume COM properties that have parameters.
ms.date: 02/15/2023
ms.topic: how-to
helpviewer_keywords:
- "indexed properties [C#]"
- "Office programming [C#], indexed properties"
- "properties [C#], indexed"
---
# How to use indexed properties in COM interop programming
Indexed properties work together with other features in C#, such as [named and optional arguments](../../programming-guide/classes-and-structs/named-and-optional-arguments.md), a new type ([dynamic](../../language-reference/builtin-types/reference-types.md)), and [embedded type information](../../../standard/assembly/embed-types-visual-studio.md), to enhance Microsoft Office programming.
In earlier versions of C#, methods are accessible as properties only if the `get` method has no parameters and the `set` method has one and only one value parameter. However, not all COM properties meet those restrictions. For example, the Excel <xref:Microsoft.Office.Interop.Excel.Range.Range%2A> property has a `get` accessor that requires a parameter for the name of the range. In the past, because you couldn't access the `Range` property directly, you had to use the `get_Range` method instead, as shown in the following example.
:::code language="{language}" source="snippets/IndexedProperties/Program.cs" id="Snippet1":::
Indexed properties enable you to write the following instead:
:::code language="{language}" source="snippets/IndexedProperties/Program.cs" id="Snippet2":::
The previous example also uses the [optional arguments](../../programming-guide/classes-and-structs/named-and-optional-arguments.md) feature, which enables you to omit `Type.Missing`.
Indexed properties enable you to write the following code.
:::code language="{language}" source="snippets/IndexedProperties/Program.cs" id="Snippet4":::
You can't create indexed properties of your own. The feature only supports consumption of existing indexed properties.
## Example
The following code shows a complete example. For more information about how to set up a project that accesses the Office API, see [How to access Office interop objects by using C# features](./how-to-access-office-interop-objects.md).
:::code language="{language}" source="snippets/IndexedProperties/Program.cs" id="Snippet5":::
## See also
- [Named and Optional Arguments](../../programming-guide/classes-and-structs/named-and-optional-arguments.md)
- [dynamic](../../language-reference/builtin-types/reference-types.md)
- [Using Type dynamic](using-type-dynamic.md)

Просмотреть файл

@ -0,0 +1,79 @@
---
title: "How to use C# named and optional arguments in Office programming"
description: Learn how to use named arguments and optional arguments to facilitate access to COM interfaces such as the Microsoft Office automation APIs.
ms.date: 02/16/2023
helpviewer_keywords:
- "named and optional arguments [C#], Office programming"
- "optional arguments [C#], Office programming"
- "named arguments [C#], Office programming"
ms.topic: how-to
---
# How to use named and optional arguments in Office programming
Named arguments and optional arguments enhance convenience, flexibility, and readability in C# programming. In addition, these features greatly facilitate access to COM interfaces such as the Microsoft Office automation APIs.
In the following example, method [ConvertToTable](<xref:Microsoft.Office.Interop.Word.Range.ConvertToTable%2A>) has 16 parameters that represent characteristics of a table, such as number of columns and rows, formatting, borders, fonts, and colors. All 16 parameters are optional, because most of the time you don't want to specify particular values for all of them. However, without named and optional arguments, you must provide a value or a placeholder value. With named and optional arguments, you specify values only for the parameters required for your project.
You must have Microsoft Office Word installed on your computer to complete these procedures.
[!INCLUDE[note_settings_general](~/includes/note-settings-general-md.md)]
## Create a new console application
Start Visual Studio. On the **File** menu, point to **New**, and then select **Project**. In the **Templates Categories** pane, expand **C#**, and then select **Windows**. Look in the top of the **Templates** pane to make sure that **.NET Framework 4** appears in the **Target Framework** box. In the **Templates** pane, select **Console Application**. Type a name for your project in the **Name** field. Select **OK**. The new project appears in **Solution Explorer**.
## Add a reference
In **Solution Explorer**, right-click your project's name and then select **Add Reference**. The **Add Reference** dialog box appears. On the **.NET** page, select **Microsoft.Office.Interop.Word** in the **Component Name** list. Select **OK**.
## Add necessary using directives
In **Solution Explorer**, right-click the *Program.cs* file and then select **View Code**. Add the following `using` directives to the top of the code file:
:::code language="csharp" source="./snippets/NamedAndOptional/wordprogram.cs" id="Snippet4":::
## Display text in a Word document
In the `Program` class in *Program.cs*, add the following method to create a Word application and a Word document. The [Add](<xref:Microsoft.Office.Interop.Word.Documents.Add%2A>) method has four optional parameters. This example uses their default values. Therefore, no arguments are necessary in the calling statement.
:::code language="csharp" source="./snippets/NamedAndOptional/wordprogram.cs" id="Snippet6":::
Add the following code at the end of the method to define where to display text in the document, and what text to display:
:::code language="csharp" source="./snippets/NamedAndOptional/wordprogram.cs" id="Snippet7":::
## Run the application
Add the following statement to Main:
:::code language="csharp" source="./snippets/NamedAndOptional/wordprogram.cs" id="Snippet8":::
Press <kbd>CTRL</kbd>+<kbd>F5</kbd> to run the project. A Word document appears that contains the specified text.
## Change the text to a table
Use the `ConvertToTable` method to enclose the text in a table. The method has 16 optional parameters. IntelliSense encloses optional parameters in brackets, as shown in the following illustration.
![List of parameters for ConvertToTable method](./media/how-to-use-named-and-optional-arguments-in-office-programming/convert-table-parameters.png)
Named and optional arguments enable you to specify values for only the parameters that you want to change. Add the following code to the end of method `DisplayInWord` to create a table. The argument specifies that the commas in the text string in `range` separate the cells of the table.
:::code language="csharp" source="./snippets/NamedAndOptional/wordprogram.cs" id="Snippet9":::
Press <kbd>CTRL</kbd>+<kbd>F5</kbd> to run the project.
## Experiment with other parameters
Change the table so that it has one column and three rows, replace the last line in `DisplayInWord` with the following statement and then type <kbd>CTRL</kbd>+<kbd>F5</kbd>.
:::code language="csharp" source="./snippets/NamedAndOptional/wordprogram.cs" id="Snippet10":::
Specify a predefined format for the table, replace the last line in `DisplayInWord` with the following statement and then type <kbd>CTRL</kbd>+<kbd>F5</kbd>. The format can be any of the [WdTableFormat](<xref:Microsoft.Office.Interop.Word.WdTableFormat>) constants.
:::code language="csharp" source="./snippets/NamedAndOptional/wordprogram.cs" id="Snippet11":::
## Example
The following code includes the full example:
:::code language="csharp" source="./snippets/NamedAndOptional/wordprogram.cs" id="Snippet12":::

Просмотреть файл

@ -0,0 +1,35 @@
---
title: "How to use platform invoke to play a WAV file"
description: This C# code example illustrates how to use platform invoke services to play a WAV sound file on the Windows operating system.
ms.topic: how-to
ms.date: 02/15/2023
helpviewer_keywords:
- "platform invoke, sound files"
- "interoperability [C#], playing WAV files using pinvoke"
- "wav files"
- ".wav files"
---
# How to use platform invoke to play a WAV file
The following C# code example illustrates how to use platform invoke services to play a WAV sound file on the Windows operating system.
## Example
This example code uses <xref:System.Runtime.InteropServices.DllImportAttribute> to import `winmm.dll`'s `PlaySound` method entry point as `Form1 PlaySound()`. The example has a simple Windows Form with a button. Clicking the button opens a standard windows <xref:System.Windows.Forms.OpenFileDialog> dialog box so that you can open a file to play. When a wave file is selected, it's played by using the `PlaySound()` method of the *winmm.dll* library. For more information about this method, see [Using the PlaySound function with Waveform-Audio Files](/windows/desktop/multimedia/using-playsound-to-play-waveform-audio-files). Browse and select a file that has a .wav extension, and then select **Open** to play the wave file by using platform invoke. A text box shows the full path of the file selected.
:::code language="csharp" source="snippets/WinSound/Form1.cs":::
The **Open Files** dialog box is filtered to show only files that have a .wav extension through the filter settings.
## Compiling the code
Create a new C# Windows Forms Application project in Visual Studio and name it **WinSound**. Copy the preceding code, and paste it over the contents of the *Form1.cs* file. Copy the following code, and paste it in the *Form1.Designer.cs* file, in the `InitializeComponent()` method, after any existing code.
:::code language="csharp" source="snippets/WinSound/Form1.Designer.cs" id="Initialization":::
Compile and run the code.
## See also
- [A Closer Look at Platform Invoke](../../../framework/interop/consuming-unmanaged-dll-functions.md#a-closer-look-at-platform-invoke)
- [Marshaling Data with Platform Invoke](../../../framework/interop/marshalling-data-with-platform-invoke.md)

Просмотреть файл

@ -0,0 +1,60 @@
---
title: "Interoperability Overview"
description: Learn about interoperability between C# and unmanaged code, including platform invoke, C++ interop, exposing COM components to C#, and exposing C# to COM.
ms.date: 02/15/2023
helpviewer_keywords:
- "COM interop"
- "C# language, interoperability"
- "C++ Interop"
- "interoperability, about interoperability"
- "platform invoke"
---
# Interoperability Overview
Interoperability enables you to preserve and take advantage of existing investments in unmanaged code. Code that runs under the control of the common language runtime (CLR) is *managed code*, and code that runs outside the CLR is *unmanaged code*. COM, COM+, C++ components, ActiveX components, and Microsoft Windows API are examples of unmanaged code.
.NET enables interoperability with unmanaged code through platform invoke services, the <xref:System.Runtime.InteropServices> namespace, C++ interoperability, and COM interoperability (COM interop).
## Platform Invoke
*Platform invoke* is a service that enables managed code to call unmanaged functions implemented in dynamic link libraries (DLLs), such as the Microsoft Windows API. It locates and invokes an exported function and marshals its arguments (integers, strings, arrays, structures, and so on) across the interoperation boundary as needed.
For more information, see [Consuming Unmanaged DLL Functions](../../../framework/interop/consuming-unmanaged-dll-functions.md) and [How to use platform invoke to play a WAV file](./how-to-use-platform-invoke-to-play-a-wave-file.md).
> [!NOTE]
> The [Common Language Runtime](../../../standard/clr.md) (CLR) manages access to system resources. Calling unmanaged code that is outside the CLR bypasses this security mechanism, and therefore presents a security risk. For example, unmanaged code might call resources in unmanaged code directly, bypassing CLR security mechanisms. For more information, see [Security in .NET](../../../standard/security/index.md).
## C++ Interop
You can use C++ interop, also known as It Just Works (IJW), to wrap a native C++ class. C++ interop enables code authored in C# or another .NET language to access it. You write C++ code to wrap a native DLL or COM component. Unlike other .NET languages, Visual C++ has interoperability support that enables managed and unmanaged code in the same application and even in the same file. You then build the C++ code by using the **/clr** compiler switch to produce a managed assembly. Finally, you add a reference to the assembly in your C# project and use the wrapped objects just as you would use other managed classes.
## Exposing COM Components to C\#
You can consume a COM component from a C# project. The general steps are as follows:
1. Locate a COM component to use and register it. Use regsvr32.exe to register or un–register a COM DLL.
1. Add to the project a reference to the COM component or type library.
When you add the reference, Visual Studio uses the [Tlbimp.exe (Type Library Importer)](../../../framework/tools/tlbimp-exe-type-library-importer.md), which takes a type library as input, to output a .NET interop assembly. The assembly, also named a runtime callable wrapper (RCW), contains managed classes and interfaces that wrap the COM classes and interfaces that are in the type library. Visual Studio adds to the project a reference to the generated assembly.
1. Create an instance of a class defined in the RCW. Creating an instance of that class creates an instance of the COM object.
1. Use the object just as you use other managed objects. When the object is reclaimed by garbage collection, the instance of the COM object is also released from memory.
For more information, see [Exposing COM Components to the .NET Framework](../../../framework/interop/exposing-com-components.md).
## Exposing C# to COM
COM clients can consume C# types that have been correctly exposed. The basic steps to expose C# types are as follows:
1. Add interop attributes in the C# project.
You can make an assembly COM visible by modifying C# project properties. For more information, see [Assembly Information Dialog Box](/visualstudio/ide/reference/assembly-information-dialog-box).
1. Generate a COM type library and register it for COM usage.
You can modify C# project properties to automatically register the C# assembly for COM interop. Visual Studio uses the [Regasm.exe (Assembly Registration Tool)](../../../framework/tools/regasm-exe-assembly-registration-tool.md), using the `/tlb` command-line switch, which takes a managed assembly as input, to generate a type library. This type library describes the `public` types in the assembly and adds registry entries so that COM clients can create managed classes.
For more information, see [Exposing .NET Framework Components to COM](../../../framework/interop/exposing-dotnet-components-to-com.md) and [Example COM Class](./example-com-class.md).
## See also
- [Improving Interop Performance](/previous-versions/msp-n-p/ff647812(v=pandp.10))
- [Introduction to Interoperability between COM and .NET](/office/client-developer/outlook/pia/introduction-to-interoperability-between-com-and-net)
- [Introduction to COM Interop in Visual Basic](../../../visual-basic/programming-guide/com-interop/introduction-to-com-interop.md)
- [Marshaling between Managed and Unmanaged Code](../../../framework/interop/interop-marshalling.md)
- [Interoperating with Unmanaged Code](../../../framework/interop/index.md)

Просмотреть файл

@ -1,5 +1,4 @@
//<Snippet8>
using System.Runtime.InteropServices;
using System.Runtime.InteropServices;
namespace project_name
{
@ -21,4 +20,3 @@ namespace project_name
{
}
}
//</Snippet8>

Просмотреть файл

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

Просмотреть файл

@ -59,6 +59,15 @@
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.Office.Interop.Excel1">
<HintPath>..\..\..\..\..\..\..\..\..\..\..\..\..\Program Files (x86)\Microsoft Visual Studio\Shared\Visual Studio Tools for Office\PIA\Office15\Microsoft.Office.Interop.Excel.dll</HintPath>
<EmbedInteropTypes>True</EmbedInteropTypes>
</Reference>
<Reference Include="Microsoft.Office.Interop.Word, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c, processorArchitecture=MSIL">
<EmbedInteropTypes>True</EmbedInteropTypes>
</Reference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

Просмотреть файл

@ -0,0 +1,11 @@
{
"host": "visualstudio",
"expectederrors": [
{
"file": "docs/csharp/advanced-topics/interop/snippets/IndexedProperties/Program.cs",
"line": 13,
"column": 40,
"error": "CS0234"
}
]
}

Просмотреть файл

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>10.0.20319</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{595F32EC-B330-4DA1-9D79-9E5E1EA6DDAB}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>NamedAndOptionalSnippets</RootNamespace>
<AssemblyName>NamedAndOptionalSnippets</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="WordProgram.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
<ItemGroup>
<COMReference Include="Microsoft.Office.Core">
<Guid>{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}</Guid>
<VersionMajor>2</VersionMajor>
<VersionMinor>8</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>primary</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
<COMReference Include="Microsoft.Office.Interop.Excel">
<Guid>{00020813-0000-0000-C000-000000000046}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>9</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>primary</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
<COMReference Include="Microsoft.Office.Interop.Word">
<Guid>{00020905-0000-0000-C000-000000000046}</Guid>
<VersionMajor>8</VersionMajor>
<VersionMinor>7</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>primary</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
<COMReference Include="VBIDE">
<Guid>{0002E157-0000-0000-C000-000000000046}</Guid>
<VersionMajor>5</VersionMajor>
<VersionMinor>3</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>primary</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

Просмотреть файл

@ -0,0 +1,11 @@
{
"host": "visualstudio",
"expectederrors": [
{
"file": "docs/csharp/advanced-topics/interop/snippets/NamedAndOptional/WordProgram.cs",
"line": 8,
"column": 24,
"error": "CS0234"
}
]
}

Просмотреть файл

@ -1,9 +1,6 @@
//
//<Snippet12>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//<Snippet4>
using Word = Microsoft.Office.Interop.Word;
//</Snippet4>
@ -104,18 +101,6 @@ namespace Parts
Word.Range range = doc.Range(ref n, ref n);
range.InsertAfter("Testing, testing, testing. . .");
//<Snippet14>
// Call to ConvertToTable in Visual C# 2008 or earlier. This code
// is not part of the solution.
var missing = Type.Missing;
object separator = ",";
range.ConvertToTable(ref separator, ref missing, ref missing,
ref missing, ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing, ref missing,
ref missing);
//</Snippet14>
}
}
}

Просмотреть файл

@ -8,8 +8,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//<Snippet1>
using Excel = Microsoft.Office.Interop.Excel;
using Word = Microsoft.Office.Interop.Word;

Просмотреть файл

@ -0,0 +1,53 @@
{
"host": "visualstudio",
"expectederrors": [
{
"file": "docs/csharp/advanced-topics/interop/snippets/OfficeInterop/Program.cs",
"line": 6,
"column": 25,
"error": "CS0234"
},
{
"file": "docs/csharp/advanced-topics/interop/snippets/OfficeInterop/Program.cs",
"line": 7,
"column": 24,
"error": "CS0234"
},
{
"file": "docs/csharp/advanced-topics/interop/snippets/OfficeInterop/Walkthrough.cs",
"line": 5,
"column": 25,
"error": "CS0234"
},
{
"file": "docs/csharp/advanced-topics/interop/snippets/OfficeInterop/Walkthrough.cs",
"line": 6,
"column": 24,
"error": "CS0234"
},
{
"file": "docs/csharp/advanced-topics/interop/snippets/OfficeInterop/Program.cs",
"line": 6,
"column": 25,
"error": "CS0234"
},
{
"file": "docs/csharp/advanced-topics/interop/snippets/OfficeInterop/Program.cs",
"line": 7,
"column": 24,
"error": "CS0234"
},
{
"file": "docs/csharp/advanced-topics/interop/snippets/OfficeInterop/Walkthrough.cs",
"line": 5,
"column": 25,
"error": "CS0234"
},
{
"file": "docs/csharp/advanced-topics/interop/snippets/OfficeInterop/Walkthrough.cs",
"line": 6,
"column": 24,
"error": "CS0234"
}
]
}

Просмотреть файл

@ -7,9 +7,7 @@
// Then, make sure no new errors are added.
//<Snippet18>
using System;
using System.Collections.Generic;
using System.Linq;
using Excel = Microsoft.Office.Interop.Excel;
using Word = Microsoft.Office.Interop.Word;

Просмотреть файл

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="17.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<!--
This section defines project-level properties.
@ -17,73 +17,27 @@
In C#, this specifies the namespace given to new files. In VB, all objects are
wrapped in this namespace at runtime.
-->
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<ProjectTypeGuids>{BAA0C2D2-18E2-41B9-852F-F413020CAA33};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{4E123DE4-B7B1-4FFF-A4A6-75843359CB59}</ProjectGuid>
<ProjectGuid>{5A1BC04B-DFEF-4A19-9C0F-570492BE0DE7}</ProjectGuid>
<OutputType>Library</OutputType>
<NoStandardLibraries>false</NoStandardLibraries>
<RootNamespace>OfficeWalkthroughCS</RootNamespace>
<AssemblyName>OfficeWalkthroughCS</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
<DefineConstants>VSTO40</DefineConstants>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>4.0</OldToolsVersion>
<VSTO_TrustAssembliesLocation>true</VSTO_TrustAssembliesLocation>
<IsWebBootstrapper>False</IsWebBootstrapper>
<BootstrapperEnabled>true</BootstrapperEnabled>
<PublishUrl>publish\</PublishUrl>
<InstallUrl />
<TargetCulture>en</TargetCulture>
<ApplicationVersion>1.0.0.0</ApplicationVersion>
<AutoIncrementApplicationRevision>true</AutoIncrementApplicationRevision>
<UpdateEnabled>true</UpdateEnabled>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>days</UpdateIntervalUnits>
<ProductName>OfficeWalkthroughCS</ProductName>
<PublisherName />
<SupportUrl />
<FriendlyName>OfficeWalkthroughCS</FriendlyName>
<OfficeApplicationDescription />
<RootNamespace>OfficeWalkthrough</RootNamespace>
<AssemblyName>OfficeWalkthrough</AssemblyName>
<LoadBehavior>3</LoadBehavior>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<DefineConstants>VSTO40</DefineConstants>
<BootstrapperEnabled>true</BootstrapperEnabled>
<BootstrapperComponentsLocation>HomeSite</BootstrapperComponentsLocation>
</PropertyGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.0,Profile=Client">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4 Client Profile %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Office.PIARedist.2007">
<Visible>False</Visible>
<ProductName>Microsoft Office 2007 Primary Interop Assemblies</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.VSTORuntime.4.0">
<Visible>False</Visible>
<ProductName>Microsoft Visual Studio 2010 Tools for Office Runtime %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<PropertyGroup>
<!--
@ -116,7 +70,6 @@
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
<DefineConstants>$(DefineConstants);DEBUG;TRACE</DefineConstants>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<!--
This section defines properties that are set when the "Release" configuration is selected.
@ -141,42 +94,15 @@
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
<DefineConstants>$(DefineConstants);TRACE</DefineConstants>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<!--
This section enables pre- and post-build steps. However, in VSTO use
MSBuild tasks instead of these properties.
-->
<PropertyGroup>
<PreBuildEvent>
</PreBuildEvent>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
<!--
This section specifies references for the project.
-->
<ItemGroup>
<Reference Include="Accessibility" />
<Reference Include="Microsoft.Office.Interop.Excel, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">
<EmbedInteropTypes>True</EmbedInteropTypes>
</Reference>
<Reference Include="Microsoft.Office.Interop.Word, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c, processorArchitecture=MSIL">
<EmbedInteropTypes>True</EmbedInteropTypes>
</Reference>
<Reference Include="Microsoft.Office.Tools, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<EmbedInteropTypes>True</EmbedInteropTypes>
</Reference>
<Reference Include="Microsoft.Office.Tools.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<EmbedInteropTypes>True</EmbedInteropTypes>
</Reference>
<Reference Include="Microsoft.VisualStudio.Tools.Applications.Runtime, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="Office, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">
<EmbedInteropTypes>True</EmbedInteropTypes>
</Reference>
<Reference Include="stdole, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<EmbedInteropTypes>True</EmbedInteropTypes>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
@ -188,26 +114,52 @@
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.Office.Tools.v4.0.Framework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="Microsoft.Office.Tools.Excel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="Microsoft.Office.Tools.v4.0.Framework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Tools.Applications.Runtime, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Office.Tools, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Office.Tools.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Office.Tools.Excel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.Office.Tools.Common.v4.0.Utilities, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Reference Include="Office, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">
<Private>False</Private>
<EmbedInteropTypes>true</EmbedInteropTypes>
</Reference>
<Reference Include="Microsoft.Office.Interop.Excel, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">
<Private>False</Private>
<EmbedInteropTypes>true</EmbedInteropTypes>
</Reference>
<Reference Include="stdole, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Private>False</Private>
</Reference>
</ItemGroup>
<!--
This section defines the user source files that are part of the project.
A "Compile" element specifies a source file to compile.
An "EmbeddedResource" element specifies an .resx file for embedded resources.
A "None" element specifies a file that is not to be passed to the compiler (for instance,
A "None" element specifies a file that is not to be passed to the compiler (for instance,
a text file or XML file).
The "AppDesigner" element specifies the directory where the application properties files
can be found.
-->
<ItemGroup>
<Compile Include="Account.cs" />
<Compile Include="account.cs" />
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
@ -219,8 +171,8 @@
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="OfficeWalkthrough_TemporaryKey.pfx" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
@ -228,7 +180,6 @@
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="ThisAddIn.cs">
<SubType>Code</SubType>
@ -245,19 +196,28 @@
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<PropertyGroup>
<SignManifests>true</SignManifests>
</PropertyGroup>
<PropertyGroup>
<ManifestKeyFile>OfficeWalkthrough_TemporaryKey.pfx</ManifestKeyFile>
</PropertyGroup>
<PropertyGroup>
<ManifestCertificateThumbprint>64E5FAB68A3026C22AD36BD5DF7B81CF865E4CCE</ManifestCertificateThumbprint>
</PropertyGroup>
<!-- Include the build rules for a C# project. -->
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- Include additional build rules for an Office application add-in. -->
<Import Project="$(VSToolsPath)\OfficeTools\Microsoft.VisualStudio.Tools.Office.targets" Condition="'$(VSToolsPath)' != ''" />
<!-- This section defines VSTO properties that describe the host-changeable project properties. -->
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{BAA0C2D2-18E2-41B9-852F-F413020CAA33}">
<ProjectProperties HostName="Excel" HostPackage="{29A7B9D7-A7F1-4328-8EF0-6B2D1A56B2C1}" OfficeVersion="15.0" VstxVersion="4.0" ApplicationType="Excel" Language="cs" TemplatesPath="VSTOTemplates" DebugInfoExeName="#Software\Microsoft\Office\16.0\Excel\InstallRoot\Path#excel.exe" DebugInfoCommandLine="/x " AddItemTemplatesGuid="{51063C3A-E220-4D12-8922-BDA915ACD783}" />
<Host Name="Excel" GeneratedCodeNamespace="OfficeWalkthroughCS" IconIndex="0">
<ProjectProperties HostName="Excel" HostPackage="{29A7B9D7-A7F1-4328-8EF0-6B2D1A56B2C1}" OfficeVersion="15.0" VstxVersion="4.0" ApplicationType="Excel" Language="cs" TemplatesPath="" DebugInfoExeName="#Software\Microsoft\Office\16.0\Excel\InstallRoot\Path#excel.exe" DebugInfoCommandLine="/x" AddItemTemplatesGuid="{51063C3A-E220-4D12-8922-BDA915ACD783}" />
<Host Name="Excel" GeneratedCodeNamespace="OfficeWalkthrough" IconIndex="0">
<HostItem Name="ThisAddIn" Code="ThisAddIn.cs" CanonicalName="AddIn" CanActivate="false" IconIndex="1" Blueprint="ThisAddIn.Designer.xml" GeneratedCode="ThisAddIn.Designer.cs" />
</Host>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
<Import Project="$(VSToolsPath)\OfficeTools\Microsoft.VisualStudio.Tools.Office.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>
</Project>

Просмотреть файл

@ -0,0 +1,38 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("OfficeWalkthrough")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("OfficeWalkthrough")]
[assembly: AssemblyCopyright("Copyright © 2023")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("500e9810-a014-472b-a2a2-d4788b8a1e8b")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

Просмотреть файл

@ -8,10 +8,9 @@
// </auto-generated>
//------------------------------------------------------------------------------
namespace OfficeWalkthroughCS.Properties {
using System;
namespace OfficeWalkthrough.Properties {
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
@ -19,19 +18,19 @@ namespace OfficeWalkthroughCS.Properties {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
@ -39,13 +38,13 @@ namespace OfficeWalkthroughCS.Properties {
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("OfficeWalkthroughCS.Properties.Resources", typeof(Resources).Assembly);
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("OfficeWalkthrough.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.

Просмотреть файл

@ -8,15 +8,15 @@
// </auto-generated>
//------------------------------------------------------------------------------
namespace OfficeWalkthroughCS.Properties {
namespace OfficeWalkthrough.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.7.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;

Просмотреть файл

@ -9,35 +9,35 @@
//------------------------------------------------------------------------------
#pragma warning disable 414
namespace OfficeWalkthroughCS {
///
namespace OfficeWalkthrough {
///
[Microsoft.VisualStudio.Tools.Applications.Runtime.StartupObjectAttribute(0)]
[global::System.Security.Permissions.PermissionSetAttribute(global::System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
public sealed partial class ThisAddIn : Microsoft.Office.Tools.AddInBase {
internal Microsoft.Office.Tools.CustomTaskPaneCollection CustomTaskPanes;
internal Microsoft.Office.Tools.SmartTagCollection VstoSmartTags;
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "15.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
private global::System.Object missing = global::System.Type.Missing;
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "15.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
internal Microsoft.Office.Interop.Excel.Application Application;
///
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
public ThisAddIn(global::Microsoft.Office.Tools.Excel.ApplicationFactory factory, global::System.IServiceProvider serviceProvider) :
public ThisAddIn(global::Microsoft.Office.Tools.Excel.ApplicationFactory factory, global::System.IServiceProvider serviceProvider) :
base(factory, serviceProvider, "AddIn", "ThisAddIn") {
Globals.Factory = factory;
}
///
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "15.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
protected override void Initialize() {
base.Initialize();
@ -49,29 +49,29 @@ namespace OfficeWalkthroughCS {
this.InitializeComponents();
this.InitializeData();
}
///
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "15.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
protected override void FinishInitialization() {
this.InternalStartup();
this.OnStartup();
}
///
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "15.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
protected override void InitializeDataBindings() {
this.BeginInitialization();
this.BindToData();
this.EndInitialization();
}
///
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "15.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
private void InitializeCachedData() {
if ((this.DataHost == null)) {
@ -81,88 +81,88 @@ namespace OfficeWalkthroughCS {
this.DataHost.FillCachedData(this);
}
}
///
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "15.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
private void InitializeData() {
}
///
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "15.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
private void BindToData() {
}
///
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
private void StartCaching(string MemberName) {
this.DataHost.StartCaching(this, MemberName);
}
///
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
private void StopCaching(string MemberName) {
this.DataHost.StopCaching(this, MemberName);
}
///
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
private bool IsCached(string MemberName) {
return this.DataHost.IsCached(this, MemberName);
}
///
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "15.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
private void BeginInitialization() {
this.BeginInit();
this.CustomTaskPanes.BeginInit();
this.VstoSmartTags.BeginInit();
}
///
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "15.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
private void EndInitialization() {
this.VstoSmartTags.EndInit();
this.CustomTaskPanes.EndInit();
this.EndInit();
}
///
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "15.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
private void InitializeControls() {
this.CustomTaskPanes = Globals.Factory.CreateCustomTaskPaneCollection(null, null, "CustomTaskPanes", "CustomTaskPanes", this);
this.VstoSmartTags = Globals.Factory.CreateSmartTagCollection(null, null, "VstoSmartTags", "VstoSmartTags", this);
}
///
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "15.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
private void InitializeComponents() {
}
///
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
private bool NeedsFill(string MemberName) {
return this.DataHost.NeedsFill(this, MemberName);
}
///
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "15.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
protected override void OnShutdown() {
this.VstoSmartTags.Dispose();
@ -170,22 +170,22 @@ namespace OfficeWalkthroughCS {
base.OnShutdown();
}
}
///
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "15.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
internal sealed partial class Globals {
///
///
private Globals() {
}
private static ThisAddIn _ThisAddIn;
private static global::Microsoft.Office.Tools.Excel.ApplicationFactory _factory;
private static ThisRibbonCollection _ThisRibbonCollection;
internal static ThisAddIn ThisAddIn {
get {
return _ThisAddIn;
@ -199,7 +199,7 @@ namespace OfficeWalkthroughCS {
}
}
}
internal static global::Microsoft.Office.Tools.Excel.ApplicationFactory Factory {
get {
return _factory;
@ -213,7 +213,7 @@ namespace OfficeWalkthroughCS {
}
}
}
internal static ThisRibbonCollection Ribbons {
get {
if ((_ThisRibbonCollection == null)) {
@ -223,14 +223,14 @@ namespace OfficeWalkthroughCS {
}
}
}
///
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "15.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "17.0.0.0")]
internal sealed partial class ThisRibbonCollection : Microsoft.Office.Tools.Ribbon.RibbonCollectionBase {
///
internal ThisRibbonCollection(global::Microsoft.Office.Tools.Ribbon.RibbonFactory factory) :
///
internal ThisRibbonCollection(global::Microsoft.Office.Tools.Ribbon.RibbonFactory factory) :
base(factory) {
}
}

Просмотреть файл

@ -0,0 +1,5 @@
<hostitem:hostItem hostitem:baseType="Microsoft.Office.Tools.AddInBase" hostitem:namespace="OfficeWalkthrough" hostitem:className="ThisAddIn" hostitem:identifier="ThisAddIn" hostitem:primaryCookie="AddIn" hostitem:master="true" hostitem:factoryType="Microsoft.Office.Tools.Excel.ApplicationFactory" hostitem:startupIndex="0" xmlns:hostitem="http://schemas.microsoft.com/2004/VisualStudio/Tools/Applications/HostItem.xsd">
<hostitem:hostObject hostitem:name="Application" hostitem:identifier="Application" hostitem:type="Microsoft.Office.Interop.Excel.Application" hostitem:cookie="Application" hostitem:modifier="Internal" />
<hostitem:hostControl hostitem:name="CustomTaskPanes" hostitem:identifier="CustomTaskPanes" hostitem:type="Microsoft.Office.Tools.CustomTaskPaneCollection" hostitem:primaryCookie="CustomTaskPanes" hostitem:modifier="Internal" />
<hostitem:hostControl hostitem:name="VstoSmartTags" hostitem:identifier="VstoSmartTags" hostitem:type="Microsoft.Office.Tools.SmartTagCollection" hostitem:primaryCookie="VstoSmartTags" hostitem:modifier="Internal" />
</hostitem:hostItem>

Просмотреть файл

@ -1,23 +1,17 @@
//
using System;
using System.Linq;
using System.Text;
using System.Xml.Linq;
//<snippet1>
using System;
//<Usings>
using System.Collections.Generic;
using Excel = Microsoft.Office.Interop.Excel;
using Word = Microsoft.Office.Interop.Word;
//</snippet1>
using Office = Microsoft.Office.Core;
using Microsoft.Office.Tools.Excel;
//</Usings>
namespace OfficeWalkthroughCS
namespace OfficeWalkthrough
{
public partial class ThisAddIn
{
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
//<snippet3>
//<CreateAccount>
var bankAccounts = new List<Account>
{
new Account
@ -31,9 +25,9 @@ namespace OfficeWalkthroughCS
Balance = -127.44
}
};
//</snippet3>
//</CreateAccount>
//<snippet9>
//<CallDisplay>
DisplayInExcel(bankAccounts, (account, cell) =>
// This multiline lambda expression sets custom processing rules
// for the bankAccounts.
@ -46,17 +40,17 @@ namespace OfficeWalkthroughCS
cell.Offset[0, 1].Interior.Color = 255;
}
});
//</snippet9>
//</CallDisplay>
//<snippet10>
//<PasteIntoWord>
var wordApp = new Word.Application();
wordApp.Visible = true;
wordApp.Documents.Add();
wordApp.Selection.PasteSpecial(Link: true, DisplayAsIcon: true);
//</snippet10>
//</PasteIntoWord>
}
//<snippet4>
//<Display>
void DisplayInExcel(IEnumerable<Account> accounts,
Action<Account, Excel.Range> DisplayFunc)
{
@ -76,7 +70,12 @@ namespace OfficeWalkthroughCS
// Copy the results to the Clipboard.
excelApp.Range["A1:B3"].Copy();
}
//</snippet4>
//</Display>
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
}
void Pieces(IEnumerable<Account> accounts,
Action<Account, Excel.Range> DisplayFunc)
@ -97,74 +96,16 @@ namespace OfficeWalkthroughCS
// Copy the results to the Clipboard.
excelApp.Range["A1:B3"].Copy();
//<snippet7>
//<AutoFit>
excelApp.Columns[1].AutoFit();
excelApp.Columns[2].AutoFit();
//</snippet7>
//</AutoFit>
//<snippet5>
//<IndexedProperties>
// Visual C# 2010 provides indexed properties for COM programming.
excelApp.Range["A1"].Value = "ID";
excelApp.ActiveCell.Offset[1, 0].Select();
//</snippet5>
//<snippet6>
// In Visual C# 2008, you cannot access the Range, Offset, and Value
// properties directly.
excelApp.get_Range("A1").Value2 = "ID";
excelApp.ActiveCell.get_Offset(1, 0).Select();
//</snippet6>
//<snippet8>
// Casting is required in Visual C# 2008.
((Excel.Range)excelApp.Columns[1]).AutoFit();
// Casting is not required in Visual C# 2010.
excelApp.Columns[1].AutoFit();
//</snippet8>
var wordApp = new Word.Application();
wordApp.Visible = true;
wordApp.Documents.Add();
//<snippet11>
// Call to PasteSpecial in Visual C# 2008.
object iconIndex = Type.Missing;
object link = true;
object placement = Type.Missing;
object displayAsIcon = true;
object dataType = Type.Missing;
object iconFileName = Type.Missing;
object iconLabel = Type.Missing;
wordApp.Selection.PasteSpecial(ref iconIndex,
ref link,
ref placement,
ref displayAsIcon,
ref dataType,
ref iconFileName,
ref iconLabel);
// Call to PasteSpecial in Visual C# 2010.
wordApp.Selection.PasteSpecial(Link: true, DisplayAsIcon: true);
//</snippet11>
// Snippets 12 and 13 are from Using Type dynamic.
//<snippet12>
// Before the introduction of dynamic.
((Excel.Range)excelApp.Cells[1, 1]).Value2 = "Name";
Excel.Range range2008 = (Excel.Range)excelApp.Cells[1, 1];
//</snippet12>
//<snippet13>
// After the introduction of dynamic, the access to the Value property and
// the conversion to Excel.Range are handled by the run-time COM binder.
excelApp.Cells[1, 1].Value = "Name";
Excel.Range range2010 = excelApp.Cells[1, 1];
//</snippet13>
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
//</IndexedProperties>
}
#region VSTO generated code
@ -178,7 +119,7 @@ namespace OfficeWalkthroughCS
this.Startup += new System.EventHandler(ThisAddIn_Startup);
this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
}
#endregion
}
}

Просмотреть файл

@ -0,0 +1,10 @@
namespace OfficeWalkthrough
{
//<AccountClass>
class Account
{
public int ID { get; set; }
public double Balance { get; set; }
}
//</AccountClass>
}

Просмотреть файл

@ -0,0 +1,17 @@
{
"host": "visualstudio",
"expectederrors": [
{
"file": "docs/csharp/advanced-topics/interop/snippets/OfficeWalkthrough/OfficeWalkthrough.csproj",
"line": 211,
"column": 3,
"error": "MSB4019"
},
{
"file": "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/MSBuild/Current/Bin/amd64/Microsoft.Common.CurrentVersion.targets",
"line": 3476,
"column": 5,
"error": "MSB3323"
}
]
}

73
docs/csharp/advanced-topics/interop/snippets/WinSound/Form1.Designer.cs сгенерированный Normal file
Просмотреть файл

@ -0,0 +1,73 @@
namespace WinSound;
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Text = "Form1";
//<Initialization>
this.button1 = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(192, 40);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(88, 24);
this.button1.TabIndex = 0;
this.button1.Text = "Browse";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(8, 40);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(168, 20);
this.textBox1.TabIndex = 1;
this.textBox1.Text = "File path";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Platform Invoke WinSound C#";
this.ResumeLayout(false);
this.PerformLayout();
//</Initialization>
}
#endregion
}

Просмотреть файл

@ -0,0 +1,56 @@
using System.Runtime.InteropServices;
namespace WinSound;
public partial class Form1 : Form
{
private TextBox textBox1;
private Button button1;
public Form1() // Constructor.
{
InitializeComponent();
}
[DllImport("winmm.DLL", EntryPoint = "PlaySound", SetLastError = true, CharSet = CharSet.Unicode, ThrowOnUnmappableChar = true)]
private static extern bool PlaySound(string szSound, System.IntPtr hMod, PlaySoundFlags flags);
[System.Flags]
public enum PlaySoundFlags : int
{
SND_SYNC = 0x0000,
SND_ASYNC = 0x0001,
SND_NODEFAULT = 0x0002,
SND_LOOP = 0x0008,
SND_NOSTOP = 0x0010,
SND_NOWAIT = 0x00002000,
SND_FILENAME = 0x00020000,
SND_RESOURCE = 0x00040004
}
private void button1_Click(object sender, System.EventArgs e)
{
var dialog1 = new OpenFileDialog();
dialog1.Title = "Browse to find sound file to play";
dialog1.InitialDirectory = @"c:\";
//<Snippet5>
dialog1.Filter = "Wav Files (*.wav)|*.wav";
//</Snippet5>
dialog1.FilterIndex = 2;
dialog1.RestoreDirectory = true;
if (dialog1.ShowDialog() == DialogResult.OK)
{
textBox1.Text = dialog1.FileName;
PlaySound(dialog1.FileName, new System.IntPtr(), PlaySoundFlags.SND_SYNC);
}
}
private void Form1_Load(object sender, EventArgs e)
{
// Including this empty method in the sample because in the IDE,
// when users click on the form, generates code that looks for a default method
// with this name. We add it here to prevent confusion for those using the samples.
}
}

Просмотреть файл

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

Просмотреть файл

@ -0,0 +1,16 @@
namespace WinSound;
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new Form1());
}
}

Просмотреть файл

@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net7.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>

Просмотреть файл

@ -0,0 +1,3 @@
{
"host": "visualstudio"
}

Просмотреть файл

@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
//<Snippet1>
using System.Linq;
using Microsoft.Scripting.Hosting;

Просмотреть файл

@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DynamicWalkthrough
{

Просмотреть файл

@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//<Snippet1>
using System.IO;
using System.Dynamic;

Просмотреть файл

@ -0,0 +1,82 @@
namespace TestDynamicSnippets
{
class UsingDynamic
{
//<Snippet50>
static void Main(string[] args)
{
ExampleClass ec = new ExampleClass();
// The following call to exampleMethod1 causes a compiler error
// if exampleMethod1 has only one parameter. Uncomment the line
// to see the error.
//ec.exampleMethod1(10, 4);
dynamic dynamic_ec = new ExampleClass();
// The following line is not identified as an error by the
// compiler, but it causes a run-time exception.
dynamic_ec.exampleMethod1(10, 4);
// The following calls also do not cause compiler errors, whether
// appropriate methods exist or not.
dynamic_ec.someMethod("some argument", 7, null);
dynamic_ec.nonexistentMethod();
}
//</Snippet50>
}
// <Snippet56>
class ExampleClass
{
public ExampleClass() { }
public ExampleClass(int v) { }
public void exampleMethod1(int i) { }
public void exampleMethod2(string str) { }
}
// </Snippet56>
class OtherExamples
{
static void Examples()
{
ExampleClass ec = new ExampleClass();
//<Snippet51>
dynamic d = 1;
var testSum = d + 3;
// Rest the mouse pointer over testSum in the following statement.
System.Console.WriteLine(testSum);
//</Snippet51>
//<Snippet52>
var testInstance = new ExampleClass(d);
//</Snippet52>
//<Snippet53>
dynamic d1 = 7;
dynamic d2 = "a string";
dynamic d3 = System.DateTime.Today;
dynamic d4 = System.Diagnostics.Process.GetProcesses();
//</Snippet53>
//<Snippet54>
int i = d1;
string str = d2;
DateTime dt = d3;
System.Diagnostics.Process[] procs = d4;
//</Snippet54>
//<Snippet55>
// Valid.
ec.exampleMethod2("a string");
// The following statement does not cause a compiler error, even though ec is not
// dynamic. A run-time exception is raised because the run-time type of d1 is int.
ec.exampleMethod2(d1);
// The following statement does cause a compiler error.
//ec.exampleMethod2(7);
//</Snippet55>
}
}
}

Просмотреть файл

@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<RootNamespace>using_dynamic</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

Просмотреть файл

@ -0,0 +1,66 @@
---
title: "Using type dynamic"
description: Learn how to use the dynamic type. The dynamic type is a static type, but dynamic objects bypass static type checking.
ms.date: 02/17/2023
helpviewer_keywords:
- "dynamic [C#], about dynamic type"
- "dynamic type [C#]"
---
# Using type dynamic
The `dynamic` type is a static type, but an object of type `dynamic` bypasses static type checking. In most cases, it functions like it has type `object`. The compiler assumes a `dynamic` element supports any operation. Therefore, you don't have to determine whether the object gets its value from a COM API, from a dynamic language such as IronPython, from the HTML Document Object Model (DOM), from reflection, or from somewhere else in the program. However, if the code isn't valid, errors surface at run time.
For example, if instance method `exampleMethod1` in the following code has only one parameter, the compiler recognizes that the first call to the method, `ec.exampleMethod1(10, 4)`, isn't valid because it contains two arguments. The call causes a compiler error. The compiler doesn't check the second call to the method, `dynamic_ec.exampleMethod1(10, 4)`, because the type of `dynamic_ec` is `dynamic`. Therefore, no compiler error is reported. However, the error doesn't escape notice indefinitely. It appears at run time and causes a run-time exception.
:::code language="csharp" source="./snippets/using-dynamic/Program.cs" id="Snippet50":::
:::code language="csharp" source="./snippets/using-dynamic/Program.cs" id="Snippet56":::
The role of the compiler in these examples is to package together information about what each statement is proposing to do to the `dynamic` object or expression. The runtime examines the stored information and any statement that isn't valid causes a run-time exception.
The result of most dynamic operations is itself `dynamic`. For example, if you rest the mouse pointer over the use of `testSum` in the following example, IntelliSense displays the type **(local variable) dynamic testSum**.
:::code language="csharp" source="./snippets/using-dynamic/Program.cs" id="Snippet51":::
Operations in which the result isn't `dynamic` include:
* Conversions from `dynamic` to another type.
* Constructor calls that include arguments of type `dynamic`.
For example, the type of `testInstance` in the following declaration is `ExampleClass`, not `dynamic`:
:::code language="csharp" source="./snippets/using-dynamic/Program.cs" id="Snippet52":::
## Conversions
Conversions between dynamic objects and other types are easy. Conversions enable the developer to switch between dynamic and non-dynamic behavior.
You can convert any to `dynamic` implicitly, as shown in the following examples.
:::code language="csharp" source="./snippets/using-dynamic/Program.cs" id="Snippet53":::
Conversely, you can dynamically apply any implicit conversion to any expression of type `dynamic`.
:::code language="csharp" source="./snippets/using-dynamic/Program.cs" id="Snippet54":::
## Overload resolution with arguments of type dynamic
Overload resolution occurs at run time instead of at compile time if one or more of the arguments in a method call have the type `dynamic`, or if the receiver of the method call is of type `dynamic`. In the following example, if the only accessible `exampleMethod2` method takes a string argument, sending `d1` as the argument doesn't cause a compiler error, but it does cause a run-time exception. Overload resolution fails at run time because the run-time type of `d1` is `int`, and `exampleMethod2` requires a string.
:::code language="csharp" source="./snippets/using-dynamic/Program.cs" id="Snippet55":::
## Dynamic language runtime
The dynamic language runtime (DLR) provides the infrastructure that supports the `dynamic` type in C#, and also the implementation of dynamic programming languages such as IronPython and IronRuby. For more information about the DLR, see [Dynamic Language Runtime Overview](../../../framework/reflection-and-codedom/dynamic-language-runtime-overview.md).
## COM interop
Many COM methods allow for variation in argument types and return type by designating the types as `object`. COM interop necessitates explicit casting of the values to coordinate with strongly typed variables in C#. If you compile by using the [**EmbedInteropTypes** (C# Compiler Options)](../../language-reference/compiler-options/inputs.md#embedinteroptypes) option, the introduction of the `dynamic` type enables you to treat the occurrences of `object` in COM signatures as if they were of type `dynamic`, and thereby to avoid much of the casting. For more information on using the `dynamic` type with COM objects, see the article on [How to access Office interop objects by using C# features](./how-to-access-office-interop-objects.md).
## Related articles
|Title|Description|
|-----------|-----------------|
|[dynamic](../../language-reference/builtin-types/reference-types.md)|Describes the usage of the `dynamic` keyword.|
|[Dynamic Language Runtime Overview](../../../framework/reflection-and-codedom/dynamic-language-runtime-overview.md)|Provides an overview of the DLR, which is a runtime environment that adds a set of services for dynamic languages to the common language runtime (CLR).|
|[Walkthrough: Creating and Using Dynamic Objects](walkthrough-creating-and-using-dynamic-objects.md)|Provides step-by-step instructions for creating a custom dynamic object and for creating a project that accesses an `IronPython` library.|

Просмотреть файл

@ -0,0 +1,125 @@
---
title: "Walkthrough: Creating and Using Dynamic Objects in C#"
description: Learn how to create and use dynamic objects in this walkthrough. Create a custom dynamic object and a project that uses an 'IronPython' library.
ms.date: 02/17/2023
helpviewer_keywords:
- "dynamic objects"
- "dynamic objects [C#]"
---
# Walkthrough: Creating and Using Dynamic Objects in C\#
Dynamic objects expose members such as properties and methods at run time, instead of at compile time. Dynamic objects enable you to create objects to work with structures that don't match a static type or format. For example, you can use a dynamic object to reference the HTML Document Object Model (DOM), which can contain any combination of valid HTML markup elements and attributes. Because each HTML document is unique, the members for a particular HTML document are determined at run time. A common method to reference an attribute of an HTML element is to pass the name of the attribute to the `GetProperty` method of the element. To reference the `id` attribute of the HTML element `<div id="Div1">`, you first obtain a reference to the `<div>` element, and then use `divElement.GetProperty("id")`. If you use a dynamic object, you can reference the `id` attribute as `divElement.id`.
Dynamic objects also provide convenient access to dynamic languages such as IronPython and IronRuby. You can use a dynamic object to refer to a dynamic script interpreted at run time.
You reference a dynamic object by using late binding. You specify the type of a late-bound object as `dynamic`.For more information, see [dynamic](../../language-reference/builtin-types/reference-types.md).
You can create custom dynamic objects by using the classes in the <xref:System.Dynamic?displayProperty=nameWithType> namespace. For example, you can create an <xref:System.Dynamic.ExpandoObject> and specify the members of that object at run time. You can also create your own type that inherits the <xref:System.Dynamic.DynamicObject> class. You can then override the members of the <xref:System.Dynamic.DynamicObject> class to provide run-time dynamic functionality.
This article contains two independent walkthroughs:
- Create a custom object that dynamically exposes the contents of a text file as properties of an object.
- Create a project that uses an `IronPython` library.
## Prerequisites
* [Visual Studio 2022 version 17.3 or a later version](https://visualstudio.microsoft.com/downloads/?utm_medium=microsoft&utm_source=learn.microsoft.com&utm_campaign=inline+link&utm_content=download+vs2019) with the **.NET desktop development** workload installed. The .NET 7 SDK is included when you select this workload.
[!INCLUDE[note_settings_general](~/includes/note-settings-general-md.md)]
* For the second walkthrough, install [IronPython](https://ironpython.net/) for .NET. Go to their [Download page](https://ironpython.net/download/) to obtain the latest version.
## Create a Custom Dynamic Object
The first walkthrough defines a custom dynamic object that searches the contents of a text file. A dynamic property specifies the text to search for. For example, if calling code specifies `dynamicFile.Sample`, the dynamic class returns a generic list of strings that contains all of the lines from the file that begin with "Sample". The search is case-insensitive. The dynamic class also supports two optional arguments. The first argument is a search option enum value that specifies that the dynamic class should search for matches at the start of the line, the end of the line, or anywhere in the line. The second argument specifies that the dynamic class should trim leading and trailing spaces from each line before searching. For example, if calling code specifies `dynamicFile.Sample(StringSearchOption.Contains)`, the dynamic class searches for "Sample" anywhere in a line. If calling code specifies `dynamicFile.Sample(StringSearchOption.StartsWith, false)`, the dynamic class searches for "Sample" at the start of each line, and doesn't remove leading and trailing spaces. The default behavior of the dynamic class is to search for a match at the start of each line and to remove leading and trailing spaces.
### Create a custom dynamic class
Start Visual Studio. Select **Create a new project**. In the **Create a new project** dialog, select C#, select **Console Application**, and then select **Next**. In the **Configure your new project** dialog, enter `DynamicSample` for the **Project name**, and then select **Next**. In the **Additional information** dialog, select **.NET 7.0 (Current)** for the **Target Framework**, and then select **Create**. In **Solution Explorer**, right-click the DynamicSample project and select **Add** > **Class**. In the **Name** box, type `ReadOnlyFile`, and then select **Add**. At the top of the *ReadOnlyFile.cs* or *ReadOnlyFile.vb* file, add the following code to import the <xref:System.IO?displayProperty=nameWithType> and <xref:System.Dynamic?displayProperty=nameWithType> namespaces.
:::code language="csharp" source="./snippets/dynamic-walkthrough/readonlyfile.cs" id="Snippet1":::
The custom dynamic object uses an enum to determine the search criteria. Before the class statement, add the following enum definition.
:::code language="csharp" source="./snippets/dynamic-walkthrough/readonlyfile.cs" id="Snippet2":::
Update the class statement to inherit the `DynamicObject` class, as shown in the following code example.
:::code language="csharp" source="./snippets/dynamic-walkthrough/readonlyfile.cs" id="Snippet3":::
Add the following code to the `ReadOnlyFile` class to define a private field for the file path and a constructor for the `ReadOnlyFile` class.
:::code language="csharp" source="./snippets/dynamic-walkthrough/readonlyfile.cs" id="Snippet4":::
1. Add the following `GetPropertyValue` method to the `ReadOnlyFile` class. The `GetPropertyValue` method takes, as input, search criteria and returns the lines from a text file that match that search criteria. The dynamic methods provided by the `ReadOnlyFile` class call the `GetPropertyValue` method to retrieve their respective results.
:::code language="csharp" source="./snippets/dynamic-walkthrough/readonlyfile.cs" id="Snippet5":::
After the `GetPropertyValue` method, add the following code to override the <xref:System.Dynamic.DynamicObject.TryGetMember%2A> method of the <xref:System.Dynamic.DynamicObject> class. The <xref:System.Dynamic.DynamicObject.TryGetMember%2A> method is called when a member of a dynamic class is requested and no arguments are specified. The `binder` argument contains information about the referenced member, and the `result` argument references the result returned for the specified member. The <xref:System.Dynamic.DynamicObject.TryGetMember%2A> method returns a Boolean value that returns `true` if the requested member exists; otherwise it returns `false`.
:::code language="csharp" source="./snippets/dynamic-walkthrough/readonlyfile.cs" id="Snippet6":::
After the `TryGetMember` method, add the following code to override the <xref:System.Dynamic.DynamicObject.TryInvokeMember%2A> method of the <xref:System.Dynamic.DynamicObject> class. The <xref:System.Dynamic.DynamicObject.TryInvokeMember%2A> method is called when a member of a dynamic class is requested with arguments. The `binder` argument contains information about the referenced member, and the `result` argument references the result returned for the specified member. The `args` argument contains an array of the arguments that are passed to the member. The <xref:System.Dynamic.DynamicObject.TryInvokeMember%2A> method returns a Boolean value that returns `true` if the requested member exists; otherwise it returns `false`.
The custom version of the `TryInvokeMember` method expects the first argument to be a value from the `StringSearchOption` enum that you defined in a previous step. The `TryInvokeMember` method expects the second argument to be a Boolean value. If one or both arguments are valid values, they're passed to the `GetPropertyValue` method to retrieve the results.
:::code language="csharp" source="./snippets/dynamic-walkthrough/readonlyfile.cs" id="Snippet7":::
Save and close the file.
### Create a sample text file
In **Solution Explorer**, right-click the DynamicSample project and select **Add** > **New Item**. In the **Installed Templates** pane, select **General**, and then select the **Text File** template. Leave the default name of *TextFile1.txt* in the **Name** box, and then select **Add**. Copy the following text to the *TextFile1.txt* file.
```text
List of customers and suppliers
Supplier: Lucerne Publishing (https://www.lucernepublishing.com/)
Customer: Preston, Chris
Customer: Hines, Patrick
Customer: Cameron, Maria
Supplier: Graphic Design Institute (https://www.graphicdesigninstitute.com/)
Supplier: Fabrikam, Inc. (https://www.fabrikam.com/)
Customer: Seubert, Roxanne
Supplier: Proseware, Inc. (http://www.proseware.com/)
Customer: Adolphi, Stephan
Customer: Koch, Paul
```
Save and close the file.
### Create a sample application that uses the custom dynamic object
In **Solution Explorer**, double-click the *Program.cs* file. Add the following code to the `Main` procedure to create an instance of the `ReadOnlyFile` class for the *TextFile1.txt* file. The code uses late binding to call dynamic members and retrieve lines of text that contain the string "Customer".
:::code language="csharp" source="./snippets/dynamic-walkthrough/program.cs" id="Snippet8":::
Save the file and press <kbd>Ctrl</kdb>+<kbd>F5</kbd> to build and run the application.
## Call a dynamic language library
The following walkthrough creates a project that accesses a library written in the dynamic language IronPython.
### To create a custom dynamic class
In Visual Studio, select **File** > **New** > **Project**. In the **Create a new project** dialog, select C#, select **Console Application**, and then select **Next**. In the **Configure your new project** dialog, enter `DynamicIronPythonSample` for the **Project name**, and then select **Next**. In the **Additional information** dialog, select **.NET 7.0 (Current)** for the **Target Framework**, and then select **Create**. Install the [IronPython](https://www.nuget.org/packages/IronPython) NuGet package. Edit the *Program.cs* file. At the top of the file, add the following code to import the `Microsoft.Scripting.Hosting` and `IronPython.Hosting` namespaces from the IronPython libraries and the `System.Linq` namespace.
:::code language="csharp" source="./snippets/dynamic-iron-python-walkthrough/program.cs" id="Snippet1":::
In the Main method, add the following code to create a new `Microsoft.Scripting.Hosting.ScriptRuntime` object to host the IronPython libraries. The `ScriptRuntime` object loads the IronPython library module random.py.
:::code language="csharp" source="./snippets/dynamic-iron-python-walkthrough/program.cs" id="Snippet2":::
After the code to load the random.py module, add the following code to create an array of integers. The array is passed to the `shuffle` method of the random.py module, which randomly sorts the values in the array.
:::code language="csharp" source="./snippets/dynamic-iron-python-walkthrough/program.cs" id="Snippet3":::
Save the file and press <kbd>Ctrl</kdb>+<kbd>F5</kbd> to build and run the application.
## See also
- <xref:System.Dynamic?displayProperty=nameWithType>
- <xref:System.Dynamic.DynamicObject?displayProperty=nameWithType>
- [Using Type dynamic](./using-type-dynamic.md)
- [dynamic](../../language-reference/builtin-types/reference-types.md)
- [Implementing Dynamic Interfaces (downloadable PDF from Microsoft TechNet)](https://download.microsoft.com/download/5/4/B/54B83DFE-D7AA-4155-9687-B0CF58FF65D7/implementing-dynamic-interfaces.pdf)

Просмотреть файл

@ -0,0 +1,131 @@
---
title: "Walkthrough: Office Programming - C#"
description: Learn about the features Visual Studio offers that improve Microsoft Office programming.
ms.date: 02/15/2023
ms.topic: tutorial
dev_langs:
- "csharp"
helpviewer_keywords:
- "Office programming [C#]"
---
# Walkthrough: Office Programming in C\#
C# offers features that improve Microsoft Office programming. Helpful C# features include named and optional arguments and return values of type `dynamic`. In COM programming, you can omit the `ref` keyword and gain access to indexed properties.
Both languages enable embedding of type information, which allows deployment of assemblies that interact with COM components without deploying primary interop assemblies (PIAs) to the user's computer. For more information, see [Walkthrough: Embedding Types from Managed Assemblies](../../../standard/assembly/embed-types-visual-studio.md).
This walkthrough demonstrates these features in the context of Office programming, but many of these features are also useful in general programming. In the walkthrough, you use an Excel Add-in application to create an Excel workbook. Next, you create a Word document that contains a link to the workbook. Finally, you see how to enable and disable the PIA dependency.
## Prerequisites
You must have Microsoft Office Excel and Microsoft Office Word installed on your computer to complete this walkthrough.
[!INCLUDE[note_settings_general](~/includes/note-settings-general-md.md)]
## Set up an Excel Add-in application
1. Start Visual Studio.
1. On the **File** menu, point to **New**, and then select **Project**.
1. In the **Installed Templates** pane, expand **C#**, expand **Office**, and then select the version year of the Office product.
1. In the **Templates** pane, select **Excel \<version> Add-in**.
1. Look at the top of the **Templates** pane to make sure that **.NET Framework 4**, or a later version, appears in the **Target Framework** box.
1. Type a name for your project in the **Name** box, if you want to.
1. Select **OK**.
1. The new project appears in **Solution Explorer**.
## Add references
1. In **Solution Explorer**, right-click your project's name and then select **Add Reference**. The **Add Reference** dialog box appears.
1. On the **Assemblies** tab, select **Microsoft.Office.Interop.Excel**, version `<version>.0.0.0` (for a key to the Office product version numbers, see [Microsoft Versions](https://en.wikipedia.org/wiki/Microsoft_Office#Versions)), in the **Component Name** list, and then hold down the CTRL key and select **Microsoft.Office.Interop.Word**, `version <version>.0.0.0`. If you don't see the assemblies, you may need to install them (see [How to: Install Office Primary Interop Assemblies](/visualstudio/vsto/how-to-install-office-primary-interop-assemblies)).
1. Select **OK**.
## Add necessary Imports statements or using directives
In **Solution Explorer**, right-click the **ThisAddIn.cs** file and then select **View Code**. Add the following `using` directives (C#) to the top of the code file if they aren't already present.
:::code language="csharp" source="./snippets/OfficeWalkthrough/ThisAddIn.cs" id="Usings":::
## Create a list of bank accounts
In **Solution Explorer**, right-click your project's name, select **Add**, and then select **Class**. Name the class Account.cs. Select **Add**. Replace the definition of the `Account` class with the following code. The class definitions use *auto-implemented properties*.
:::code language="csharp" source="./snippets/OfficeWalkthrough/account.cs" id="AccountClass":::
To create a `bankAccounts` list that contains two accounts, add the following code to the `ThisAddIn_Startup` method in *ThisAddIn.cs*. The list declarations use *collection initializers*.
:::code language="csharp" source="./snippets/OfficeWalkthrough/ThisAddIn.cs" id="CreateAccount":::
## Export data to Excel
In the same file, add the following method to the `ThisAddIn` class. The method sets up an Excel workbook and exports data to it.
:::code language="csharp" source="./snippets/OfficeWalkthrough/ThisAddIn.cs" id="Display":::
- Method [Add](<xref:Microsoft.Office.Interop.Excel.Workbooks.Add%2A>) has an *optional parameter* for specifying a particular template. Optional parameters enable you to omit the argument for that parameter if you want to use the parameter's default value. Because the previous example has no arguments, `Add` uses the default template and creates a new workbook. The equivalent statement in earlier versions of C# requires a placeholder argument: `excelApp.Workbooks.Add(Type.Missing)`. For more information, see [Named and Optional Arguments](../../programming-guide/classes-and-structs/named-and-optional-arguments.md).
- The `Range` and `Offset` properties of the [Range](<xref:Microsoft.Office.Interop.Excel.Range>) object use the *indexed properties* feature. This feature enables you to consume these properties from COM types by using the following typical C# syntax. Indexed properties also enable you to use the `Value` property of the `Range` object, eliminating the need to use the `Value2` property. The `Value` property is indexed, but the index is optional. Optional arguments and indexed properties work together in the following example.
:::code language="csharp" source="./snippets/OfficeWalkthrough/ThisAddIn.cs" id="IndexedProperties":::
You can't create indexed properties of your own. The feature only supports consumption of existing indexed properties.
Add the following code at the end of `DisplayInExcel` to adjust the column widths to fit the content.
:::code language="csharp" source="./snippets/OfficeWalkthrough/ThisAddIn.cs" id="AutoFit":::
These additions demonstrate another feature in C#: treating `Object` values returned from COM hosts such as Office as if they have type [dynamic](../../language-reference/builtin-types/reference-types.md). COM objects are treated as `dynamic` automatically when **Embed Interop Types** has its default value, `True`, or, equivalently, when you reference the assembly with the [**EmbedInteropTypes**](../../language-reference/compiler-options/inputs.md#embedinteroptypes) compiler option. For more information about embedding interop types, see procedures "To find the PIA reference" and "To restore the PIA dependency" later in this article. For more information about `dynamic`, see [dynamic](../../language-reference/builtin-types/reference-types.md) or [Using Type dynamic](using-type-dynamic.md).
## Invoke DisplayInExcel
Add the following code at the end of the `ThisAddIn_StartUp` method. The call to `DisplayInExcel` contains two arguments. The first argument is the name of the list of accounts processed. The second argument is a multiline lambda expression defining how to process the data. The `ID` and `balance` values for each account are displayed in adjacent cells, and the row is displayed in red if the balance is less than zero. For more information, see [Lambda Expressions](../../language-reference/operators/lambda-expressions.md).
:::code language="csharp" source="./snippets/OfficeWalkthrough/ThisAddIn.cs" id="CallDisplay":::
To run the program, press F5. An Excel worksheet appears that contains the data from the accounts.
## Add a Word document
Add the following code at the end of the `ThisAddIn_StartUp` method to create a Word document that contains a link to the Excel workbook.
:::code language="csharp" source="./snippets/OfficeWalkthrough/ThisAddIn.cs" id="PasteIntoWord":::
This code demonstrates several of the features in C#: the ability to omit the `ref` keyword in COM programming, named arguments, and optional arguments.The [PasteSpecial](<xref:Microsoft.Office.Interop.Word.Selection.PasteSpecial%2A>) method has seven parameters, all of which are optional reference parameters. Named and optional arguments enable you to designate the parameters you want to access by name and to send arguments to only those parameters. In this example, arguments indicate creating a link to the workbook on the Clipboard (parameter `Link`) and displaying that the link in the Word document as an icon (parameter `DisplayAsIcon`). C# also enables you to omit the `ref` keyword for these arguments.
## Run the application
Press F5 to run the application. Excel starts and displays a table that contains the information from the two accounts in `bankAccounts`. Then a Word document appears that contains a link to the Excel table.
## Clean up the completed project
In Visual Studio, select **Clean Solution** on the **Build** menu. Otherwise, the add-in runs every time that you open Excel on your computer.
## Find the PIA reference
1. Run the application again, but don't select **Clean Solution**.
1. Select the **Start**. Locate **Microsoft Visual Studio \<version>** and open a developer command prompt.
1. Type `ildasm` in the Developer Command Prompt for Visual Studio window, and then press ENTER. The IL DASM window appears.
1. On the **File** menu in the IL DASM window, select **File** > **Open**. Double-click **Visual Studio \<version>**, and then double-click **Projects**. Open the folder for your project, and look in the bin/Debug folder for *your project name*.dll. Double-click *your project name*.dll. A new window displays your project's attributes, in addition to references to other modules and assemblies. The assembly includes the namespaces `Microsoft.Office.Interop.Excel` and `Microsoft.Office.Interop.Word`. By default in Visual Studio, the compiler imports the types you need from a referenced PIA into your assembly. For more information, see [How to: View Assembly Contents](../../../standard/assembly/view-contents.md).
1. Double-click the **MANIFEST** icon. A window appears that contains a list of assemblies that contain items referenced by the project. `Microsoft.Office.Interop.Excel` and `Microsoft.Office.Interop.Word` aren't in the list. Because you imported the types your project needs into your assembly, you aren't required to install references to a PIA. Importing the types into your assembly makes deployment easier. The PIAs don't have to be present on the user's computer. An application doesn't require deployment of a specific version of a PIA. Applications can work with multiple versions of Office, provided that the necessary APIs exist in all versions. Because deployment of PIAs is no longer necessary, you can create an application in advanced scenarios that works with multiple versions of Office, including earlier versions. Your code can't use any APIs that aren't available in the version of Office you're working with. It isn't always clear whether a particular API was available in an earlier version. Working with earlier versions of Office isn't recommended.
1. Close the manifest window and the assembly window.
## Restore the PIA dependency
1. In **Solution Explorer**, select the **Show All Files** button. Expand the **References** folder and select **Microsoft.Office.Interop.Excel**. Press F4 to display the **Properties** window.
1. In the **Properties** window, change the **Embed Interop Types** property from **True** to **False**.
1. Repeat steps 1 and 2 in this procedure for `Microsoft.Office.Interop.Word`.
1. In C#, comment out the two calls to `Autofit` at the end of the `DisplayInExcel` method.
1. Press F5 to verify that the project still runs correctly.
1. Repeat steps 1-3 from the previous procedure to open the assembly window. Notice that `Microsoft.Office.Interop.Word` and `Microsoft.Office.Interop.Excel` are no longer in the list of embedded assemblies.
1. Double-click the **MANIFEST** icon and scroll through the list of referenced assemblies. Both `Microsoft.Office.Interop.Word` and `Microsoft.Office.Interop.Excel` are in the list. Because the application references the Excel and Word PIAs, and the **Embed Interop Types** property is **False**, both assemblies must exist on the end user's computer.
1. In Visual Studio, select **Clean Solution** on the **Build** menu to clean up the completed project.
## See also
- [Auto-Implemented Properties (C#)](../../programming-guide/classes-and-structs/auto-implemented-properties.md)
- [Object and Collection Initializers](../../programming-guide/classes-and-structs/object-and-collection-initializers.md)
- [Named and Optional Arguments](../../programming-guide/classes-and-structs/named-and-optional-arguments.md)
- [dynamic](../../language-reference/builtin-types/reference-types.md)
- [Using Type dynamic](using-type-dynamic.md)
- [Lambda Expressions (C#)](../../language-reference/operators/lambda-expressions.md)
- [Walkthrough: Embedding Type Information from Microsoft Office Assemblies in Visual Studio](/previous-versions/visualstudio/visual-studio-2013/ee317478(v=vs.120))
- [Walkthrough: Embedding Types from Managed Assemblies](../../../standard/assembly/embed-types-visual-studio.md)
- [Walkthrough: Creating Your First VSTO Add-in for Excel](/visualstudio/vsto/walkthrough-creating-your-first-vsto-add-in-for-excel)

Просмотреть файл

@ -277,7 +277,7 @@ The following sections describe practices that the C# team follows to prepare co
:::code language="csharp" source="./snippets/coding-conventions/program.cs" id="Snippet10":::
- Avoid the use of `var` in place of [dynamic](../../language-reference/builtin-types/reference-types.md). Use `dynamic` when you want run-time type inference. For more information, see [Using type dynamic (C# Programming Guide)](../../programming-guide/types/using-type-dynamic.md).
- Avoid the use of `var` in place of [dynamic](../../language-reference/builtin-types/reference-types.md). Use `dynamic` when you want run-time type inference. For more information, see [Using type dynamic (C# Programming Guide)](../../advanced-topics/interop/using-type-dynamic.md).
- Use implicit typing to determine the type of the loop variable in [`for`](../../language-reference/statements/iteration-statements.md#the-for-statement) loops.

Просмотреть файл

@ -287,13 +287,13 @@ For more information, see the following sections of the [C# language specificati
- [C# Reference](../index.md)
- [C# Keywords](../keywords/index.md)
- [Events](../../programming-guide/events/index.md)
- [Using Type dynamic](../../programming-guide/types/using-type-dynamic.md)
- [Using Type dynamic](../../advanced-topics/interop/using-type-dynamic.md)
- [Best Practices for Using Strings](../../../standard/base-types/best-practices-strings.md)
- [Basic String Operations](../../../standard/base-types/basic-string-operations.md)
- [Creating New Strings](../../../standard/base-types/creating-new.md)
- [Type-testing and cast operators](../operators/type-testing-and-cast.md)
- [How to safely cast using pattern matching and the as and is operators](../../fundamentals/tutorials/safely-cast-using-pattern-matching-is-and-as-operators.md)
- [Walkthrough: creating and using dynamic objects](../../programming-guide/types/walkthrough-creating-and-using-dynamic-objects.md)
- [Walkthrough: creating and using dynamic objects](../../advanced-topics/interop/walkthrough-creating-and-using-dynamic-objects.md)
- <xref:System.Object?displayProperty=nameWithType>
- <xref:System.String?displayProperty=nameWithType>
- <xref:System.Dynamic.DynamicObject?displayProperty=nameWithType>

Просмотреть файл

@ -40,4 +40,4 @@ unsafe public class C
## See also
- [Interoperability](../../programming-guide/interop/index.md)
- [Interoperability](../../advanced-topics/interop/index.md)

Просмотреть файл

@ -1,109 +0,0 @@
---
title: "How to use named and optional arguments in Office programming - C# Programming Guide"
description: Learn how to use named arguments and optional arguments to facilitate access to COM interfaces such as the Microsoft Office automation APIs.
ms.date: 07/20/2015
helpviewer_keywords:
- "named and optional arguments [C#], Office programming"
- "optional arguments [C#], Office programming"
- "named arguments [C#], Office programming"
ms.topic: how-to
ms.custom: contperf-fy21q2
ms.assetid: 65b8a222-bcd8-454c-845f-84adff5a356f
---
# How to use named and optional arguments in Office programming (C# Programming Guide)
Named arguments and optional arguments enhance convenience, flexibility, and readability in C# programming. In addition, these features greatly facilitate access to COM interfaces such as the Microsoft Office automation APIs.
In the following example, method [ConvertToTable](<xref:Microsoft.Office.Interop.Word.Range.ConvertToTable%2A>) has sixteen parameters that represent characteristics of a table, such as number of columns and rows, formatting, borders, fonts, and colors. All sixteen parameters are optional, because most of the time you do not want to specify particular values for all of them. However, without named and optional arguments, a value or a placeholder value has to be provided for each parameter. With named and optional arguments, you specify values only for the parameters that are required for your project.
You must have Microsoft Office Word installed on your computer to complete these procedures.
[!INCLUDE[note_settings_general](~/includes/note-settings-general-md.md)]
## To create a new console application
1. Start Visual Studio.
2. On the **File** menu, point to **New**, and then click **Project**.
3. In the **Templates Categories** pane, expand **Visual C#**, and then click **Windows**.
4. Look in the top of the **Templates** pane to make sure that **.NET Framework 4** appears in the **Target Framework** box.
5. In the **Templates** pane, click **Console Application**.
6. Type a name for your project in the **Name** field.
7. Click **OK**.
The new project appears in **Solution Explorer**.
## To add a reference
1. In **Solution Explorer**, right-click your project's name and then click **Add Reference**. The **Add Reference** dialog box appears.
2. On the **.NET** page, select **Microsoft.Office.Interop.Word** in the **Component Name** list.
3. Click **OK**.
## To add necessary using directives
1. In **Solution Explorer**, right-click the *Program.cs* file and then click **View Code**.
2. Add the following `using` directives to the top of the code file:
[!code-csharp[csProgGuideNamedAndOptional#4](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguidenamedandoptional/cs/wordprogram.cs#4)]
## To display text in a Word document
1. In the `Program` class in *Program.cs*, add the following method to create a Word application and a Word document. The [Add](<xref:Microsoft.Office.Interop.Word.Documents.Add%2A>) method has four optional parameters. This example uses their default values. Therefore, no arguments are necessary in the calling statement.
[!code-csharp[csProgGuideNamedAndOptional#6](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguidenamedandoptional/cs/wordprogram.cs#6)]
2. Add the following code at the end of the method to define where to display text in the document, and what text to display:
[!code-csharp[csProgGuideNamedAndOptional#7](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguidenamedandoptional/cs/wordprogram.cs#7)]
## To run the application
1. Add the following statement to Main:
[!code-csharp[csProgGuideNamedAndOptional#8](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguidenamedandoptional/cs/wordprogram.cs#8)]
2. Press <kbd>CTRL</kbd>+<kbd>F5</kbd> to run the project. A Word document appears that contains the specified text.
## To change the text to a table
1. Use the `ConvertToTable` method to enclose the text in a table. The method has sixteen optional parameters. IntelliSense encloses optional parameters in brackets, as shown in the following illustration.
![List of parameters for ConvertToTable method](./media/how-to-use-named-and-optional-arguments-in-office-programming/convert-table-parameters.png)
Named and optional arguments enable you to specify values for only the parameters that you want to change. Add the following code to the end of method `DisplayInWord` to create a simple table. The argument specifies that the commas in the text string in `range` separate the cells of the table.
[!code-csharp[csProgGuideNamedAndOptional#9](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguidenamedandoptional/cs/wordprogram.cs#9)]
In earlier versions of C#, the call to `ConvertToTable` requires a reference argument for each parameter, as shown in the following code:
[!code-csharp[csProgGuideNamedAndOptional#14](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguidenamedandoptional/cs/wordprogram.cs#14)]
2. Press <kbd>CTRL</kbd>+<kbd>F5</kbd> to run the project.
## To experiment with other parameters
1. To change the table so that it has one column and three rows, replace the last line in `DisplayInWord` with the following statement and then type <kbd>CTRL</kbd>+<kbd>F5</kbd>.
[!code-csharp[csProgGuideNamedAndOptional#10](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguidenamedandoptional/cs/wordprogram.cs#10)]
2. To specify a predefined format for the table, replace the last line in `DisplayInWord` with the following statement and then type <kbd>CTRL</kbd>+<kbd>F5</kbd>. The format can be any of the [WdTableFormat](<xref:Microsoft.Office.Interop.Word.WdTableFormat>) constants.
[!code-csharp[csProgGuideNamedAndOptional#11](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguidenamedandoptional/cs/wordprogram.cs#11)]
## Example
The following code includes the full example:
[!code-csharp[csProgGuideNamedAndOptional#12](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguidenamedandoptional/cs/wordprogram.cs#12)]
## See also
- [Named and Optional Arguments](./named-and-optional-arguments.md)

Просмотреть файл

@ -2,7 +2,6 @@
title: "Named and Optional Arguments - C# Programming Guide"
description: Named arguments in C# specify arguments by name, not position. Optional arguments can be omitted.
ms.date: 09/25/2020
ms.custom: contperf-fy21q1
f1_keywords:
- "namedParameter_CSharpKeyword"
- "optionalParameter_CSharpKeyword"
@ -67,7 +66,7 @@ PrintOrderDetails(productName: "Red Mug", 31, "Gift Shop");
The following code implements the examples from this section along with some additional ones.
[!code-csharp[csProgGuideNamedAndOptional#1](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguidenamedandoptional/cs/program.cs#1)]
:::code language="csharp" source="./snippets/NamedAndOptional/program.cs" id="Snippet1":::
## Optional arguments
@ -81,7 +80,7 @@ Each optional parameter has a default value as part of its definition. If no arg
Optional parameters are defined at the end of the parameter list, after any required parameters. If the caller provides an argument for any one of a succession of optional parameters, it must provide arguments for all preceding optional parameters. Comma-separated gaps in the argument list aren't supported. For example, in the following code, instance method `ExampleMethod` is defined with one required and two optional parameters.
[!code-csharp[csProgGuideNamedAndOptional#15](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguidenamedandoptional/cs/optional.cs#15)]
:::code language="csharp" source="./snippets/NamedAndOptional/optional.cs" id="Snippet15":::
The following call to `ExampleMethod` causes a compiler error, because an argument is provided for the third parameter but not for the second.
@ -106,7 +105,7 @@ IntelliSense uses brackets to indicate optional parameters, as shown in the foll
In the following example, the constructor for `ExampleClass` has one parameter, which is optional. Instance method `ExampleMethod` has one required parameter, `required`, and two optional parameters, `optionalstr` and `optionalint`. The code in `Main` shows the different ways in which the constructor and method can be invoked.
[!code-csharp[csProgGuideNamedAndOptional#2](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguidenamedandoptional/cs/optional.cs#2)]
:::code language="csharp" source="./snippets/NamedAndOptional/optional.cs" id="Snippet2":::
The preceding code shows a number of examples where optional parameters aren't applied correctly. The first illustrates that an argument must be supplied for the first parameter, which is required.
@ -120,9 +119,9 @@ For example, the <xref:Microsoft.Office.Interop.Excel.Range.AutoFormat%2A> metho
However, you can greatly simplify the call to `AutoFormat` by using named and optional arguments. Named and optional arguments enable you to omit the argument for an optional parameter if you don't want to change the parameter's default value. In the following call, a value is specified for only one of the seven parameters.
[!code-csharp[csProgGuideNamedAndOptional#13](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguidenamedandoptional/cs/namedandoptcom.cs#13)]
:::code language="csharp" source="./snippets/NamedAndOptional/namedandoptcom.cs" id="Snippet13":::
For more information and examples, see [How to use named and optional arguments in Office programming](./how-to-use-named-and-optional-arguments-in-office-programming.md) and [How to access Office interop objects by using C# features](../interop/how-to-access-office-onterop-objects.md).
For more information and examples, see [How to use named and optional arguments in Office programming](../../advanced-topics/interop/how-to-use-named-and-optional-arguments-in-office-programming.md) and [How to access Office interop objects by using C# features](../../advanced-topics/interop/how-to-access-office-interop-objects.md).
## Overload resolution

Просмотреть файл

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/></startup></configuration>

Просмотреть файл

@ -1,8 +1,4 @@
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NamedAndOptionalSnippets
{

Просмотреть файл

@ -12,7 +12,6 @@
<AssemblyName>NamedAndOptionalSnippets</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<StartupObject>OfficeHowTo.WordProgram</StartupObject>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
@ -34,12 +33,14 @@
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<StartupObject>OptionalNamespace.OptionalExample</StartupObject>
</PropertyGroup>
<ItemGroup>
<Compile Include="NamedAndOptCOM.cs" />
<Compile Include="Optional.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="WordProgram.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />

Просмотреть файл

@ -1,8 +1,5 @@
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//<Snippet2>
namespace OptionalNamespace
@ -59,7 +56,7 @@ namespace OptionalNamespace
//<Snippet15>
public void ExampleMethod(int required, string optionalstr = "default string",
int optionalint = 10)
//</Snippet15>
//</Snippet15>
{
Console.WriteLine(
$"{_name}: {required}, {optionalstr}, and {optionalint}.");

Просмотреть файл

@ -7,9 +7,6 @@
// Then, make sure no new errors are added.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NamedAndOptionalSnippets
{

Просмотреть файл

@ -1,17 +1,16 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("OfficeWalkthroughCS")]
[assembly: AssemblyTitle("NamedAndOptionalSnippets")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft IT")]
[assembly: AssemblyProduct("OfficeWalkthroughCS")]
[assembly: AssemblyCopyright("Copyright © Microsoft IT 2009")]
[assembly: AssemblyCompany("Microsoft Corp.")]
[assembly: AssemblyProduct("NamedAndOptionalSnippets")]
[assembly: AssemblyCopyright("Copyright © Microsoft Corp. 2009")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@ -21,7 +20,7 @@ using System.Security;
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("c62bbe65-1b38-4f56-95ca-adb8a0e1cd09")]
[assembly: Guid("6803107a-bd5f-4a70-834b-0988088f89bb")]
// Version information for an assembly consists of the following four values:
//
@ -35,10 +34,3 @@ using System.Security;
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
internal static class DesignTimeConstants {
internal const string Version = "10.0.0.0";
internal const string DesignerAssembly = "Microsoft.VisualStudio.Tools.Office.Designer, Version=" + Version + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
internal const string TypeCodeDomSerializer = "System.ComponentModel.Design.Serialization.TypeCodeDomSerializer, System.Design";
internal const string RibbonTypeSerializer = "Microsoft.VisualStudio.Tools.Office.Ribbon.Serialization.RibbonTypeCodeDomSerializer, " + DesignerAssembly;
}

Просмотреть файл

@ -0,0 +1,23 @@
{
"host": "visualstudio",
"expectederrors": [
{
"file": "docs/csharp/programming-guide/classes-and-structs/snippets/NamedAndOptional/Program.cs",
"line": 6,
"column": 25,
"error": "CS0234"
},
{
"file": "docs/csharp/programming-guide/classes-and-structs/snippets/NamedAndOptional/namedandoptcom.cs",
"line": 15,
"column": 42,
"error": "CS0234"
},
{
"file": "docs/csharp/programming-guide/classes-and-structs/snippets/NamedAndOptional/namedandoptcom.cs",
"line": 20,
"column": 17,
"error": "CS0234"
}
]
}

Просмотреть файл

@ -79,8 +79,6 @@ This section provides detailed information on key C# language features and featu
[File System and the Registry (C# Programming Guide)](./file-system/index.md)
[Interoperability](./interop/index.md)
[Reflection](./concepts/reflection.md)
## See also

Просмотреть файл

@ -1,41 +0,0 @@
---
title: "Example COM Class - C# Programming Guide"
description: Learn how to expose a class as a COM object in C#. This example adds code in a .cs files to a project and sets the Register for COM Interop property.
ms.date: 07/20/2015
ms.topic: how-to
helpviewer_keywords:
- "examples [C#], COM classes"
- "COM, exposing Visual C# objects to"
ms.assetid: 6504dea9-ad1c-4993-a794-830fec5270af
---
# Example COM Class (C# Programming Guide)
The following is an example of a class that you would expose as a COM object. After this code has been placed in a .cs file and added to your project, set the **Register for COM Interop** property to **True**. For more information, see [How to: Register a Component for COM Interop](/previous-versions/visualstudio/visual-studio-2010/w29wacsy(v=vs.100)).
Exposing Visual C# objects to COM requires declaring a class interface, an events interface if it is required, and the class itself. Class members must follow these rules to be visible to COM:
- The class must be public.
- Properties, methods, and events must be public.
- Properties and methods must be declared on the class interface.
- Events must be declared in the event interface.
Other public members in the class that are not declared in these interfaces will not be visible to COM, but they will be visible to other .NET objects.
To expose properties and methods to COM, you must declare them on the class interface and mark them with a `DispId` attribute, and implement them in the class. The order in which the members are declared in the interface is the order used for the COM vtable.
To expose events from your class, you must declare them on the events interface and mark them with a `DispId` attribute. The class should not implement this interface.
The class implements the class interface; it can implement more than one interface, but the first implementation will be the default class interface. Implement the methods and properties exposed to COM here. They must be marked public and must match the declarations in the class interface. Also, declare the events raised by the class here. They must be marked public and must match the declarations in the events interface.
## Example
[!code-csharp[csProgGuideInterop#8](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideInterop/CS/ExampleCOM.cs#8)]
## See also
- [C# Programming Guide](../index.md)
- [Interoperability](./index.md)
- [Build Page, Project Designer (C#)](/visualstudio/ide/reference/build-page-project-designer-csharp)

Просмотреть файл

@ -1,169 +0,0 @@
---
title: "How to access Office interop objects - C# Programming Guide"
description: Learn about C# features that simplify access to Office API objects. Use the new features to write code that creates and displays an Excel worksheet.
ms.topic: how-to
ms.date: 07/20/2015
helpviewer_keywords:
- "optional parameters [C#], Office programming"
- "named and optional arguments [C#], Office programming"
- "dynamic [C#], Office programming"
- "optional arguments [C#], Office programming"
- "named arguments [C#], Office programming"
- "Office programming [C#]"
ms.assetid: 041b25c2-3512-4e0f-a4ea-ceb2999e4d5e
---
# How to access Office interop objects (C# Programming Guide)
C# has features that simplify access to Office API objects. The new features include named and optional arguments, a new type called `dynamic`, and the ability to pass arguments to reference parameters in COM methods as if they were value parameters.
In this topic you will use the new features to write code that creates and displays a Microsoft Office Excel worksheet. You will then write code to add an Office Word document that contains an icon that is linked to the Excel worksheet.
To complete this walkthrough, you must have Microsoft Office Excel 2007 and Microsoft Office Word 2007, or later versions, installed on your computer.
[!INCLUDE[note_settings_general](~/includes/note-settings-general-md.md)]
## To create a new console application
1. Start Visual Studio.
2. On the **File** menu, point to **New**, and then click **Project**. The **New Project** dialog box appears.
3. In the **Installed Templates** pane, expand **Visual C#**, and then click **Windows**.
4. Look at the top of the **New Project** dialog box to make sure that **.NET Framework 4** (or later version) is selected as a target framework.
5. In the **Templates** pane, click **Console Application**.
6. Type a name for your project in the **Name** field.
7. Click **OK**.
The new project appears in **Solution Explorer**.
## To add references
1. In **Solution Explorer**, right-click your project's name and then click **Add Reference**. The **Add Reference** dialog box appears.
2. On the **Assemblies** page, select **Microsoft.Office.Interop.Word** in the **Component Name** list, and then hold down the CTRL key and select **Microsoft.Office.Interop.Excel**. If you do not see the assemblies, you may need to ensure they are installed and displayed. See [How to: Install Office Primary Interop Assemblies](/visualstudio/vsto/how-to-install-office-primary-interop-assemblies).
3. Click **OK**.
## To add necessary using directives
1. In **Solution Explorer**, right-click the *Program.cs* file and then click **View Code**.
2. Add the following `using` directives to the top of the code file:
[!code-csharp[csProgGuideOfficeHowTo#1](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideofficehowto/cs/program.cs#1)]
## To create a list of bank accounts
1. Paste the following class definition into **Program.cs**, under the `Program` class.
[!code-csharp[csProgGuideOfficeHowTo#2](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideofficehowto/cs/program.cs#2)]
2. Add the following code to the `Main` method to create a `bankAccounts` list that contains two accounts.
[!code-csharp[csProgGuideOfficeHowTo#3](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideofficehowto/cs/program.cs#3)]
## To declare a method that exports account information to Excel
1. Add the following method to the `Program` class to set up an Excel worksheet.
Method <xref:Microsoft.Office.Interop.Excel.Workbooks.Add%2A> has an optional parameter for specifying a particular template. Optional parameters enable you to omit the argument for that parameter if you want to use the parameter's default value. Because no argument is sent in the following code, `Add` uses the default template and creates a new workbook. The equivalent statement in earlier versions of C# requires a placeholder argument: `ExcelApp.Workbooks.Add(Type.Missing)`.
[!code-csharp[csProgGuideOfficeHowTo#4](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideofficehowto/cs/program.cs#4)]
2. Add the following code at the end of `DisplayInExcel`. The code inserts values into the first two columns of the first row of the worksheet.
[!code-csharp[csProgGuideOfficeHowTo#5](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideofficehowto/cs/program.cs#5)]
3. Add the following code at the end of `DisplayInExcel`. The `foreach` loop puts the information from the list of accounts into the first two columns of successive rows of the worksheet.
[!code-csharp[csProgGuideOfficeHowTo#7](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideofficehowto/cs/program.cs#7)]
4. Add the following code at the end of `DisplayInExcel` to adjust the column widths to fit the content.
[!code-csharp[csProgGuideOfficeHowTo#13](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideofficehowto/cs/program.cs#13)]
Earlier versions of C# require explicit casting for these operations because `ExcelApp.Columns[1]` returns an `Object`, and `AutoFit` is an Excel <xref:Microsoft.Office.Interop.Excel.Range> method. The following lines show the casting.
[!code-csharp[csProgGuideOfficeHowTo#14](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideofficehowto/cs/program.cs#14)]
C# converts the returned `Object` to `dynamic` automatically if the assembly is referenced by the [**EmbedInteropTypes**](../../language-reference/compiler-options/inputs.md#embedinteroptypes) compiler option or, equivalently, if the Excel **Embed Interop Types** property is set to true. True is the default value for this property.
## To run the project
1. Add the following line at the end of `Main`.
[!code-csharp[csProgGuideOfficeHowTo#8](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideofficehowto/cs/program.cs#8)]
2. Press CTRL+F5.
An Excel worksheet appears that contains the data from the two accounts.
## To add a Word document
1. To illustrate additional ways in which C# enhances Office programming, the following code opens a Word application and creates an icon that links to the Excel worksheet.
Paste method `CreateIconInWordDoc`, provided later in this step, into the `Program` class. `CreateIconInWordDoc` uses named and optional arguments to reduce the complexity of the method calls to <xref:Microsoft.Office.Interop.Word.Documents.Add%2A> and <xref:Microsoft.Office.Interop.Word.Selection.PasteSpecial%2A>. These calls incorporate two other features that simplify calls to COM methods that have reference parameters. First, you can send arguments to the reference parameters as if they were value parameters. That is, you can send values directly, without creating a variable for each reference parameter. The compiler generates temporary variables to hold the argument values, and discards the variables when you return from the call. Second, you can omit the `ref` keyword in the argument list.
The `Add` method has four reference parameters, all of which are optional. You can omit arguments for any or all of the parameters if you want to use their default values.
The `PasteSpecial` method inserts the contents of the Clipboard. The method has seven reference parameters, all of which are optional. The following code specifies arguments for two of them: `Link`, to create a link to the source of the Clipboard contents, and `DisplayAsIcon`, to display the link as an icon. You can use named arguments for those two and omit the others. Although these are reference parameters, you do not have to use the `ref` keyword, or to create variables to send in as arguments. You can send the values directly.
[!code-csharp[csProgGuideOfficeHowTo#9](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideofficehowto/cs/program.cs#9)]
2. Add the following statement at the end of `Main`.
[!code-csharp[csProgGuideOfficeHowTo#11](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideofficehowto/cs/program.cs#11)]
3. Add the following statement at the end of `DisplayInExcel`. The `Copy` method adds the worksheet to the Clipboard.
[!code-csharp[csProgGuideOfficeHowTo#12](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideofficehowto/cs/program.cs#12)]
4. Press CTRL+F5.
A Word document appears that contains an icon. Double-click the icon to bring the worksheet to the foreground.
## To set the Embed Interop Types property
1. Additional enhancements are possible when you call a COM type that does not require a primary interop assembly (PIA) at run time. Removing the dependency on PIAs results in version independence and easier deployment. For more information about the advantages of programming without PIAs, see [Walkthrough: Embedding Types from Managed Assemblies](../../../standard/assembly/embed-types-visual-studio.md).
In addition, programming is easier because the types that are required and returned by COM methods can be represented by using the type `dynamic` instead of `Object`. Variables that have type `dynamic` are not evaluated until run time, which eliminates the need for explicit casting. For more information, see [Using Type dynamic](../types/using-type-dynamic.md).
Embedding type information instead of using PIAs is default behavior. Because of that default, several of the previous examples are simplified because explicit casting is not required. For example, the declaration of `worksheet` in `DisplayInExcel` is written as `Excel._Worksheet workSheet = excelApp.ActiveSheet` rather than `Excel._Worksheet workSheet = (Excel.Worksheet)excelApp.ActiveSheet`. The calls to `AutoFit` in the same method also would require explicit casting without the default, because `ExcelApp.Columns[1]` returns an `Object`, and `AutoFit` is an Excel method. The following code shows the casting.
[!code-csharp[csProgGuideOfficeHowTo#14](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideofficehowto/cs/program.cs#14)]
2. To change the default and use PIAs instead of embedding type information, expand the **References** node in **Solution Explorer** and then select **Microsoft.Office.Interop.Excel** or **Microsoft.Office.Interop.Word**.
3. If you cannot see the **Properties** window, press **F4**.
4. Find **Embed Interop Types** in the list of properties, and change its value to **False**. Equivalently, you can compile by using the [**References**](../../language-reference/compiler-options/inputs.md#references) compiler option instead of [**EmbedInteropTypes**](../../language-reference/compiler-options/inputs.md#embedinteroptypes) at a command prompt.
## To add additional formatting to the table
1. Replace the two calls to `AutoFit` in `DisplayInExcel` with the following statement.
[!code-csharp[csProgGuideOfficeHowTo#15](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideofficehowto/cs/program.cs#15)]
The <xref:Microsoft.Office.Interop.Excel.Range.AutoFormat%2A> method has seven value parameters, all of which are optional. Named and optional arguments enable you to provide arguments for none, some, or all of them. In the previous statement, an argument is supplied for only one of the parameters, `Format`. Because `Format` is the first parameter in the parameter list, you do not have to provide the parameter name. However, the statement might be easier to understand if the parameter name is included, as is shown in the following code.
[!code-csharp[csProgGuideOfficeHowTo#16](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideofficehowto/cs/program.cs#16)]
2. Press CTRL+F5 to see the result. Other formats are listed in the <xref:Microsoft.Office.Interop.Excel.XlRangeAutoFormat> enumeration.
## Example
The following code shows the complete example.
[!code-csharp[csProgGuideOfficeHowTo#18](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideofficehowto/cs/walkthrough.cs#18)]
## See also
- <xref:System.Type.Missing?displayProperty=nameWithType>
- [dynamic](../../language-reference/builtin-types/reference-types.md)
- [Using Type dynamic](../types/using-type-dynamic.md)
- [Named and Optional Arguments](../classes-and-structs/named-and-optional-arguments.md)
- [How to use named and optional arguments in Office programming](../classes-and-structs/how-to-use-named-and-optional-arguments-in-office-programming.md)

Просмотреть файл

@ -1,45 +0,0 @@
---
title: "How to use indexed properties in COM interop programming - C# Programming Guide"
description: Learn how indexed properties improve the way in which COM properties that have parameters are consumed in this C# example.
ms.date: 07/20/2015
ms.topic: how-to
helpviewer_keywords:
- "indexed properties [C#]"
- "Office programming [C#], indexed properties"
- "properties [C#], indexed"
ms.assetid: 756bfc1e-7c28-4d4d-b114-ac9288c73882
---
# How to use indexed properties in COM interop programming (C# Programming Guide)
*Indexed properties* improve the way in which COM properties that have parameters are consumed in C# programming. Indexed properties work together with other features in Visual C#, such as [named and optional arguments](../classes-and-structs/named-and-optional-arguments.md), a new type ([dynamic](../../language-reference/builtin-types/reference-types.md)), and [embedded type information](../../../standard/assembly/embed-types-visual-studio.md), to enhance Microsoft Office programming.
In earlier versions of C#, methods are accessible as properties only if the `get` method has no parameters and the `set` method has one and only one value parameter. However, not all COM properties meet those restrictions. For example, the Excel <xref:Microsoft.Office.Interop.Excel.Range.Range%2A> property has a `get` accessor that requires a parameter for the name of the range. In the past, because you could not access the `Range` property directly, you had to use the `get_Range` method instead, as shown in the following example.
[!code-csharp[csProgGuideIndexedProperties#1](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideindexedproperties/cs/program.cs#1)]
Indexed properties enable you to write the following instead:
[!code-csharp[csProgGuideIndexedProperties#2](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideindexedproperties/cs/program.cs#2)]
The previous example also uses the [optional arguments](../classes-and-structs/named-and-optional-arguments.md) feature, which enables you to omit `Type.Missing`.
Indexed properties enable you to write the following code.
[!code-csharp[csProgGuideIndexedProperties#4](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideindexedproperties/cs/program.cs#4)]
You cannot create indexed properties of your own. The feature only supports consumption of existing indexed properties.
## Example
The following code shows a complete example. For more information about how to set up a project that accesses the Office API, see [How to access Office interop objects by using C# features](./how-to-access-office-onterop-objects.md).
[!code-csharp[csProgGuideIndexedProperties#5](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideindexedproperties/cs/program.cs#5)]
## See also
- [Named and Optional Arguments](../classes-and-structs/named-and-optional-arguments.md)
- [dynamic](../../language-reference/builtin-types/reference-types.md)
- [Using Type dynamic](../types/using-type-dynamic.md)
- [How to use named and optional arguments in Office programming](../classes-and-structs/how-to-use-named-and-optional-arguments-in-office-programming.md)
- [How to access Office interop objects by using C# features](./how-to-access-office-onterop-objects.md)
- [Walkthrough: Office Programming](./walkthrough-office-programming.md)

Просмотреть файл

@ -1,44 +0,0 @@
---
title: "How to use platform invoke to play a WAV file - C# Programming Guide"
description: This C# code example illustrates how to use platform invoke services to play a WAV sound file on the Windows operating system.
ms.topic: how-to
ms.date: 07/20/2015
helpviewer_keywords:
- "platform invoke, sound files"
- "interoperability [C#], playing WAV files using pinvoke"
- "wav files"
- ".wav files"
ms.assetid: f7f62f53-e026-4c40-b221-3a26adb0c2c5
---
# How to use platform invoke to play a WAV file (C# Programming Guide)
The following C# code example illustrates how to use platform invoke services to play a WAV sound file on the Windows operating system.
## Example
This example code uses <xref:System.Runtime.InteropServices.DllImportAttribute> to import `winmm.dll`'s `PlaySound` method entry point as `Form1 PlaySound()`. The example has a simple Windows Form with a button. Clicking the button opens a standard windows <xref:System.Windows.Forms.OpenFileDialog> dialog box so that you can open a file to play. When a wave file is selected, it is played by using the `PlaySound()` method of the *winmm.dll* library. For more information about this method, see [Using the PlaySound function with Waveform-Audio Files](/windows/desktop/multimedia/using-playsound-to-play-waveform-audio-files). Browse and select a file that has a .wav extension, and then click **Open** to play the wave file by using platform invoke. A text box shows the full path of the file selected.
The **Open Files** dialog box is filtered to show only files that have a .wav extension through the filter settings:
[!code-csharp[csProgGuideInterop#5](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideInterop/CS/WinSound.cs#5)]
[!code-csharp[csProgGuideInterop#3](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideInterop/CS/WinSound.cs#3)]
## Compiling the code
1. Create a new C# Windows Forms Application project in Visual Studio and name it **WinSound**.
2. Copy the code above, and paste it over the contents of the *Form1.cs* file.
3. Copy the following code, and paste it in the *Form1.Designer.cs* file, in the `InitializeComponent()` method, after any existing code.
[!code-csharp[csProgGuideInterop#4](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideInterop/CS/WinSound.cs#4)]
4. Compile and run the code.
## See also
- [C# Programming Guide](../index.md)
- [Interoperability Overview](interoperability-overview.md)
- [A Closer Look at Platform Invoke](../../../framework/interop/consuming-unmanaged-dll-functions.md#a-closer-look-at-platform-invoke)
- [Marshalling Data with Platform Invoke](../../../framework/interop/marshalling-data-with-platform-invoke.md)

Просмотреть файл

@ -1,47 +0,0 @@
---
title: "Interoperability - C# Programming Guide"
description: Interoperability supports unmanaged code beside the code that runs under the common language runtime. Use these resources to understand interop options.
ms.date: 07/20/2015
helpviewer_keywords:
- "COM interop"
- "interoperability"
- "platform invoke, accessing APIs with C#"
- "C# language, interoperability"
ms.assetid: 238bb95a-e962-4026-bbd5-197055bdb8ee
---
# Interoperability (C# Programming Guide)
Interoperability enables you to preserve and take advantage of existing investments in unmanaged code. Code that runs under the control of the common language runtime (CLR) is called *managed code*, and code that runs outside the CLR is called *unmanaged code*. COM, COM+, C++ components, ActiveX components, and Microsoft Windows API are examples of unmanaged code.
.NET enables interoperability with unmanaged code through platform invoke services, the <xref:System.Runtime.InteropServices> namespace, C++ interoperability, and COM interoperability (COM interop).
## In This Section
[Interoperability Overview](./interoperability-overview.md)
Describes methods to interoperate between C# managed code and unmanaged code.
[How to access Office interop objects by using C# features](./how-to-access-office-onterop-objects.md)
Describes features that are introduced in Visual C# to facilitate Office programming.
[How to use indexed properties in COM interop programming](./how-to-use-indexed-properties-in-com-interop-rogramming.md)
Describes how to use indexed properties to access COM properties that have parameters.
[How to use platform invoke to play a WAV file](./how-to-use-platform-invoke-to-play-a-wave-file.md)
Describes how to use platform invoke services to play a .wav sound file on the Windows operating system.
[Walkthrough: Office Programming](./walkthrough-office-programming.md)
Shows how to create an Excel workbook and a Word document that contains a link to the workbook.
[Example COM Class](./example-com-class.md)
Demonstrates how to expose a C# class as a COM object.
## C# Language Specification
For more information, see [Unsafe code](~/_csharpstandard/standard/unsafe-code.md) in the [C# Language Specification](~/_csharpstandard/standard/README.md). The language specification is the definitive source for C# syntax and usage.
## See also
- <xref:System.Runtime.InteropServices.Marshal.ReleaseComObject%2A?displayProperty=nameWithType>
- [C# Programming Guide](../index.md)
- [Interoperating with Unmanaged Code](../../../framework/interop/index.md)
- [Walkthrough: Office Programming](./walkthrough-office-programming.md)

Просмотреть файл

@ -1,67 +0,0 @@
---
title: "Interoperability Overview - C# Programming Guide"
description: Learn about interoperability between C# and unmanaged code, including platform invoke, C++ interop, exposing COM components to C#, and exposing C# to COM.
ms.date: 07/20/2015
helpviewer_keywords:
- "COM interop"
- "C# language, interoperability"
- "C++ Interop"
- "interoperability, about interoperability"
- "platform invoke"
ms.assetid: c025b2e0-2357-4c27-8461-118f0090aeff
---
# Interoperability Overview (C# Programming Guide)
The topic describes methods to enable interoperability between C# managed code and unmanaged code.
## Platform Invoke
*Platform invoke* is a service that enables managed code to call unmanaged functions that are implemented in dynamic link libraries (DLLs), such as those in the Microsoft Windows API. It locates and invokes an exported function and marshals its arguments (integers, strings, arrays, structures, and so on) across the interoperation boundary as needed.
For more information, see [Consuming Unmanaged DLL Functions](../../../framework/interop/consuming-unmanaged-dll-functions.md) and [How to use platform invoke to play a WAV file](./how-to-use-platform-invoke-to-play-a-wave-file.md).
> [!NOTE]
> The [Common Language Runtime](../../../standard/clr.md) (CLR) manages access to system resources. Calling unmanaged code that is outside the CLR bypasses this security mechanism, and therefore presents a security risk. For example, unmanaged code might call resources in unmanaged code directly, bypassing CLR security mechanisms. For more information, see [Security in .NET](../../../standard/security/index.md).
## C++ Interop
You can use C++ interop, also known as It Just Works (IJW), to wrap a native C++ class so that it can be consumed by code that is authored in C# or another .NET language. To do this, you write C++ code to wrap a native DLL or COM component. Unlike other .NET languages, Visual C++ has interoperability support that enables managed and unmanaged code to be located in the same application and even in the same file. You then build the C++ code by using the **/clr** compiler switch to produce a managed assembly. Finally, you add a reference to the assembly in your C# project and use the wrapped objects just as you would use other managed classes.
## Exposing COM Components to C\#
You can consume a COM component from a C# project. The general steps are as follows:
1. Locate a COM component to use and register it. Use regsvr32.exe to register or un–register a COM DLL.
2. Add to the project a reference to the COM component or type library.
When you add the reference, Visual Studio uses the [Tlbimp.exe (Type Library Importer)](../../../framework/tools/tlbimp-exe-type-library-importer.md), which takes a type library as input, to output a .NET interop assembly. The assembly, also named a runtime callable wrapper (RCW), contains managed classes and interfaces that wrap the COM classes and interfaces that are in the type library. Visual Studio adds to the project a reference to the generated assembly.
3. Create an instance of a class that is defined in the RCW. This, in turn, creates an instance of the COM object.
4. Use the object just as you use other managed objects. When the object is reclaimed by garbage collection, the instance of the COM object is also released from memory.
For more information, see [Exposing COM Components to the .NET Framework](../../../framework/interop/exposing-com-components.md).
## Exposing C# to COM
COM clients can consume C# types that have been correctly exposed. The basic steps to expose C# types are as follows:
1. Add interop attributes in the C# project.
You can make an assembly COM visible by modifying Visual C# project properties. For more information, see [Assembly Information Dialog Box](/visualstudio/ide/reference/assembly-information-dialog-box).
2. Generate a COM type library and register it for COM usage.
You can modify Visual C# project properties to automatically register the C# assembly for COM interop. Visual Studio uses the [Regasm.exe (Assembly Registration Tool)](../../../framework/tools/regasm-exe-assembly-registration-tool.md), using the `/tlb` command-line switch, which takes a managed assembly as input, to generate a type library. This type library describes the `public` types in the assembly and adds registry entries so that COM clients can create managed classes.
For more information, see [Exposing .NET Framework Components to COM](../../../framework/interop/exposing-dotnet-components-to-com.md) and [Example COM Class](./example-com-class.md).
## See also
- [Improving Interop Performance](/previous-versions/msp-n-p/ff647812(v=pandp.10))
- [Introduction to Interoperability between COM and .NET](/office/client-developer/outlook/pia/introduction-to-interoperability-between-com-and-net)
- [Introduction to COM Interop in Visual Basic](../../../visual-basic/programming-guide/com-interop/introduction-to-com-interop.md)
- [Marshalling between Managed and Unmanaged Code](../../../framework/interop/interop-marshalling.md)
- [Interoperating with Unmanaged Code](../../../framework/interop/index.md)
- [C# Programming Guide](../index.md)

Просмотреть файл

@ -1,74 +0,0 @@
---
title: "Using type dynamic - C# Programming Guide"
description: Learn how to use the dynamic type. The dynamic type is a static type, but dynamic objects bypass static type checking.
ms.date: 07/20/2015
helpviewer_keywords:
- "dynamic [C#], about dynamic type"
- "dynamic type [C#]"
ms.assetid: 3828989d-c967-4a51-b948-857ebc8fdf26
---
# Using type dynamic (C# Programming Guide)
The `dynamic` type is a static type, but an object of type `dynamic` bypasses static type checking. In most cases, it functions like it has type `object`. At compile time, an element that is typed as `dynamic` is assumed to support any operation. Therefore, you do not have to be concerned about whether the object gets its value from a COM API, from a dynamic language such as IronPython, from the HTML Document Object Model (DOM), from reflection, or from somewhere else in the program. However, if the code is not valid, errors are caught at run time.
For example, if instance method `exampleMethod1` in the following code has only one parameter, the compiler recognizes that the first call to the method, `ec.exampleMethod1(10, 4)`, is not valid because it contains two arguments. The call causes a compiler error. The second call to the method, `dynamic_ec.exampleMethod1(10, 4)`, is not checked by the compiler because the type of `dynamic_ec` is `dynamic`. Therefore, no compiler error is reported. However, the error does not escape notice indefinitely. It is caught at run time and causes a run-time exception.
[!code-csharp[CsProgGuideTypes#50](~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsProgGuideTypes/CS/usingdynamic.cs#50)]
[!code-csharp[CsProgGuideTypes#56](~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsProgGuideTypes/CS/usingdynamic.cs#56)]
The role of the compiler in these examples is to package together information about what each statement is proposing to do to the object or expression that is typed as `dynamic`. At run time, the stored information is examined, and any statement that is not valid causes a run-time exception.
The result of most dynamic operations is itself `dynamic`. For example, if you rest the mouse pointer over the use of `testSum` in the following example, IntelliSense displays the type **(local variable) dynamic testSum**.
[!code-csharp[CsProgGuideTypes#51](~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsProgGuideTypes/CS/usingdynamic.cs#51)]
Operations in which the result is not `dynamic` include:
* Conversions from `dynamic` to another type.
* Constructor calls that include arguments of type `dynamic`.
For example, the type of `testInstance` in the following declaration is `ExampleClass`, not `dynamic`:
[!code-csharp[CsProgGuideTypes#52](~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsProgGuideTypes/CS/usingdynamic.cs#52)]
Conversion examples are shown in the following section, "Conversions."
## Conversions
Conversions between dynamic objects and other types are easy. This enables the developer to switch between dynamic and non-dynamic behavior.
Any object can be converted to dynamic type implicitly, as shown in the following examples.
[!code-csharp[CsProgGuideTypes#53](~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsProgGuideTypes/CS/usingdynamic.cs#53)]
Conversely, an implicit conversion can be dynamically applied to any expression of type `dynamic`.
[!code-csharp[CsProgGuideTypes#54](~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsProgGuideTypes/CS/usingdynamic.cs#54)]
## Overload resolution with arguments of type dynamic
Overload resolution occurs at run time instead of at compile time if one or more of the arguments in a method call have the type `dynamic`, or if the receiver of the method call is of type `dynamic`. In the following example, if the only accessible `exampleMethod2` method is defined to take a string argument, sending `d1` as the argument does not cause a compiler error, but it does cause a run-time exception. Overload resolution fails at run time because the run-time type of `d1` is `int`, and `exampleMethod2` requires a string.
[!code-csharp[CsProgGuideTypes#55](~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsProgGuideTypes/CS/usingdynamic.cs#55)]
## Dynamic language runtime
The dynamic language runtime (DLR) is an API that was introduced in .NET Framework 4. It provides the infrastructure that supports the `dynamic` type in C#, and also the implementation of dynamic programming languages such as IronPython and IronRuby. For more information about the DLR, see [Dynamic Language Runtime Overview](../../../framework/reflection-and-codedom/dynamic-language-runtime-overview.md).
## COM interop
Many COM methods allow for variation in argument types and return type by designating the types as `object`. This has necessitated explicit casting of the values to coordinate with strongly typed variables in C#. If you compile by using the [**EmbedInteropTypes** (C# Compiler Options)](../../language-reference/compiler-options/inputs.md#embedinteroptypes) option, the introduction of the `dynamic` type enables you to treat the occurrences of `object` in COM signatures as if they were of type `dynamic`, and thereby to avoid much of the casting. For example, the following statements contrast how you access a cell in a Microsoft Office Excel spreadsheet with the `dynamic` type and without the `dynamic` type.
[!code-csharp[csOfficeWalkthrough#12](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csofficewalkthrough/cs/thisaddin.cs#12)]
[!code-csharp[csOfficeWalkthrough#13](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csofficewalkthrough/cs/thisaddin.cs#13)]
## Related topics
|Title|Description|
|-----------|-----------------|
|[dynamic](../../language-reference/builtin-types/reference-types.md)|Describes the usage of the `dynamic` keyword.|
|[Dynamic Language Runtime Overview](../../../framework/reflection-and-codedom/dynamic-language-runtime-overview.md)|Provides an overview of the DLR, which is a runtime environment that adds a set of services for dynamic languages to the common language runtime (CLR).|
|[Walkthrough: Creating and Using Dynamic Objects](walkthrough-creating-and-using-dynamic-objects.md)|Provides step-by-step instructions for creating a custom dynamic object and for creating a project that accesses an `IronPython` library.|
|[How to access Office interop objects by using C# features](../interop/how-to-access-office-onterop-objects.md)|Demonstrates how to create a project that uses named and optional arguments, the `dynamic` type, and other enhancements that simplify access to Office API objects.|

Просмотреть файл

@ -317,8 +317,6 @@ items:
href: expression-trees-translating.md
- name: Summary
href: expression-trees-summary.md
- name: Native interoperability
href: programming-guide/interop/index.md
- name: Versioning
href: versioning.md
- name: How-to C# articles
@ -340,6 +338,26 @@ items:
href: how-to/how-to-catch-a-non-cls-exception.md
- name: Advanced topics
items:
- name: Native interoperability
items:
- name: Overview
href: advanced-topics/interop/index.md
- name: Example COM Class
href: advanced-topics/interop/example-com-class.md
- name: "Walkthrough: Office Programming"
href: advanced-topics/interop/walkthrough-office-programming.md
- name: "How to use platform invoke to play a WAV file"
href: advanced-topics/interop/how-to-use-platform-invoke-to-play-a-wave-file.md
- name: "How to use indexed properties in COM interop programming"
href: advanced-topics/interop/how-to-use-indexed-properties-in-com-interop-programming.md
- name: "How to access Office interop objects"
href: advanced-topics/interop/how-to-access-office-interop-objects.md
- name: "How to use named and optional arguments in Office programming"
href: advanced-topics/interop/how-to-use-named-and-optional-arguments-in-office-programming.md
- name: Using Type dynamic
href: advanced-topics/interop/using-type-dynamic.md
- name: "Walkthrough: Creating and Using Dynamic Objects"
href: advanced-topics/interop/walkthrough-creating-and-using-dynamic-objects.md
- name: Performance engineering
items:
- name: Overview
@ -614,10 +632,6 @@ items:
href: programming-guide/types/how-to-convert-a-string-to-a-number.md
- name: "How to convert between hexadecimal strings and numeric types"
href: programming-guide/types/how-to-convert-between-hexadecimal-strings-and-numeric-types.md
- name: Using Type dynamic
href: programming-guide/types/using-type-dynamic.md
- name: "Walkthrough: Creating and Using Dynamic Objects (C# and Visual Basic)"
href: programming-guide/types/walkthrough-creating-and-using-dynamic-objects.md
- name: Classes, Structs, and Records
items:
- name: Polymorphism
@ -680,8 +694,6 @@ items:
href: programming-guide/classes-and-structs/how-to-create-a-new-method-for-an-enumeration.md
- name: Named and Optional Arguments
href: programming-guide/classes-and-structs/named-and-optional-arguments.md
- name: "How to use named and optional arguments in Office programming"
href: programming-guide/classes-and-structs/how-to-use-named-and-optional-arguments-in-office-programming.md
- name: Constructors
items:
- name: Constructors overview
@ -827,22 +839,6 @@ items:
href: programming-guide/file-system/how-to-read-a-text-file-one-line-at-a-time.md
- name: "How to create a key in the registry"
href: programming-guide/file-system/how-to-create-a-key-in-the-registry.md
- name: Interoperability
items:
- name: .NET Interoperability
href: programming-guide/interop/index.md
- name: Interoperability Overview
href: programming-guide/interop/interoperability-overview.md
- name: "How to access Office interop objects by using C# features"
href: programming-guide/interop/how-to-access-office-onterop-objects.md
- name: "How to use indexed properties in COM interop programming"
href: programming-guide/interop/how-to-use-indexed-properties-in-com-interop-rogramming.md
- name: "How to use platform invoke to play a WAV file"
href: programming-guide/interop/how-to-use-platform-invoke-to-play-a-wave-file.md
- name: "Walkthrough: Office Programming (C# and Visual Basic)"
href: programming-guide/interop/walkthrough-office-programming.md
- name: Example COM Class
href: programming-guide/interop/example-com-class.md
- name: Language reference
items:
- name: Overview

Просмотреть файл

@ -100,4 +100,4 @@ The DLR uses binders in call sites to communicate not only with the .NET Framewo
- [Common Language Runtime](../../standard/clr.md)
- [Expression Trees (C#)](../../csharp/programming-guide/concepts/expression-trees/index.md)
- [Expression Trees (Visual Basic)](../../visual-basic/programming-guide/concepts/expression-trees/index.md)
- [Walkthrough: Creating and Using Dynamic Objects](../../csharp/programming-guide/types/walkthrough-creating-and-using-dynamic-objects.md)
- [Walkthrough: Creating and Using Dynamic Objects](../../csharp/advanced-topics/interop/walkthrough-creating-and-using-dynamic-objects.md)

Просмотреть файл

@ -1,22 +1,16 @@
---
title: "Walkthrough: Office Programming (C# and Visual Basic)"
description: Learn about the features Visual Studio offers in C# and Visual Basic that improve Microsoft Office programming.
ms.date: 07/20/2015
title: "Walkthrough: Office Programming - Visual Basic"
description: Learn about the features Visual Studio offers in Visual Basic that improve Microsoft Office programming.
ms.date: 02/15/2023
ms.topic: tutorial
dev_langs:
- "csharp"
- "vb"
helpviewer_keywords:
- "Office, programming in Visual Basic and C#"
- "Office programming [C#]"
- "Office programming [Visual Basic]"
ms.assetid: 519cff31-f80b-4f0e-a56b-26358d0f8c51
---
# Walkthrough: Office Programming (C# and Visual Basic)
# Walkthrough: Office Programming in Visual Basic
Visual Studio offers features in C# and Visual Basic that improve Microsoft Office programming. Helpful C# features include named and optional arguments and return values of type `dynamic`. In COM programming, you can omit the `ref` keyword and gain access to indexed properties. Features in Visual Basic include auto-implemented properties, statements in lambda expressions, and collection initializers.
Both languages enable embedding of type information, which allows deployment of assemblies that interact with COM components without deploying primary interop assemblies (PIAs) to the user's computer. For more information, see [Walkthrough: Embedding Types from Managed Assemblies](../../../standard/assembly/embed-types-visual-studio.md).
Visual Studio offers features in Visual Basic that improve Microsoft Office programming. Features in Visual Basic include auto-implemented properties, statements in lambda expressions, and collection initializers. You can embed type information, which allows deployment of assemblies that interact with COM components without deploying primary interop assemblies (PIAs) to the user's computer. For more information, see [Walkthrough: Embedding Types from Managed Assemblies](../../../standard/assembly/embed-types-visual-studio.md).
This walkthrough demonstrates these features in the context of Office programming, but many of these features are also useful in general programming. In the walkthrough, you use an Excel Add-in application to create an Excel workbook. Next, you create a Word document that contains a link to the workbook. Finally, you see how to enable and disable the PIA dependency.
@ -26,13 +20,13 @@ You must have Microsoft Office Excel and Microsoft Office Word installed on your
[!INCLUDE[note_settings_general](~/includes/note-settings-general-md.md)]
### To set up an Excel Add-in application
## Set up an Excel Add-in application
1. Start Visual Studio.
2. On the **File** menu, point to **New**, and then click **Project**.
3. In the **Installed Templates** pane, expand **Visual Basic** or **Visual C#**, expand **Office**, and then click the version year of the Office product.
3. In the **Installed Templates** pane, expand **Visual Basic**, expand **Office**, and then click the version year of the Office product.
4. In the **Templates** pane, click **Excel \<version> Add-in**.
@ -44,7 +38,7 @@ You must have Microsoft Office Excel and Microsoft Office Word installed on your
8. The new project appears in **Solution Explorer**.
### To add references
## Add references
1. In **Solution Explorer**, right-click your project's name and then click **Add Reference**. The **Add Reference** dialog box appears.
@ -52,101 +46,67 @@ You must have Microsoft Office Excel and Microsoft Office Word installed on your
3. Click **OK**.
### To add necessary Imports statements or using directives
## Add necessary Imports statements or using directives
1. In **Solution Explorer**, right-click the **ThisAddIn.vb** or **ThisAddIn.cs** file and then click **View Code**.
2. Add the following `Imports` statements (Visual Basic) or `using` directives (C#) to the top of the code file if they are not already present.
[!code-csharp[csOfficeWalkthrough#1](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csofficewalkthrough/cs/thisaddin.cs#1)]
2. Add the following `Imports` statements to the top of the code file if they are not already present.
[!code-vb[csOfficeWalkthrough#1](~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/csofficewalkthrough/vb/thisaddin.vb#1)]
### To create a list of bank accounts
## Create a list of bank accounts
1. In **Solution Explorer**, right-click your project's name, click **Add**, and then click **Class**. Name the class Account.vb if you are using Visual Basic or Account.cs if you are using C#. Click **Add**.
1. In **Solution Explorer**, right-click your project's name, click **Add**, and then click **Class**. Name the class Account.vb. Click **Add**.
2. Replace the definition of the `Account` class with the following code. The class definitions use *auto-implemented properties*. For more information, see [Auto-Implemented Properties](../../../visual-basic/programming-guide/language-features/procedures/auto-implemented-properties.md).
[!code-csharp[csOfficeWalkthrough#2](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csofficewalkthrough/cs/account.cs#2)]
[!code-vb[csOfficeWalkthrough#2](~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/csofficewalkthrough/vb/account.vb#2)]
3. To create a `bankAccounts` list that contains two accounts, add the following code to the `ThisAddIn_Startup` method in *ThisAddIn.vb* or *ThisAddIn.cs*. The list declarations use *collection initializers*. For more information, see [Collection Initializers](../../../visual-basic/programming-guide/language-features/collection-initializers/index.md).
[!code-csharp[csOfficeWalkthrough#3](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csofficewalkthrough/cs/thisaddin.cs#3)]
3. To create a `bankAccounts` list that contains two accounts, add the following code to the `ThisAddIn_Startup` method in *ThisAddIn.vb*. The list declarations use *collection initializers*. For more information, see [Collection Initializers](../../../visual-basic/programming-guide/language-features/collection-initializers/index.md).
[!code-vb[csOfficeWalkthrough#3](~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/csofficewalkthrough/vb/thisaddin.vb#3)]
### To export data to Excel
## Export data to Excel
1. In the same file, add the following method to the `ThisAddIn` class. The method sets up an Excel workbook and exports data to it.
[!code-csharp[csOfficeWalkthrough#4](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csofficewalkthrough/cs/thisaddin.cs#4)]
[!code-vb[csOfficeWalkthrough#4](~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/csofficewalkthrough/vb/thisaddin.vb#4)]
Two new C# features are used in this method. Both of these features already exist in Visual Basic.
- Method [Add](<xref:Microsoft.Office.Interop.Excel.Workbooks.Add%2A>) has an *optional parameter* for specifying a particular template. Optional parameters enable you to omit the argument for that parameter if you want to use the parameter's default value. Because no argument is sent in the previous example, `Add` uses the default template and creates a new workbook.
- Method [Add](<xref:Microsoft.Office.Interop.Excel.Workbooks.Add%2A>) has an *optional parameter* for specifying a particular template. Optional parameters enable you to omit the argument for that parameter if you want to use the parameter's default value. Because no argument is sent in the previous example, `Add` uses the default template and creates a new workbook. The equivalent statement in earlier versions of C# requires a placeholder argument: `excelApp.Workbooks.Add(Type.Missing)`.
For more information, see [Named and Optional Arguments](../classes-and-structs/named-and-optional-arguments.md).
- The `Range` and `Offset` properties of the [Range](<xref:Microsoft.Office.Interop.Excel.Range>) object use the *indexed properties* feature. This feature enables you to consume these properties from COM types by using the following typical C# syntax. Indexed properties also enable you to use the `Value` property of the `Range` object, eliminating the need to use the `Value2` property. The `Value` property is indexed, but the index is optional. Optional arguments and indexed properties work together in the following example.
[!code-csharp[csOfficeWalkthrough#5](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csofficewalkthrough/cs/thisaddin.cs#5)]
In earlier versions of the language, the following special syntax is required.
[!code-csharp[csOfficeWalkthrough#6](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csofficewalkthrough/cs/thisaddin.cs#6)]
You cannot create indexed properties of your own. The feature only supports consumption of existing indexed properties.
For more information, see [How to use indexed properties in COM interop programming](./how-to-use-indexed-properties-in-com-interop-rogramming.md).
- The `Range` and `Offset` properties of the [Range](<xref:Microsoft.Office.Interop.Excel.Range>) object use the *indexed properties* feature. Indexed properties also enable you to use the `Value` property of the `Range` object, eliminating the need to use the `Value2` property. The `Value` property is indexed, but the index is optional. Optional arguments and indexed properties work together in the following example.
2. Add the following code at the end of `DisplayInExcel` to adjust the column widths to fit the content.
[!code-csharp[csOfficeWalkthrough#7](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csofficewalkthrough/cs/thisaddin.cs#7)]
[!code-vb[csOfficeWalkthrough#7](~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/csofficewalkthrough/vb/thisaddin.vb#7)]
These additions demonstrate another feature in C#: treating `Object` values returned from COM hosts such as Office as if they have type [dynamic](../../language-reference/builtin-types/reference-types.md). This happens automatically when **Embed Interop Types** is set to its default value, `True`, or, equivalently, when the assembly is referenced by the [**EmbedInteropTypes**](../../language-reference/compiler-options/inputs.md#embedinteroptypes) compiler option.
For more information about embedding interop types, see procedures "To find the PIA reference" and "To restore the PIA dependency" later in this article.
For example, `excelApp.Columns[1]` returns an `Object`, and `AutoFit` is an Excel [Range](<xref:Microsoft.Office.Interop.Excel.Range>) method. Without `dynamic`, you must cast the object returned by `excelApp.Columns[1]` as an instance of `Range` before calling method `AutoFit`.
## Invoke DisplayInExcel
[!code-csharp[csOfficeWalkthrough#8](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csofficewalkthrough/cs/thisaddin.cs#8)]
For more information about embedding interop types, see procedures "To find the PIA reference" and "To restore the PIA dependency" later in this topic. For more information about `dynamic`, see [dynamic](../../language-reference/builtin-types/reference-types.md) or [Using Type dynamic](../types/using-type-dynamic.md).
### To invoke DisplayInExcel
1. Add the following code at the end of the `ThisAddIn_StartUp` method. The call to `DisplayInExcel` contains two arguments. The first argument is the name of the list of accounts to be processed. The second argument is a multiline lambda expression that defines how the data is to be processed. The `ID` and `balance` values for each account are displayed in adjacent cells, and the row is displayed in red if the balance is less than zero. For more information, see [Lambda Expressions](../../language-reference/operators/lambda-expressions.md).
[!code-csharp[csOfficeWalkthrough#9](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csofficewalkthrough/cs/thisaddin.cs#9)]
1. Add the following code at the end of the `ThisAddIn_StartUp` method. The call to `DisplayInExcel` contains two arguments. The first argument is the name of the list of accounts to be processed. The second argument is a multiline lambda expression that defines how the data is to be processed. The `ID` and `balance` values for each account are displayed in adjacent cells, and the row is displayed in red if the balance is less than zero.
[!code-vb[csOfficeWalkthrough#9](~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/csofficewalkthrough/vb/thisaddin.vb#9)]
2. To run the program, press F5. An Excel worksheet appears that contains the data from the accounts.
### To add a Word document
## Add a Word document
1. Add the following code at the end of the `ThisAddIn_StartUp` method to create a Word document that contains a link to the Excel workbook.
[!code-csharp[csOfficeWalkthrough#10](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csofficewalkthrough/cs/thisaddin.cs#10)]
[!code-vb[csOfficeWalkthrough#10](~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/csofficewalkthrough/vb/thisaddin.vb#10)]
This code demonstrates several of the new features in C#: the ability to omit the `ref` keyword in COM programming, named arguments, and optional arguments. These features already exist in Visual Basic. The [PasteSpecial](<xref:Microsoft.Office.Interop.Word.Selection.PasteSpecial%2A>) method has seven parameters, all of which are defined as optional reference parameters. Named and optional arguments enable you to designate the parameters you want to access by name and to send arguments to only those parameters. In this example, arguments are sent to indicate that a link to the workbook on the Clipboard should be created (parameter `Link`) and that the link is to be displayed in the Word document as an icon (parameter `DisplayAsIcon`). Visual C# also enables you to omit the `ref` keyword for these arguments.
The [PasteSpecial](<xref:Microsoft.Office.Interop.Word.Selection.PasteSpecial%2A>) method has seven parameters, all of which are defined as optional reference parameters. Named and optional arguments enable you to designate the parameters you want to access by name and to send arguments to only those parameters. In this example, arguments are sent to indicate that a link to the workbook on the Clipboard should be created (parameter `Link`) and that the link is to be displayed in the Word document as an icon (parameter `DisplayAsIcon`).
### To run the application
## Run the application
1. Press F5 to run the application. Excel starts and displays a table that contains the information from the two accounts in `bankAccounts`. Then a Word document appears that contains a link to the Excel table.
### To clean up the completed project
## Clean up the completed project
1. In Visual Studio, click **Clean Solution** on the **Build** menu. Otherwise, the add-in will run every time that you open Excel on your computer.
### To find the PIA reference
## Find the PIA reference
1. Run the application again, but do not click **Clean Solution**.
@ -167,41 +127,24 @@ You must have Microsoft Office Excel and Microsoft Office Word installed on your
6. Close the manifest window and the assembly window.
### To restore the PIA dependency
## Restore the PIA dependency
1. In **Solution Explorer**, click the **Show All Files** button. Expand the **References** folder and select **Microsoft.Office.Interop.Excel**. Press F4 to display the **Properties** window.
2. In the **Properties** window, change the **Embed Interop Types** property from **True** to **False**.
3. Repeat steps 1 and 2 in this procedure for `Microsoft.Office.Interop.Word`.
4. In C#, comment out the two calls to `Autofit` at the end of the `DisplayInExcel` method.
5. Press F5 to verify that the project still runs correctly.
6. Repeat steps 1-3 from the previous procedure to open the assembly window. Notice that `Microsoft.Office.Interop.Word` and `Microsoft.Office.Interop.Excel` are no longer in the list of embedded assemblies.
7. Double-click the **MANIFEST** icon and scroll through the list of referenced assemblies. Both `Microsoft.Office.Interop.Word` and `Microsoft.Office.Interop.Excel` are in the list. Because the application references the Excel and Word PIAs, and the **Embed Interop Types** property is set to **False**, both assemblies must exist on the end user's computer.
8. In Visual Studio, click **Clean Solution** on the **Build** menu to clean up the completed project.
1. In the **Properties** window, change the **Embed Interop Types** property from **True** to **False**.
1. Repeat steps 1 and 2 in this procedure for `Microsoft.Office.Interop.Word`.
1. Press F5 to verify that the project still runs correctly.
1. Repeat steps 1-3 from the previous procedure to open the assembly window. Notice that `Microsoft.Office.Interop.Word` and `Microsoft.Office.Interop.Excel` are no longer in the list of embedded assemblies.
1. Double-click the **MANIFEST** icon and scroll through the list of referenced assemblies. Both `Microsoft.Office.Interop.Word` and `Microsoft.Office.Interop.Excel` are in the list. Because the application references the Excel and Word PIAs, and the **Embed Interop Types** property is set to **False**, both assemblies must exist on the end user's computer.
1. In Visual Studio, click **Clean Solution** on the **Build** menu to clean up the completed project.
## See also
- [Auto-Implemented Properties (Visual Basic)](../../../visual-basic/programming-guide/language-features/procedures/auto-implemented-properties.md)
- [Auto-Implemented Properties (C#)](../classes-and-structs/auto-implemented-properties.md)
- [Collection Initializers](../../../visual-basic/programming-guide/language-features/collection-initializers/index.md)
- [Object and Collection Initializers](../classes-and-structs/object-and-collection-initializers.md)
- [Optional Parameters](../../../visual-basic/programming-guide/language-features/procedures/optional-parameters.md)
- [Passing Arguments by Position and by Name](../../../visual-basic/programming-guide/language-features/procedures/passing-arguments-by-position-and-by-name.md)
- [Named and Optional Arguments](../classes-and-structs/named-and-optional-arguments.md)
- [Early and Late Binding](../../../visual-basic/programming-guide/language-features/early-late-binding/index.md)
- [dynamic](../../language-reference/builtin-types/reference-types.md)
- [Using Type dynamic](../types/using-type-dynamic.md)
- [Lambda Expressions (Visual Basic)](../../../visual-basic/programming-guide/language-features/procedures/lambda-expressions.md)
- [Lambda Expressions (C#)](../../language-reference/operators/lambda-expressions.md)
- [How to use indexed properties in COM interop programming](./how-to-use-indexed-properties-in-com-interop-rogramming.md)
- [Walkthrough: Embedding Type Information from Microsoft Office Assemblies in Visual Studio](/previous-versions/visualstudio/visual-studio-2013/ee317478(v=vs.120))
- [Auto-Implemented Properties (Visual Basic)](../language-features/procedures/auto-implemented-properties.md)
- [Collection Initializers](../language-features/collection-initializers/index.md)
- [Optional Parameters](../language-features/procedures/optional-parameters.md)
- [Passing Arguments by Position and by Name](../language-features/procedures/passing-arguments-by-position-and-by-name.md)
- [Early and Late Binding](../language-features/early-late-binding/index.md)
- [Lambda Expressions](..//language-features/procedures/lambda-expressions.md)
- [Walkthrough: Embedding Types from Managed Assemblies](../../../standard/assembly/embed-types-visual-studio.md)
- [Walkthrough: Creating Your First VSTO Add-in for Excel](/visualstudio/vsto/walkthrough-creating-your-first-vsto-add-in-for-excel)
- [COM Interop](../../../visual-basic/programming-guide/com-interop/index.md)
- [Interoperability](./index.md)
- [COM Interop](index.md)

Просмотреть файл

@ -7,3 +7,5 @@
href: calling-a-property-or-method-using-a-string-name.md
- name: Working with Dynamic Objects
href: working-with-dynamic-objects.md
- name: "Walkthrough: create and use dynamic objects"
href: walkthrough-creating-and-using-dynamic-objects.md

Просмотреть файл

@ -1,22 +1,20 @@
---
title: "Walkthrough: Creating and Using Dynamic Objects (C# and Visual Basic)"
description: Learn how to create and use dynamic objects in this walkthrough. Create a custom dynamic object and a project that uses an 'IronPython' library.
ms.date: 03/24/2021
title: "Walkthrough: Creating and Using Dynamic Objects - Visual Basic"
description: Learn how to create and use dynamic late binding objects in this walkthrough. Create a custom dynamic object and a project that uses an 'IronPython' library.
ms.date: 02/17/2023
dev_langs:
- "csharp"
- "vb"
helpviewer_keywords:
- "dynamic objects [Visual Basic]"
- "dynamic objects"
- "dynamic objects [C#]"
---
# Walkthrough: Creating and Using Dynamic Objects (C# and Visual Basic)
# Walkthrough: Creating and Using Dynamic Objects in Visual Basic
Dynamic objects expose members such as properties and methods at run time, instead of at compile time. This enables you to create objects to work with structures that do not match a static type or format. For example, you can use a dynamic object to reference the HTML Document Object Model (DOM), which can contain any combination of valid HTML markup elements and attributes. Because each HTML document is unique, the members for a particular HTML document are determined at run time. A common method to reference an attribute of an HTML element is to pass the name of the attribute to the `GetProperty` method of the element. To reference the `id` attribute of the HTML element `<div id="Div1">`, you first obtain a reference to the `<div>` element, and then use `divElement.GetProperty("id")`. If you use a dynamic object, you can reference the `id` attribute as `divElement.id`.
Dynamic objects also provide convenient access to dynamic languages such as IronPython and IronRuby. You can use a dynamic object to refer to a dynamic script that is interpreted at run time.
You reference a dynamic object by using late binding. In C#, you specify the type of a late-bound object as `dynamic`. In Visual Basic, you specify the type of a late-bound object as `Object`. For more information, see [dynamic](../../language-reference/builtin-types/reference-types.md) and [Early and Late Binding](../../../visual-basic/programming-guide/language-features/early-late-binding/index.md).
You reference a dynamic object by using late binding. You specify the type of a late-bound object as `Object`. For more information, see [[Early and Late Binding](./index.md).
You can create custom dynamic objects by using the classes in the <xref:System.Dynamic?displayProperty=nameWithType> namespace. For example, you can create an <xref:System.Dynamic.ExpandoObject> and specify the members of that object at run time. You can also create your own type that inherits the <xref:System.Dynamic.DynamicObject> class. You can then override the members of the <xref:System.Dynamic.DynamicObject> class to provide run-time dynamic functionality.
@ -46,7 +44,7 @@ The first walkthrough defines a custom dynamic object that searches the contents
1. Select **Create a new project**.
1. In the **Create a new project** dialog, select C# or Visual Basic, select **Console Application**, and then select **Next**.
1. In the **Create a new project** dialog, select Visual Basic, select **Console Application**, and then select **Next**.
1. In the **Configure your new project** dialog, enter `DynamicSample` for the **Project name**, and then select **Next**.
@ -60,39 +58,32 @@ The first walkthrough defines a custom dynamic object that searches the contents
1. At the top of the *ReadOnlyFile.cs* or *ReadOnlyFile.vb* file, add the following code to import the <xref:System.IO?displayProperty=nameWithType> and <xref:System.Dynamic?displayProperty=nameWithType> namespaces.
[!code-csharp[VbDynamicWalkthrough#1](~/samples/snippets/csharp/VS_Snippets_VBCSharp/vbdynamicwalkthrough/cs/readonlyfile.cs#1)]
[!code-vb[VbDynamicWalkthrough#1](~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/vbdynamicwalkthrough/vb/readonlyfile.vb#1)]
1. The custom dynamic object uses an enum to determine the search criteria. Before the class statement, add the following enum definition.
[!code-csharp[VbDynamicWalkthrough#2](~/samples/snippets/csharp/VS_Snippets_VBCSharp/vbdynamicwalkthrough/cs/readonlyfile.cs#2)]
[!code-vb[VbDynamicWalkthrough#2](~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/vbdynamicwalkthrough/vb/readonlyfile.vb#2)]
1. Update the class statement to inherit the `DynamicObject` class, as shown in the following code example.
[!code-csharp[VbDynamicWalkthrough#3](~/samples/snippets/csharp/VS_Snippets_VBCSharp/vbdynamicwalkthrough/cs/readonlyfile.cs#3)]
[!code-vb[VbDynamicWalkthrough#3](~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/vbdynamicwalkthrough/vb/readonlyfile.vb#3)]
1. Add the following code to the `ReadOnlyFile` class to define a private field for the file path and a constructor for the `ReadOnlyFile` class.
[!code-csharp[VbDynamicWalkthrough#4](~/samples/snippets/csharp/VS_Snippets_VBCSharp/vbdynamicwalkthrough/cs/readonlyfile.cs#4)]
[!code-vb[VbDynamicWalkthrough#4](~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/vbdynamicwalkthrough/vb/readonlyfile.vb#4)]
1. Add the following `GetPropertyValue` method to the `ReadOnlyFile` class. The `GetPropertyValue` method takes, as input, search criteria and returns the lines from a text file that match that search criteria. The dynamic methods provided by the `ReadOnlyFile` class call the `GetPropertyValue` method to retrieve their respective results.
[!code-csharp[VbDynamicWalkthrough#5](~/samples/snippets/csharp/VS_Snippets_VBCSharp/vbdynamicwalkthrough/cs/readonlyfile.cs#5)]
[!code-vb[VbDynamicWalkthrough#5](~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/vbdynamicwalkthrough/vb/readonlyfile.vb#5)]
1. After the `GetPropertyValue` method, add the following code to override the <xref:System.Dynamic.DynamicObject.TryGetMember%2A> method of the <xref:System.Dynamic.DynamicObject> class. The <xref:System.Dynamic.DynamicObject.TryGetMember%2A> method is called when a member of a dynamic class is requested and no arguments are specified. The `binder` argument contains information about the referenced member, and the `result` argument references the result returned for the specified member. The <xref:System.Dynamic.DynamicObject.TryGetMember%2A> method returns a Boolean value that returns `true` if the requested member exists; otherwise it returns `false`.
[!code-csharp[VbDynamicWalkthrough#6](~/samples/snippets/csharp/VS_Snippets_VBCSharp/vbdynamicwalkthrough/cs/readonlyfile.cs#6)]
[!code-vb[VbDynamicWalkthrough#6](~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/vbdynamicwalkthrough/vb/readonlyfile.vb#6)]
1. After the `TryGetMember` method, add the following code to override the <xref:System.Dynamic.DynamicObject.TryInvokeMember%2A> method of the <xref:System.Dynamic.DynamicObject> class. The <xref:System.Dynamic.DynamicObject.TryInvokeMember%2A> method is called when a member of a dynamic class is requested with arguments. The `binder` argument contains information about the referenced member, and the `result` argument references the result returned for the specified member. The `args` argument contains an array of the arguments that are passed to the member. The <xref:System.Dynamic.DynamicObject.TryInvokeMember%2A> method returns a Boolean value that returns `true` if the requested member exists; otherwise it returns `false`.
The custom version of the `TryInvokeMember` method expects the first argument to be a value from the `StringSearchOption` enum that you defined in a previous step. The `TryInvokeMember` method expects the second argument to be a Boolean value. If one or both arguments are valid values, they are passed to the `GetPropertyValue` method to retrieve the results.
[!code-csharp[VbDynamicWalkthrough#7](~/samples/snippets/csharp/VS_Snippets_VBCSharp/vbdynamicwalkthrough/cs/readonlyfile.cs#7)]
[!code-vb[VbDynamicWalkthrough#7](~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/vbdynamicwalkthrough/vb/readonlyfile.vb#7)]
1. Save and close the file.
@ -122,11 +113,10 @@ The first walkthrough defines a custom dynamic object that searches the contents
### To create a sample application that uses the custom dynamic object
1. In **Solution Explorer**, double-click the *Program.vb* file if you're using Visual Basic or the *Program.cs* file if you're using Visual C#.
1. In **Solution Explorer**, double-click the *Program.vb* file.
2. Add the following code to the `Main` procedure to create an instance of the `ReadOnlyFile` class for the *TextFile1.txt* file. The code uses late binding to call dynamic members and retrieve lines of text that contain the string "Customer".
[!code-csharp[VbDynamicWalkthrough#8](~/samples/snippets/csharp/VS_Snippets_VBCSharp/vbdynamicwalkthrough/cs/program.cs#8)]
[!code-vb[VbDynamicWalkthrough#8](~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/vbdynamicwalkthrough/vb/Program.vb#8)]
3. Save the file and press <kbd>Ctrl</kdb>+<kbd>F5</kbd> to build and run the application.
@ -139,7 +129,7 @@ The following walkthrough creates a project that accesses a library that is writ
1. In Visual Studio, select **File** > **New** > **Project**.
1. In the **Create a new project** dialog, select C# or Visual Basic, select **Console Application**, and then select **Next**.
1. In the **Create a new project** dialog, select Visual Basic, select **Console Application**, and then select **Next**.
1. In the **Configure your new project** dialog, enter `DynamicIronPythonSample` for the **Project name**, and then select **Next**.
@ -149,21 +139,18 @@ The following walkthrough creates a project that accesses a library that is writ
1. Install the [IronPython](https://www.nuget.org/packages/IronPython) NuGet package.
1. If you're using Visual Basic, edit the *Program.vb* file. If you're using Visual C#, edit the *Program.cs* file.
1. Edit the *Program.vb* file.
1. At the top of the file, add the following code to import the `Microsoft.Scripting.Hosting` and `IronPython.Hosting` namespaces from the IronPython libraries and the `System.Linq` namespace.
[!code-csharp[VbDynamicWalkthroughIronPython#1](~/samples/snippets/csharp/VS_Snippets_VBCSharp/vbdynamicwalkthroughironpython/cs/program.cs#1)]
[!code-vb[VbDynamicWalkthroughIronPython#1](~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/vbdynamicwalkthroughironpython/vb/Program.vb#1)]
1. In the Main method, add the following code to create a new `Microsoft.Scripting.Hosting.ScriptRuntime` object to host the IronPython libraries. The `ScriptRuntime` object loads the IronPython library module random.py.
[!code-csharp[VbDynamicWalkthroughIronPython#2](~/samples/snippets/csharp/VS_Snippets_VBCSharp/vbdynamicwalkthroughironpython/cs/program.cs#2)]
[!code-vb[VbDynamicWalkthroughIronPython#2](~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/vbdynamicwalkthroughironpython/vb/Program.vb#2)]
1. After the code to load the random.py module, add the following code to create an array of integers. The array is passed to the `shuffle` method of the random.py module, which randomly sorts the values in the array.
[!code-csharp[VbDynamicWalkthroughIronPython#3](~/samples/snippets/csharp/VS_Snippets_VBCSharp/vbdynamicwalkthroughironpython/cs/program.cs#3)]
[!code-vb[VbDynamicWalkthroughIronPython#3](~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/vbdynamicwalkthroughironpython/vb/Program.vb#3)]
1. Save the file and press <kbd>Ctrl</kdb>+<kbd>F5</kbd> to build and run the application.
@ -172,7 +159,4 @@ The following walkthrough creates a project that accesses a library that is writ
- <xref:System.Dynamic?displayProperty=nameWithType>
- <xref:System.Dynamic.DynamicObject?displayProperty=nameWithType>
- [Using Type dynamic](./using-type-dynamic.md)
- [Early and Late Binding](../../../visual-basic/programming-guide/language-features/early-late-binding/index.md)
- [dynamic](../../language-reference/builtin-types/reference-types.md)
- [Implementing Dynamic Interfaces (downloadable PDF from Microsoft TechNet)](https://download.microsoft.com/download/5/4/B/54B83DFE-D7AA-4155-9687-B0CF58FF65D7/implementing-dynamic-interfaces.pdf)

Просмотреть файл

@ -8,7 +8,7 @@ ms.assetid: bdee2a00-07ff-46f9-86dd-fdac9b99cc97
---
# Working with Dynamic Objects (Visual Basic)
Dynamic objects provide another way, other than the `Object` type, to late bind to an object at run time. A dynamic object exposes members such as properties and methods at run time by using dynamic interfaces that are defined in the <xref:System.Dynamic> namespace. You can use the classes in the <xref:System.Dynamic> namespace to create objects that work with data structures that do not match a static type or format. You can also use the dynamic objects that are defined in dynamic languages such as IronPython and IronRuby. For examples that show how to create dynamic objects or use a dynamic object defined in a dynamic language, see [Walkthrough: Creating and Using Dynamic Objects](../../../../csharp/programming-guide/types/walkthrough-creating-and-using-dynamic-objects.md), <xref:System.Dynamic.DynamicObject>, or <xref:System.Dynamic.ExpandoObject>.
Dynamic objects provide another way, other than the `Object` type, to late bind to an object at run time. A dynamic object exposes members such as properties and methods at run time by using dynamic interfaces that are defined in the <xref:System.Dynamic> namespace. You can use the classes in the <xref:System.Dynamic> namespace to create objects that work with data structures that do not match a static type or format. You can also use the dynamic objects that are defined in dynamic languages such as IronPython and IronRuby. For examples that show how to create dynamic objects or use a dynamic object defined in a dynamic language, see [Walkthrough: Creating and Using Dynamic Objects](walkthrough-creating-and-using-dynamic-objects.md), <xref:System.Dynamic.DynamicObject>, or <xref:System.Dynamic.ExpandoObject>.
Visual Basic binds to objects from the dynamic language runtime and dynamic languages such as IronPython and IronRuby by using the <xref:System.Dynamic.IDynamicMetaObjectProvider> interface. Examples of classes that implement the `IDynamicMetaObjectProvider` interface are the <xref:System.Dynamic.DynamicObject> and <xref:System.Dynamic.ExpandoObject> classes.
@ -18,5 +18,5 @@ Dynamic objects provide another way, other than the `Object` type, to late bind
- <xref:System.Dynamic.DynamicObject>
- <xref:System.Dynamic.ExpandoObject>
- [Walkthrough: Creating and Using Dynamic Objects](../../../../csharp/programming-guide/types/walkthrough-creating-and-using-dynamic-objects.md)
- [Walkthrough: Creating and Using Dynamic Objects](walkthrough-creating-and-using-dynamic-objects.md)
- [Early and Late Binding](index.md)

Просмотреть файл

@ -250,6 +250,8 @@ items:
href: programming-guide/com-interop/com-interoperability-in-net-framework-applications.md
- name: "Walkthrough: Implementing Inheritance with COM Objects"
href: programming-guide/com-interop/walkthrough-implementing-inheritance-with-com-objects.md
- name: "Walkthrough: Office programming"
href: programming-guide/com-interop/walkthrough-office-programming.md
- name: Language Reference
href: language-reference/index.md
items:

Просмотреть файл

@ -1,133 +0,0 @@
//-----------------------------------------------------------------------------
//<Snippet3>
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WinSound
{
public partial class Form1 : Form
{
private TextBox textBox1;
private Button button1;
public Form1() // Constructor.
{
InitializeComponent();
}
[DllImport("winmm.DLL", EntryPoint = "PlaySound", SetLastError = true, CharSet = CharSet.Unicode, ThrowOnUnmappableChar = true)]
private static extern bool PlaySound(string szSound, System.IntPtr hMod, PlaySoundFlags flags);
[System.Flags]
public enum PlaySoundFlags : int
{
SND_SYNC = 0x0000,
SND_ASYNC = 0x0001,
SND_NODEFAULT = 0x0002,
SND_LOOP = 0x0008,
SND_NOSTOP = 0x0010,
SND_NOWAIT = 0x00002000,
SND_FILENAME = 0x00020000,
SND_RESOURCE = 0x00040004
}
private void button1_Click(object sender, System.EventArgs e)
{
var dialog1 = new OpenFileDialog();
dialog1.Title = "Browse to find sound file to play";
dialog1.InitialDirectory = @"c:\";
//<Snippet5>
dialog1.Filter = "Wav Files (*.wav)|*.wav";
//</Snippet5>
dialog1.FilterIndex = 2;
dialog1.RestoreDirectory = true;
if (dialog1.ShowDialog() == DialogResult.OK)
{
textBox1.Text = dialog1.FileName;
PlaySound(dialog1.FileName, new System.IntPtr(), PlaySoundFlags.SND_SYNC);
}
}
private void Form1_Load(object sender, EventArgs e)
{
// Including this empty method in the sample because in the IDE,
// when users click on the form, generates code that looks for a default method
// with this name. We add it here to prevent confusion for those using the samples.
}
}
}
//</Snippet3>
//-----------------------------------------------------------------------------
// Form1.Designer.cs
//-----------------------------------------------------------------------------
namespace WinSound
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components=null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing&&(components!=null))
{
components.Dispose();
}
base.Dispose(disposing);
}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components=new System.ComponentModel.Container();
this.AutoScaleMode=System.Windows.Forms.AutoScaleMode.Font;
this.Text="WinSound";
//<Snippet4>
this.button1 = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(192, 40);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(88, 24);
this.button1.TabIndex = 0;
this.button1.Text = "Browse";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(8, 40);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(168, 20);
this.textBox1.TabIndex = 1;
this.textBox1.Text = "FIle path";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Platform Invoke WinSound C#";
this.ResumeLayout(false);
this.PerformLayout();
//</Snippet4>
}
}
}

Просмотреть файл

@ -1,16 +0,0 @@
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace OfficeWalkthroughCS
{
//<snippet2>
class Account
{
public int ID { get; set; }
public double Balance { get; set; }
}
//</snippet2>
}

Просмотреть файл

@ -1,5 +0,0 @@
<hostitem:hostItem hostitem:baseType="Microsoft.Office.Tools.AddInBase" hostitem:namespace="OfficeWalkthroughCS" hostitem:className="ThisAddIn" hostitem:identifier="ThisAddIn" hostitem:primaryCookie="AddIn" hostitem:master="true" hostitem:factoryType="Microsoft.Office.Tools.Excel.ApplicationFactory" hostitem:startupIndex="0" xmlns:hostitem="http://schemas.microsoft.com/2004/VisualStudio/Tools/Applications/HostItem.xsd">
<hostitem:hostObject hostitem:name="Application" hostitem:identifier="Application" hostitem:type="Microsoft.Office.Interop.Excel.Application" hostitem:cookie="Application" hostitem:modifier="Internal"/>
<hostitem:hostControl hostitem:name="CustomTaskPanes" hostitem:identifier="CustomTaskPanes" hostitem:type="Microsoft.Office.Tools.CustomTaskPaneCollection" hostitem:primaryCookie="CustomTaskPanes" hostitem:modifier="Internal"/>
<hostitem:hostControl hostitem:name="VstoSmartTags" hostitem:identifier="VstoSmartTags" hostitem:type="Microsoft.Office.Tools.SmartTagCollection" hostitem:primaryCookie="VstoSmartTags" hostitem:modifier="Internal"/>
</hostitem:hostItem>

Просмотреть файл

@ -1,11 +0,0 @@
{
"host": "visualstudio",
"expectederrors": [
{
"file": "samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideindexedproperties/cs/Program.cs",
"line": 5,
"column": 25,
"error": "CS0234"
}
]
}

Просмотреть файл

@ -1,17 +0,0 @@
{
"host": "visualstudio",
"expectederrors": [
{
"file": "samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguidenamedandoptional/cs/Program.cs",
"line": 6,
"column": 25,
"error": "CS0234"
},
{
"file": "samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguidenamedandoptional/cs/WordProgram.cs",
"line": 8,
"column": 24,
"error": "CS0234"
}
]
}

Просмотреть файл

@ -1,53 +0,0 @@
{
"host": "visualstudio",
"expectederrors": [
{
"file": "samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideofficehowto/cs/Program.cs",
"line": 6,
"column": 25,
"error": "CS0234"
},
{
"file": "samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideofficehowto/cs/Program.cs",
"line": 7,
"column": 24,
"error": "CS0234"
},
{
"file": "samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideofficehowto/cs/Walkthrough.cs",
"line": 5,
"column": 25,
"error": "CS0234"
},
{
"file": "samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideofficehowto/cs/Walkthrough.cs",
"line": 6,
"column": 24,
"error": "CS0234"
},
{
"file": "samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideofficehowto/cs/Program.cs(6,25)",
"line": 6,
"column": 25,
"error": "CS0234"
},
{
"file": "samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideofficehowto/cs/Program.cs(7,24)",
"line": 7,
"column": 24,
"error": "CS0234"
},
{
"file": "samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideofficehowto/cs/Walkthrough.cs(5,25)",
"line": 5,
"column": 25,
"error": "CS0234"
},
{
"file": "samples/snippets/csharp/VS_Snippets_VBCSharp/csprogguideofficehowto/cs/Walkthrough.cs(6,24)",
"line": 6,
"column": 24,
"error": "CS0234"
}
]
}