Jump to content

filetype plugin not showing in open/save list


Evan Wallace

Recommended Posts

Ok, I know this is an odd request, but here it goes...

I need to use C++, not C#, because I need to use a JPEG library in C. It is supposed to work because of Common Language Runtime. I have tried to create two identical code samples in both C# and C++, but the C# one works and the C++ one only works sometimes. It works on my laptop but not on my desktop, and both have the most recent version (3.35?). If you guys don't do C++ at all, just say so and I'll look elsewhere, but I just thought I'd try.

Here is the C# version:

using System;
using System.IO;
using PaintDotNet;
using PaintDotNet.Data;

using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;

using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Resources;

[assembly]
[assembly]
[assembly]
[assembly]
[assembly]
[assembly]
[assembly]
[assembly]

[assembly]
[assembly]
[assembly]
[assembly]
[assembly]

namespace Test
{
public class TestFileType : FileType
{
	public TestFileType()
		: base("Text Document",
			FileTypeFlags.SupportsLoading | FileTypeFlags.SupportsSaving,
			new String[] { ".txt" } )
	{
		StreamWriter file = new StreamWriter(File.Open("C:\\test.log", FileMode.Append));
		file.WriteLine("TestFileType::TestFileType() - C#");
		file.Close();
	}

	protected override Document OnLoad(Stream input)
	{
		StreamWriter file = new StreamWriter(File.Open("C:\\test.log", FileMode.Append));
		file.WriteLine("TestFileType::OnLoad() - C#");
		file.Close();

		return new Document(100, 100);
	}

	protected override void OnSave(Document input, Stream output, SaveConfigToken token,
		Surface scratchSurface, ProgressEventHandler callback)
	{
		StreamWriter file = new StreamWriter(File.Open("C:\\test.log", FileMode.Append));
		file.WriteLine("TestFileType::OnSave() - C#");
		file.Close();
	}
};

public class TestFileTypeFactory : IFileTypeFactory
{
	public FileType[] GetFileTypeInstances()
	{
		StreamWriter file = new StreamWriter(File.Open("C:\\test.log", FileMode.Append));
		file.WriteLine("TestFileTypeFactory::GetFileTypeInstances() - C#");
		file.Close();

		return new FileType[] { new TestFileType() };
	}
};
}

Here is the C++ version:

using namespace System;
using namespace System::IO;
using namespace PaintDotNet;
using namespace PaintDotNet::Data;

using namespace System::Collections::Generic;
using namespace System::Text;
using namespace System::Drawing;
using namespace System::Drawing::Imaging;

using namespace System::Reflection;
using namespace System::Runtime::CompilerServices;
using namespace System::Runtime::InteropServices;
using namespace System::Resources;

[assembly];
[assembly];
[assembly];
[assembly];
[assembly];
[assembly];
[assembly];
[assembly];

[assembly];
[assembly];
[assembly];
[assembly];
[assembly];

namespace Test
{
public ref class TestFileType : FileType
{
public:
	static array^ extensions = gcnew array { ".txt" };

	TestFileType()
		: FileType("Text Document",
			FileTypeFlags::SupportsLoading | FileTypeFlags::SupportsSaving,
			extensions )
	{
		StreamWriter^ file = gcnew StreamWriter(File::Open("C:\\test.log", FileMode::Append));
		file->WriteLine("FileType::TestFileType() - C++");
		file->Close();
	}

protected:
	virtual Document^ OnLoad(Stream^ input) override
	{
		StreamWriter^ file = gcnew StreamWriter(File::Open("C:\\test.log", FileMode::Append));
		file->WriteLine("FileType::OnLoad() - C++");
		file->Close();

		return gcnew Document(100, 100);
	}

	virtual void OnSave(Document^ input, Stream^ output, SaveConfigToken^ token,
		Surface^ scratchSurface, ProgressEventHandler^ callback) override
	{
		StreamWriter^ file = gcnew StreamWriter(File::Open("C:\\test.log", FileMode::Append));
		file->WriteLine("FileType::OnSave() - C++");
		file->Close();
	}
};

public ref class TestFileTypeFactory : IFileTypeFactory
{
public:
	virtual array^ GetFileTypeInstances()
	{
		StreamWriter^ file = gcnew StreamWriter(File::Open("C:\\test.log", FileMode::Append));
		file->WriteLine("TestFileTypeFactory::GetFileTypeInstances() - C++");
		file->Close();

		return gcnew array { gcnew TestFileType() };
	}
};
}

The code logs every function to C:\test.log. When I test both plugins, C:\test.log only contains:

TestFileTypeFactory::GetFileTypeInstances() - C#
TestFileType::TestFileType() - C#

I was thinking that since TestFileTypeFactory::GetFileTypeInstances wasn't called, that:

virtual array^ GetFileTypeInstances()

isn't the right translation for:

public FileType[] GetFileTypeInstances()

or maybe there is an exception thrown in the Paint.NET source that is not reported, but I don't know. Any ideas?

Link to comment
Share on other sites

Hmm I haven't used managed C++ or C++/CLI ... what happens if you look at the compiled DLL with Reflector? You can probably set it to C# mode for its disassembly which should help with translation.

http://www.aisto.com/roeder/dotnet/

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

Reflector looks like a great tool, but all of the decompiled functions look identical. I have a hunch that it isn't strictly a problem with the assembly, because it loads fine on some computers...

Apparently Paint.NET silently ignores loading errors in release builds:

foreach (Type type in fileTypeFactories)
{
   ConstructorInfo ci = type.GetConstructor(System.Type.EmptyTypes);
   IFileTypeFactory factory;

   try
   {
       factory = (IFileTypeFactory)ci.Invoke(null);
   }

   catch (Exception)
   {
#if DEBUG
       throw;
#else
       continue;
#endif
   }

   FileType[] fileTypes;

   try
   {
       fileTypes = factory.GetFileTypeInstances();
   }

   catch (Exception)
   {
#if DEBUG
       throw;
#else
       continue;
#endif
   }

   if (fileTypes != null)
   {
       foreach (FileType fileType in fileTypes)
       {
           allFileTypes.Add(fileType);
       }
   }
}

So I guess I'll never know why...unless there is some way to get a debug version of Paint.NET ;)

Link to comment
Share on other sites

So I guess I'll never know why...unless there is some way to get a debug version of Paint.NET ;)
Try copying PDN's file type code and executing that by itself.
Link to comment
Share on other sites

I finally figured it out. Gahh that took forever! I did write a loader using the Paint.NET source code and I got the error:

Could not load file or assembly 'test_cpp, Version=1.0.3146.28511, Culture=neutral, PublicKeyToken=null' or one of its dependencies. This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem. (Exception from HRESULT: 0x800736B1)

That led me here, which said that you have to:

Copy everything on your computer from:

C:\Program Files\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.CRT

To here on the computer where it is not working:

C:\Program Files\Paint.NET\FileTypes\Microsoft.VC90.CRT

Finally works... looks like Visual C++ Express is not backwards-compatible, and Microsoft.VC90.CRT is installed in a IE7 update or something... anyway, thanks for your help!

Link to comment
Share on other sites

Yeah I considered using the Microsoft Visual C++ 2008 Redistributable Package but I don't know if there is an uninstall option, and I like to know what I am doing to my system. If you ever want to stop using my plugin, all you have to do is delete it and the Microsoft.VC90.CRT folder instead of leaving those files who knows where on your HD. Personal preference I guess...

Link to comment
Share on other sites

The redistributable packages all appear in the Control Panel Applications menu, even different versions separately. Uninstalling is as simple as with other programs, on my comp atleast.

sig.jpg.7f312affa740bae49243c4439bc4a244.jpg

Link to comment
Share on other sites

A lot of other software uses the version 9 C-runtime redistributable. It's no big deal to have it installed on the system; it's not like it's a service running in the background or anything.

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...