Exception when using TaskDialogCommandLink in Windows APICodePack TaskDialog in 64-bit environment

Asked 2 years ago, Updated 2 years ago, 43 views

.NET 4.5 (C#6.0) is developing Windows form applications application.
When using TaskDialog using the libraries below, an exception occurs.

  • Microsoft.WindowsAPICodePack.dll
  • Microsoft.WindowsAPICodePack.Shell.dll

[Exception details]

System.ComponentModel.Win32Exception (0x80004005): 
Dialog contents too complex.
System.OutOfMemoryException: Insufficient memory to continue the execution of the program.
at Microsoft.WindowsAPICodePack.Dialogs.NativeTaskDialog.NativeShow()
at Microsoft.WindowsAPICodePack.Dialogs.TaskDialog.ShowCore()

[Additional note]
An exception occurs when operating in 64-bit mode in an x64 environment.
Checked and compiled 32-bit priority in Visual Studio and it works.

windows c# .net

2022-09-30 18:45

1 Answers

I haven't tried it in Windows 8, but it worked in Windows 8.1+ Visual Studio 2013.

C#5.0 and .NET 4.5.

Create a Windows Form application and
From nuGet Package Manager
Search Windows 7 APICodepack to install Unmarked Shell.(Core is now installed and 3 are convenient.)

Add the application manifest file to the project, open the added file, and uncomment and enable the dependency comment-out in Microsoft.Windows.Common-Controls (version="6.0.0.0") commented-out at the end.

A dialog appears when you place a button on the form and configure and run an event handler similar to the following:

void button1_Click(object sender, EventArgse){
    vardialog = new TaskDialog();
    dialog.Caption="cap";
    dialog.InstructionText="inst";
    dialog.Text="text";
    dialog.Icon=TaskDialogStandardIcon.Information;
    dialog.StandardButtons=TaskDialogStandardButtons.Ok;
    dialog.Show();
}

Also, if you leave it as it is, the icon will not be displayed (bug?), so please try to replace it with opened as below.

void button1_Click(object sender, EventArgse){
    vardialog = new TaskDialog();
    dialog.Caption="cap";
    dialog.InstructionText="inst";
    dialog.Text="text";
    dialog.Icon=TaskDialogStandardIcon.Information;
    dialog.StandardButtons=TaskDialogStandardButtons.Ok;

    dialog.Opened+=dialog_opened;
    dialog.Show();
}

void dialog_opened(object sender, EventArgse) {
       TaskDialog taskDialog = sender as TaskDialog;
       taskDialog.Icon=taskDialog.Icon;
       taskDialog.InstructionText=taskDialog.InstructionText;
}

I prepared a new Win8.1 Pro+VS2015 preview and Win8.1 Pro.

There was no problem with the code I mentioned earlier, but if you use the TaskDialogCommandLink mentioned in the comment section, it will certainly be reproduced.This is a problem with Windows APICodePack.
The same thing happened when debugging was performed on VS2015.

Head office SO posted a similar issue

The problem is that the pointer is limited to 32 bits as shown here, and overflow exception occurs.
This happens in both 1.0.0 and 1.1.0 of MS.

I don't know why your 1.1.1 exception (too complex) occurs, but I would like to modify the github code to show you how to create a version of TaskDialogCommandLink that works in a 64-bit environment.

The code was originally published in http://code.msdn.microsoft.com/WindowsAPICodePack/, but it has already been closed. (On the contrary, there may be no more official fixes?)
So I'm going to get the source.Downloaded from the repository source for aybe/Windows-API-Code-Pack-1.1 that you think is your 1.1.1 repository

  • This is not a Microsoft official source
  • Procedure for upgrading to .NET 4.5 and compiling with VS2015 Preview.I will not discuss other environments.
  • TaskDialogCommandLink only has minimal source modification to work
  • Exclude and do not support ShellExtensions projects
  • I have no intention of submitting a pull request in particular, so you can do so here.

Please confirm with the above in mind.

Upgrade Project

Clone or download the source and open the solution in WindowsAPICodePack12.sln VS2015 Preview.The original source also appears to be included, so if you like, unzip the source(original) directory and correct it from the WindowsAPICodePack10.sln solution.

Originally based on 3.5, the upgrade wizard will occur in environments without 3.5.Upgrade to 4.5 as is.
If you want to use it in 3.5 environments, you can either create a different development environment or install .NET 3.5.

ShellExtensions has many errors due to interface reference errors, but I will not refer to them this time, so I will not be able to deal with them.Exclude from the solution

Adding References

The Shell project does not find the ContentProperty attribute, resulting in a compilation error.
Resolve the Shell project by adding the System.Xaml namespace.

Modifying is Nullable

VS2015 (or Roslyn?) cannot specify Nullable as the second operand of is.For this reason,

A compilation error occurs on line 205 of WindowsAPICodePack\Shell\PropertySystem\ShellProperty.cs.

I don't know what this line is doing in the first place (codingly, if value is nullable is true, call the HasValue property of value and if the result is false, it looks like a code to do the same as null, but value is nullable is not true?) Corrected as follows.

 // if (value is Nullable)
if(Nullable.GetUnderlyingType(typeof(T))!=null) 
{   // when type of value T is nullable-type
    Type = type of (T);
    PropertyInfopi=t.GetProperty("HasValue");
    if(pi!=null&value!=null)
    {

Note that the if statement on line 210 as well as line 205 says value!=null (I checked and found that if the value of the nullable type was null, it then dropped to GetValue).I don't think it's okay to just block else if.

Correct the Problem

Correct the cause of the problem error.

WindowsAPICodePack\Core\Interop\TaskDialogs\NativeTaskDialog.cs
Line 533 of the AllocateAndMarshalButtons method foreach configuring currentPtr

Marshal.StructureToPtr(button, currentPtr, false);
currentPtr=(IntPtr)(int)currentPtr+Marshal.SizeOf(button));

Rewrite to the following (this will be fixed to 64-bit only, but we will make both corresponding modifications):

Marshal.StructureToPtr(button, currentPtr, false);
// currentPtr=(IntPtr)(int)currentPtr+Marshal.SizeOf(button));
if(IntPtr.Size==4)
{
    currentPtr=(IntPtr)(int)currentPtr+Marshal.SizeOf(button));
}
else
{
    currentPtr=(IntPtr)(currentPtr.ToInt64() + Marshall.SizeOf(button));
}

There may be a tsukkomi that says 4 is a magic number, but I don't care because there were other parts that were judged by 4 or 8. :-)

If you build it now, I think the build will be completed without any problems.

Modify your source references

Uninstall the nuGet package and add the assembly you just built to the reference configuration.
If you look at Shell (WindowsAPICodePack\Shell\bin\Debug for Debug builds), you'll see Core and you'll find the assembly, so I'll add the two here.

After that, I think AnyCPU+32bit priority, x86, works whether it's 32-bit priority off or platform target x64.

The code used for verification (dialog display) is as follows:

private void button2_Click (object sender, EventArgse)
    {
        varcommandLinkDialog = new TaskDialog();

        commandLinkDialog.Caption="cap";
        commandLinkDialog.InstructionText="inst";
        commandLinkDialog.Text="Howru";

        varlink = null as TaskDialogCommandLink;

        link = new TaskDialogCommandLink("fine", "I'm fine.");
        link.Click+=(s,evt)=>commandLinkDialog.Close();
        commandLinkDialog.Controls.Add(link);

        link = new TaskDialogCommandLink("sick", "I'm sick.");
        link.Click+=(s,evt)=>commandLinkDialog.Close();
        commandLinkDialog.Controls.Add(link);

        commandLinkDialog.Show();
    }

What's Running and Project Options

I have just checked, but I have changed the source of the source to be modified a few times, so please let me know if there is anything wrong.


2022-09-30 18:45

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.