0

I am going to open the photo viewer using .net core and this is my code

using System.Diagnostics;
namespace TestProcessForOpenPhoto
{
    class Program
    {
        static void Main(string[] args)
        {
            var photoViewer = new Process();
            photoViewer.StartInfo.FileName = @"C:\Program Files\Windows Photo Viewer\PhotoViewer.dll";
            photoViewer.StartInfo.Arguments = @" C:\Users\XXXXX\Desktop\TestImage\abc.jpg";
            photoViewer.StartInfo.UseShellExecute = false;
            photoViewer.Start();
        }
    }
}

and I got this error message

System.ComponentModel.Win32Exception: 'The specified executable is not a valid application for this OS platform.'

Can anyone help me to fix this bug, thanks

EnergyBoy
  • 547
  • 1
  • 5
  • 18
  • 1
    *PhotoViewer.dll* is not an executable file. It's a dynamic link library. You can't execute those. You probably have to call an export from that DLL. – Andy Aug 18 '20 at 03:17
  • 1
    You could probably just set the `FileName` parameter to the `abc.jpg` path, remove the `Arguments` line, then set `UseShellExecute` to `true` – Andy Aug 18 '20 at 03:24
  • 1
    Greate ! @Andy this works for me ! thanks a lot – EnergyBoy Aug 18 '20 at 03:45
  • BTW I saw a solution in https://stackoverflow.com/questions/6808029/open-image-in-windows-photo-viewer/6808066 what is the difference ? – EnergyBoy Aug 18 '20 at 03:45
  • They are running `rundll32.exe` to invoke an export `ImageView_Fullscreen` stored in `PhotoViewer.dll` – Andy Aug 18 '20 at 03:57

1 Answers1

1

After researching this I noticed folks using rundll32.exe to execute an export from PhotoViewer.dll to display a picture using Microsoft Photo Viewer application. So I think that's what OP was trying to do, they just forgot to use the rundll32.exe application.

So I thought I'd take a crack at this and not use the rundll32.exe and just call the export directly. I debugged it with x86dbg and saw that it's passing in 4 parameters: pointer, pointer, pointer (to wchar_t*), int. I don't know what the parameters do, so I just set them to NULL and made sure to pass in the path to the picture as the 3rd and it seems to work.

So this will do what you want it to do. I know that hard-coding system paths is bad practice, but maybe someone who has more time can make this more dynamic.

private static class WindowsPhotoViewer
{
    private const string FilePath32 = @"c:\program files (x86)\Windows Photo Viewer\PhotoViewer.dll";
    private const string FilePath64 = @"c:\program files\Windows Photo Viewer\PhotoViewer.dll";

    [DllImport(FilePath32, CharSet = CharSet.Unicode, EntryPoint = "ImageView_FullscreenW")]
    private static extern void ImageView_Fullscreen32(
        IntPtr unknown1, IntPtr unknown2, string path, int unknown3);

    [DllImport(FilePath64, CharSet = CharSet.Unicode, EntryPoint = "ImageView_FullscreenW")]
    private static extern void ImageView_Fullscreen64(
        IntPtr unknown1, IntPtr unknown2, string path, int unknown3);

    public static bool ShowImage(FileInfo imageFile)
    {
        if ((IntPtr.Size == 8) && File.Exists(FilePath64) && imageFile.Exists)
        {
            ImageView_Fullscreen64(IntPtr.Zero, IntPtr.Zero, imageFile.FullName, 0);
            return true;
        }
        else if ((IntPtr.Size == 4) && File.Exists(FilePath32) && imageFile.Exists)
        {
            ImageView_Fullscreen32(IntPtr.Zero, IntPtr.Zero, imageFile.FullName, 0);
            return true;
        }
        return false;
    }
}

Then you can call it as so:

if(!WindowsPhotoViewer.ShowImage(new FileInfo(@"c:\users\andy\desktop\test.jpg")))
{
    Console.WriteLine("Failed to show image");
}
Andy
  • 12,859
  • 5
  • 41
  • 56
  • Oh that's a really great example, in my understanding, you are trying to import the viewer dll file and open image with that, is that correct ? – EnergyBoy Aug 18 '20 at 05:27
  • @EnergyBoy -- yes... I am calling the exported function in `PhotoViewer.dll` directly. Basically it's doing what the `rundll32.exe` program would have done. Probably a little overkill for what you need! But it seems to get the job done. – Andy Aug 18 '20 at 05:28
  • OK! I think the first comment you left to me is more simply for me. I will study this in the future, thanks a lot ! – EnergyBoy Aug 18 '20 at 05:31
  • Hi Andy I encounter some problem, is it possible implement this function in windows services ? It ran smoothly when I run in debug mode, but when I install it as a windows services, the image won't pop up – EnergyBoy Aug 18 '20 at 09:05
  • @EnergyBoy -- It's not possible without a little finesse. Check this out: https://stackoverflow.com/questions/4398694/starting-a-windows-application-from-a-windows-service – Andy Aug 18 '20 at 16:05