| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- using System;
- using System.ComponentModel;
- using System.IO;
- using System.Runtime.InteropServices;
- using UnityEngine;
- public class FileDialogHelper
- {
- public class FileOpMsg
- {
- public bool success;
- public string msg;
- }
- public const string IMAGEFILTER = "图片文件(*.jpg;*.png)\0*.jpg;*.png";
- public const string ALLFILTER = "所有文件(*.*)\0*.*";
- public bool CopySelectFile(string sourcePath, string targetPath)
- {
- try
- {
- File.Copy(sourcePath, targetPath + $"/{Path.GetFileName(sourcePath)}", true);
- return true;
- }
- catch (Exception)
- {
- Debug.LogError($"sourcePath = {sourcePath}");
- Debug.LogError($"targetPath = {Path.GetFileName(sourcePath)}");
- Debug.LogError("拷贝失败");
- return false;
- }
- }
- public string SelectFile(Action<FileOpMsg> callback, string filter = ALLFILTER)
- {
- Debug.Log("open 00");
- FileOpMsg fileOpMsg = new FileOpMsg();
- try
- {
- OpenFileName openFileName = new OpenFileName();
- openFileName.structSize = Marshal.SizeOf(openFileName);
- //openFileName.hwndOwner = WindowsTools.ProcessHandle;
- openFileName.filter = filter;
- openFileName.file = new string(new char[256]);
- openFileName.maxFile = openFileName.file.Length;
- openFileName.fileTitle = new string(new char[64]);
- openFileName.maxFileTitle = openFileName.fileTitle.Length;
- openFileName.title = "选择文件";
- openFileName.flags = 0x00080000 | 0x00001000 | 0x00000800 | 0x00000008;
- if (GetSaveFileName(openFileName))
- {
- string filepath = openFileName.file; //选择的文件路径;
- if (File.Exists(filepath))
- {
- fileOpMsg.success = true;
- fileOpMsg.msg = filepath;
- callback?.Invoke(fileOpMsg);
- return fileOpMsg.msg;
- }
- }
- }
- catch (Exception e)
- {
- fileOpMsg.success = false;
- fileOpMsg.msg = e.ToString();
- callback?.Invoke(fileOpMsg);
- Debug.LogError(fileOpMsg.msg);
- return fileOpMsg.msg;
- }
- fileOpMsg.success = true;
- fileOpMsg.msg = string.Empty;
- callback?.Invoke(fileOpMsg);
- return fileOpMsg.msg;
- }
- [DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
- private static extern bool GetSaveFileName([In, Out] OpenFileName ofn);
- [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;
- }
- #region 隐藏
-
- /// <summary> 用于显示Windows平台的标准文件对话框 </summary>
- /// <param name="ofn"></param>
- /// <returns>返回用户所选文件的路径信息</returns>
- // 引入外部库,SetLastError = true将上一个错误代码设置为非零值,CharSet = CharSet.Auto字符集由运行时环境自动选择
- ///[In, Out]是修饰符,用于指定参数是既输入又输出的(类似于引用传参)
- [DllImport("Comdlg32.dll", SetLastError = true, CharSet = CharSet.Auto)]
- private static extern bool GetOpenFileName([In, Out] FileDialogWin ofn);
- [DllImport("kernel32.dll")]
- private static extern uint GetLastError();
- /// <summary>
- /// 打开文件对话框
- /// </summary>
- /// <param name="title">对话框标题</param>
- /// <param name="defaultPath">对话框默认路径</param>
- /// <param name="extension">文件默认格式</param>
- /// <returns></returns>
- public string OpenWindowsFileDialog(string title, string defaultPath, string extension)
- {
- #if UNITY_EDITOR
- return UnityEditor.EditorUtility.OpenFilePanel(title, defaultPath, extension);
- #else
- // 在运行时用原生对话框
- FileDialogWin ofn = new FileDialogWin();
- ofn.structSize = Marshal.SizeOf(ofn);
- ofn.filter = extension;
- ofn.file = new string(new char[256]);
- ofn.maxFile = ofn.file.Length;
- ofn.title = title;
- ofn.initialDir = defaultPath;
- ofn.flags = 0x00080000 | 0x00001000 | 0x00000800 | 0x00000008;
- bool result = GetOpenFileName(ofn);
- Debug.LogError($"ofn = {ofn}");
- Debug.LogError($"result: {result}");
- if (!result)
- {
- uint errorCode = GetLastError();
- Debug.LogError($"errorCode = {errorCode}");
- if (errorCode == 0)
- {
- // 用户取消了对话框,这是正常行为
- Debug.Log("用户取消了文件选择");
- return null;
- }
- else
- {
- string errorMessage = new Win32Exception((int)errorCode).Message;
- Debug.LogError($"打开文件对话框失败,错误代码: {errorCode}, 错误信息: {errorMessage}");
- // 常见的错误代码
- switch (errorCode)
- {
- case 0x00000002: // ERROR_FILE_NOT_FOUND
- Debug.LogError("文件未找到,请检查默认路径是否存在");
- break;
- case 0x00000005: // ERROR_ACCESS_DENIED
- Debug.LogError("访问被拒绝,可能没有足够的权限");
- break;
- case 0x00000057: // ERROR_INVALID_PARAMETER
- Debug.LogError("参数无效,请检查结构体字段设置");
- break;
- }
- }
- return null;
- }
- return ofn.file;
- #endif
- }
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
- public class FileDialogWin
- {
- 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 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;
- }
-
- #endregion
- }
|