当前位置:   article > 正文

C# WPF 项目中无法使用Console输出时出现句柄无效的IO异常解决方法_console.windowwidth句柄无效

console.windowwidth句柄无效

如以下代码,重点看:ConsoleManager.Show()的位置注释即可;


  1. using System;
  2. using System.Collections.Generic;
  3. using System.Windows;
  4. using System.IO;
  5. using System.Security;
  6. using System.Runtime.InteropServices;
  7. using System.Diagnostics;
  8. namespace GameLanguagePicker
  9. {
  10. /// <summary>
  11. /// 该类源于Stackoverflow 的一问题贴的回答:
  12. /// 问题:No output to console from a WPF application?
  13. /// 地址:http://stackoverflow.com/questions/160587/no-output-to-console-from-a-wpf-application/718505
  14. /// </summary>
  15. [SuppressUnmanagedCodeSecurity]
  16. public static class ConsoleManager
  17. {
  18. private const string Kernel32_DllName = "kernel32.dll";
  19. [DllImport(Kernel32_DllName)]
  20. private static extern bool AllocConsole();
  21. [DllImport(Kernel32_DllName)]
  22. private static extern bool FreeConsole();
  23. [DllImport(Kernel32_DllName)]
  24. private static extern IntPtr GetConsoleWindow();
  25. [DllImport(Kernel32_DllName)]
  26. private static extern int GetConsoleOutputCP();
  27. public static bool HasConsole
  28. {
  29. get { return GetConsoleWindow() != IntPtr.Zero; }
  30. }
  31. /// <summary>
  32. /// Creates a new console instance if the process is not attached to a console already.
  33. /// </summary>
  34. public static void Show()
  35. {
  36. //#if DEBUG
  37. if (!HasConsole)
  38. {
  39. AllocConsole();
  40. InvalidateOutAndError();
  41. }
  42. //#endif
  43. }
  44. /// <summary>
  45. /// If the process has a console attached to it, it will be detached and no longer visible. Writing to the System.Console is still possible, but no output will be shown.
  46. /// </summary>
  47. public static void Hide()
  48. {
  49. //#if DEBUG
  50. if (HasConsole)
  51. {
  52. SetOutAndErrorNull();
  53. FreeConsole();
  54. }
  55. //#endif
  56. }
  57. public static void Toggle()
  58. {
  59. if (HasConsole)
  60. {
  61. Hide();
  62. }
  63. else
  64. {
  65. Show();
  66. }
  67. }
  68. static void InvalidateOutAndError()
  69. {
  70. Type type = typeof(System.Console);
  71. System.Reflection.FieldInfo _out = type.GetField("_out",
  72. System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
  73. System.Reflection.FieldInfo _error = type.GetField("_error",
  74. System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
  75. System.Reflection.MethodInfo _InitializeStdOutError = type.GetMethod("InitializeStdOutError",
  76. System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
  77. Debug.Assert(_out != null);
  78. Debug.Assert(_error != null);
  79. Debug.Assert(_InitializeStdOutError != null);
  80. _out.SetValue(null, null);
  81. _error.SetValue(null, null);
  82. _InitializeStdOutError.Invoke(null, new object[] { true });
  83. }
  84. static void SetOutAndErrorNull()
  85. {
  86. Console.SetOut(TextWriter.Null);
  87. Console.SetError(TextWriter.Null);
  88. }
  89. }
  90. /// <summary>
  91. /// @author Jave.Lin
  92. /// @date 2014-1-9
  93. /// </summary>
  94. public class Programs
  95. {
  96. [STAThread]
  97. public static void Main(string[] args)
  98. {
  99. try
  100. {
  101. var listArgs = new List<string>(args);
  102. //listArgs.Add("-h");
  103. listArgs.Add("-p");
  104. listArgs.Add(@"E:\myWork");
  105. if (listArgs.Count == 0 || !listArgs.Contains("-h")) // 可视化操作
  106. {
  107. var win = new MainWindow();//你要启动的Window类;就是你继承自Window类的类,并加载了一些.xaml(不加也可以)的窗体类;
  108. Application app = new Application();//自己去new一个,或使用当前这个App也可以(它也是继承Application)
  109. app.MainWindow = win;
  110. //来种方式启动;
  111. //第一种:
  112. //wb.Show();
  113. //app.Run();//以MainWindow作为启动窗体
  114. //第二种
  115. var pIdx = listArgs.IndexOf("-p");
  116. if (pIdx != -1)
  117. {
  118. win.pathTextBox.Text = win.Picker.Path = listArgs[pIdx + 1];
  119. win.Start();
  120. }
  121. app.Run(win);//以指定的Window来启动
  122. }
  123. else // 控制台式操作
  124. {
  125. // 如果这里不申请控制台,后台,所有用到:Console的API都会报:句柄无效的IO异常;
  126. // 可能是WPF 项目配置,还是其它的,在启动时,将Console指定了输出流吧;这个希望有知道的朋友可以告知一下
  127. ConsoleManager.Show();
  128. if (listArgs.Contains("-?") || (listArgs.Count > 1 && listArgs[0].ToLower() == "help") || !listArgs.Contains("-h") || !listArgs.Contains("-p"))
  129. {
  130. ShowUsage();
  131. Console.ReadLine();
  132. }
  133. else
  134. {
  135. var picker = new Picker();
  136. var left = Console.CursorLeft;
  137. var top = Console.CursorTop;
  138. var pIdx = listArgs.IndexOf("-p");
  139. picker.Path = listArgs[pIdx + 1];
  140. picker.Start((value, max) =>
  141. {
  142. // progress
  143. Console.SetCursorPosition(left, top);
  144. Console.WriteLine(string.Format("提取进度:{0} / {1}", value, max));
  145. }, () =>
  146. {
  147. // complete
  148. //Console.SetCursorPosition(left, top);
  149. Console.WriteLine(string.Format("提取完成:{0}, 耗时:{1}", picker.FileCount, picker.ElapsedTime));
  150. Console.ReadLine();
  151. }, (er) =>
  152. {
  153. // error
  154. throw er;
  155. });
  156. }
  157. }
  158. //Console.SetCursorPosition
  159. Console.ReadLine();
  160. //Console.ReadKey();
  161. }
  162. catch (Exception er)
  163. {
  164. Console.WriteLine("Exception!");
  165. Console.WriteLine(er.ToString());
  166. }
  167. }
  168. private static void ShowUsage()
  169. {
  170. Console.WriteLine("usage : GameLanguagePicker.exe [-options]");
  171. Console.WriteLine("-options:");
  172. Console.WriteLine("\t[-h]\t加-h说明:控制台方式操作,否则为:可视化窗口操作;不加则默认是:可视化窗口操作");
  173. Console.WriteLine("\t[-p pathValue]\t指定要提取的路径,-p pathValue必须成对出现");
  174. //Console.ReadLine();
  175. }
  176. }
  177. }


声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号