Использование GetOpenFileName вместо OpenFileDialog - PullRequest
2 голосов
/ 01 февраля 2012

Я не могу использовать OpenFileDialog в моем приложении.

В качестве альтернативы я использую метод GetOpenFileName ():

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace Reader
{
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public class OpenFileName
    {
        public int lstructSize;
        public IntPtr hwndOwner;
        public IntPtr hInstance;
        public string lpstrFilter = null;
        public string lpstrCustomFilter = null;
        public int lMaxCustomFilter;
        public int lFilterIndex;
        public string lpstrFile = null;
        public int lMaxFile = 0;
        public string lpstrFileTitle = null;
        public int lMaxFileTitle = 0;
        public string lpstrInitialDir = null;
        public string lpstrTitle = null;
        public int lFlags;
        public ushort nFileOffset;
        public ushort nFileExtension;
        public string lpstrDefExt = null;
        public int lCustData;
        public int lpfHook;
        public int lpTemplateName;
    }

    public class OpenDialog
    {
        [DllImport("Comdlg32.dll",CharSet = CharSet.Auto)]
        public static extern bool GetOpenFileName([In, Out] OpenFileName ofn);
    }
}

А затем используйте его в событии OnClick для кнопки, подобной этой:

OpenFileName qofn = new OpenFileName();

qofn.lstructSize = Marshal.SizeOf(qofn);
qofn.lpstrFile = "";
qofn.lMaxFile = 256;
qofn.lpstrFileTitle = "";
qofn.lMaxFileTitle = 64;
qofn.hInstance = this.Handle;
source.Text = "Wait...";
if (OpenDialog.GetOpenFileName(qofn))
{
    MessageBox.Show("ofn.file: " + qofn. lpstrFile );
}

Когда приложение запускается и нажимается кнопка, и я пытаюсь открыть файл, вот что происходит:

1-я попытка:

возвращает путь к моему файлу, но вместо C: \ Dira \ DIRB \ DIRC \ имяфайла.рсш я имею C: \ Dira \ DIRB \ dircfilename.ext без '\' перед именем файла

2-я попытка

Все в порядке

следующая: случаются случайные сбои, например нарушение произвольного доступа или зависание графического интерфейса пользователя, а также невозможность остановки процесса приложения даже в диспетчере задач или другие ошибки.

Обычно диалог работает 2-3 раза, прежде чем приложение перестает работать навсегда.

Что не так с моим кодом?

EDIT:

Я не могу использовать OpenFileDialog. Я использую WinPE 4.0 (Windows ADK). Когда я пробую OpenFileDIalog, он выдает ошибку времени выполнения 80040111 . Вероятно, это связано с тем, что ядро ​​не поддерживается (так же, как Server Core не поддерживает OpenFileDialog, ошибка та же). Вероятно, в WinPE 4.0 они используют GetOpenFileName в таких приложениях, как блокнот. И это работает для них.

Ответы [ 2 ]

4 голосов
/ 01 февраля 2012

ОК, я нашел этот образец Microsoft, и он работает:

// Copyright
// Microsoft Corporation
// All rights reserved

// OpenFileDlg.cs

using System;
using System.Text;
using System.Runtime.InteropServices;

/*
typedef struct tagOFN { 
  DWORD         lStructSize; 
  HWND          hwndOwner; 
  HINSTANCE     hInstance; 
  LPCTSTR       lpstrFilter; 
  LPTSTR        lpstrCustomFilter; 
  DWORD         nMaxCustFilter; 
  DWORD         nFilterIndex; 
  LPTSTR        lpstrFile; 
  DWORD         nMaxFile; 
  LPTSTR        lpstrFileTitle; 
  DWORD         nMaxFileTitle; 
  LPCTSTR       lpstrInitialDir; 
  LPCTSTR       lpstrTitle; 
  DWORD         Flags; 
  WORD          nFileOffset; 
  WORD          nFileExtension; 
  LPCTSTR       lpstrDefExt; 
  LPARAM        lCustData; 
  LPOFNHOOKPROC lpfnHook; 
  LPCTSTR       lpTemplateName; 
#if (_WIN32_WINNT >= 0x0500)
  void *        pvReserved;
  DWORD         dwReserved;
  DWORD         FlagsEx;
#endif // (_WIN32_WINNT >= 0x0500)
} OPENFILENAME, *LPOPENFILENAME; 
*/

[ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Auto )]  
public class OpenFileName 
{
    public int      structSize = 0;
    public IntPtr   dlgOwner = IntPtr.Zero; 
    public IntPtr   instance = IntPtr.Zero;

    public String   filter = null;
    public String   customFilter = null;
    public int      maxCustFilter = 0;
    public int      filterIndex = 0;

    public String   file = null;
    public int      maxFile = 0;

    public String   fileTitle = null;
    public int      maxFileTitle = 0;

    public String   initialDir = null;

    public String   title = null;   

    public int      flags = 0; 
    public short    fileOffset = 0;
    public short    fileExtension = 0;

    public String   defExt = null; 

    public IntPtr   custData = IntPtr.Zero;  
    public IntPtr   hook = IntPtr.Zero;  

    public String   templateName = null; 

    public IntPtr   reservedPtr = IntPtr.Zero; 
    public int      reservedInt = 0;
    public int      flagsEx = 0;
}

public class LibWrap
{
    //BOOL GetOpenFileName(LPOPENFILENAME lpofn);

    [ DllImport( "Comdlg32.dll", CharSet=CharSet.Auto )]                
    public static extern bool GetOpenFileName([ In, Out ] OpenFileName ofn );   
}

public class App
{
    public static void Main()
    {
        OpenFileName ofn = new OpenFileName();

        ofn.structSize = Marshal.SizeOf( ofn );

        ofn.filter = "Log files\0*.log\0Batch files\0*.bat\0";

        ofn.file = new String( new char[ 256 ]);
        ofn.maxFile = ofn.file.Length;

        ofn.fileTitle = new String( new char[ 64 ]);
        ofn.maxFileTitle = ofn.fileTitle.Length;    

        ofn.initialDir = "C:\\";
        ofn.title = "Open file called using platform invoke...";
        ofn.defExt = "txt";

        if( LibWrap.GetOpenFileName( ofn ))
        {
            Console.WriteLine( "Selected file with full path: {0}", ofn.file );
            Console.WriteLine( "Selected file name: {0}", ofn.fileTitle );
            Console.WriteLine( "Offset from file name: {0}", ofn.fileOffset );
            Console.WriteLine( "Offset from file extension: {0}", ofn.fileExtension );
        }
    }
}
2 голосов
/ 29 сентября 2014

Доступны примеры OpenFileDlg (например, тот, который использовался в ответе Ари) Здесь .

На странице есть примеры на C #, C ++ и VB.Я протестировал пример VB в WinPE 5.1, и он прекрасно работает, за исключением фильтра типов файлов;Он показывает все типы файлов все время.

Я был удивлен, обнаружив, что даже с пакетом WinPE-NetFX, установленным в моем образе WinPE, OpenFileDialog не доступен в WinPE, и при попытке его использования выдается ошибка, указанная ввопрос.Эти примеры OpenFileDlg, в которых используется неуправляемая функция GetOpenFileName, являются единственной альтернативой, которую мне удалось найти для использования в WinPE.

...