C# 调用 WinApi 中 ShellExecute 打开 Excel 的方法
背景:通过 C# 代码打开 Excel 时,Excel 内包含的宏无法正常加载,但是通过鼠标打开时,宏加载正常,因此想到可以通过 WinApi 来打开文件。
官网地址:https://docs.microsoft.com/zh-cn/windows/win32/api/shellapi/nf-shellapi-shellexecutea
API参考手册:http://www.office-cn.net/t/api/api_content.htm
WinApi 中 ShellExecute 的功能是运行一个外部程序(或者是打开一个已注册的文件、打开一个目录、打印一个文件等等),并对外部程序有一定的控制。函数如下:
IntPtr ShellExecute(IntPtr hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, ShowCommands nShowCmd);
参数说明:
hwnd:指定父窗口句柄,未指定时可以为 null 或者为 0
lpOperation:指定操作, 值可以为【open】、【print】、【explore】,释义如下:
open :执行由 lpFile 参数指定的程序,或打开由 lpFile 参数指定的文件或文件夹; print :打印由 lpFile 参数指定的文件; explore:浏览由 lpFile 参数指定的文件夹。
当参数设为 null 时,默认为 open。
lpFile:指定要打开的文件或程序
lpParameters:给要打开的程序指定参数; 如果打开的是文件,值为 null
lpDirectory:默认目录
nShowCmd:打开设置项,具体意义如下:
SW_HIDE = 0; //隐藏 SW_SHOWNORMAL = 1; //用最近的大小和位置显示, 激活 SW_NORMAL = 1; //同 SW_SHOWNORMAL SW_SHOWMINIMIZED = 2; //最小化, 激活 SW_SHOWMAXIMIZED = 3; //最大化, 激活 SW_MAXIMIZE = 3; //同 SW_SHOWMAXIMIZED SW_SHOWNOACTIVATE = 4; //用最近的大小和位置显示, 不激活 SW_SHOW = 5; //同 SW_SHOWNORMAL SW_MINIMIZE = 6; //最小化, 不激活 SW_SHOWMINNOACTIVE = 7; //同 SW_MINIMIZE SW_SHOWNA = 8; //同 SW_SHOWNOACTIVATE SW_RESTORE = 9; //同 SW_SHOWNORMAL SW_SHOWDEFAULT = 10; //同 SW_SHOWNORMAL SW_MAX = 10; //同 SW_SHOWNORMAL
返回值说明:
返回值大于 32 时,即执行成功。执行失败的返回值具体意义如下:
0 = 0 //内存不足 ERROR_FILE_NOT_FOUND = 2; //文件名错误 ERROR_PATH_NOT_FOUND = 3; //路径名错误 ERROR_BAD_FORMAT = 11; //EXE 文件无效 SE_ERR_SHARE = 26; //发生共享错误 SE_ERR_ASSOCINCOMPLETE = 27; //文件名不完全或无效 SE_ERR_DDETIMEOUT = 28; //超时 SE_ERR_DDEFAIL = 29; //DDE 事务失败 SE_ERR_DDEBUSY = 30; //正在处理其他 DDE 事务而不能完成该 DDE 事务 SE_ERR_NOASSOC = 31; //没有相关联的应用程序
C#代码实现如下:
1 class Program 2 { 3 /// <summary> 4 /// 显示方式 5 /// </summary> 6 public enum ShowCommands : int 7 { 8 SW_HIDE = 0, 9 SW_SHOWNORMAL = 1, 10 SW_NORMAL = 1, 11 SW_SHOWMINIMIZED = 2, 12 SW_SHOWMAXIMIZED = 3, 13 SW_MAXIMIZE = 3, 14 SW_SHOWNOACTIVATE = 4, 15 SW_SHOW = 5, 16 SW_MINIMIZE = 6, 17 SW_SHOWMINNOACTIVE = 7, 18 SW_SHOWNA = 8, 19 SW_RESTORE = 9, 20 SW_SHOWDEFAULT = 10, 21 SW_FORCEMINIMIZE = 11, 22 SW_MAX = 11 23 } 24 25 [DllImport("shell32.dll")] 26 static extern IntPtr ShellExecute(IntPtr hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, ShowCommands nShowCmd); 27 28 [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] 29 private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);// 30 31 [DllImport("user32", CharSet = CharSet.Ansi, EntryPoint = "FindWindowA", ExactSpelling = false, SetLastError = true)] 32 public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 33 34 [DllImport("Oleacc.dll")] 35 public static extern int AccessibleObjectFromWindow(int hwnd, uint dwObjectID, byte[] riid, ref Microsoft.Office.Interop.Excel.Window ptr); 36 37 static void Main(string[] args) 38 { 39 string filepath = @"C:\Users\Administrator\Desktop\ddd.txt"; 40 IntPtr result = ShellExecute(IntPtr.Zero, "open", filepath, "", "", ShowCommands.SW_SHOWNORMAL); 41 42 if (result.ToInt32() <= 32) 43 { 44 Console.WriteLine("打开失败"); 45 } 46 47 Console.ReadKey(); 48 } 49 }