zoukankan      html  css  js  c++  java
  • 再谈System.ComponentModel.Win32Exception

    如名称的Win32部分所示System.ComponentModel.Win32Exception仅在处理传统样式的应用程序或代码时发生-应用程序必须调用直接操作系统调用,例如尝试执行其他应用程序。在本文中,我们将深入探讨System.ComponentModel.Win32异常。更详细地说,包括它在.NET异常层次结构中的位置。我们还将深入研究一些函数C#代码示例,以更好地说明如何System.ComponentModel.Win32Exceptions可能会在自己的编码中被抛出!

    要点

    • 所有 .NET exceptions 继承自 System.Exception base class, 或者继承自inherited class.
    • System.SystemException 继承自 System.Exception class.
    • System.Runtime.InteropServices.ExternalException 直接继承自System.SystemException.
    • 最后, System.ComponentModel.Win32Exception 继承自 System.Runtime.InteropServices.ExternalException.

    什么时候用它呢?

    这个System.ComponentModel.Win32异常是在使用内部win32样式的操作系统调用时发生错误时在.NET应用程序中发生的最基本的异常类型。这些问题可能不同,从无效路径和文件找不到错误到网络地址问题和资源管理问题。因为System.ComponentModel.Win32Exceptions是旧形式异常的包装器,您可能遇到的每个可能的错误都有自己的NativeErrorCode属性值,它是一个32位整数,引用与引发的异常相关联的Win32错误代码值。
    我们的示例代码开始。整个代码段如下所示,之后我们将更详细地讨论它:

    using System.Diagnostics;
    using Utility;
    
    namespace Airbrake.ComponentModel.Win32Exception
    {
        class Program
        {
            static void Main(string[] args)
            {
                StartProcessFromPath("c:/windows/notepad.exe");
                Logging.LineSeparator();
                StartProcessFromPath("c:/windows/invalid.exe");
            }
    
            static void StartProcessFromPath(string path)
            {
                try
                {
                    // Create a new process with StartInfo.FileName set to provided path.
                    var process = new Process { StartInfo = { FileName = path } };
                    // Attempt to start the process using provided executable path.
                    var success = process.Start();
                    if (success)
                    {
                        Logging.Log($"Successfully launched '{process.ProcessName.ToString()}' process!");
                        // Sleep for two seconds to allow time for window to be shown.
                        System.Threading.Thread.Sleep(2000);
                        // Kill process.
                        process.Kill();
                        Logging.Log($"Killed '{process.ProcessName.ToString()}' process.");
                    }
                    else
                    {
                        // This code never executes since we're catching
                        // an exception from the process.Start() invocation line.
                    }
                }
                catch (System.ComponentModel.Win32Exception exception)
                {
                    // Indicate failure to start.
                    Logging.Log($"Unable to start process with executable path '{path}'.");
                    // Output caught exception.
                    Logging.Log(exception);
                    Logging.Log($"Native Win32 Error Code: {exception.NativeErrorCode}");
                }
            }
        }
    }
    
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Reflection;
    using System.Text;
    
    namespace Utility
    {
        /// <summary>
        /// Houses all logging methods for various debug outputs.
        /// </summary>
        public static class Logging
        {
            /// <summary>
            /// Outputs to <see cref="System.Diagnostics.Debug.WriteLine"/> if DEBUG mode is enabled,
            /// otherwise uses standard <see cref="Console.WriteLine"/>.
            /// </summary>
            /// <param name="value">Value to be output to log.</param>
            public static void Log(string value)
            {
    #if DEBUG
                Debug.WriteLine(value);
    #else
                Console.WriteLine(value);
    #endif
            }
    
            /// <summary>
            /// When <see cref="Exception"/> parameter is passed, modifies the output to indicate
            /// if <see cref="Exception"/> was expected, based on passed in `expected` parameter.
            /// <para>Outputs the full <see cref="Exception"/> type and message.</para>
            /// </summary>
            /// <param name="exception">The <see cref="Exception"/> to output.</param>
            /// <param name="expected">Boolean indicating if <see cref="Exception"/> was expected.</param>
            public static void Log(Exception exception, bool expected = true)
            {
                string value = $"[{(expected ? "EXPECTED" : "UNEXPECTED")}] {exception.ToString()}: {exception.Message}";
    #if DEBUG
                Debug.WriteLine(value);
    #else
                Console.WriteLine(value);
    #endif
            }
    
            /// <summary>
            /// Outputs a dashed line separator to <see cref="System.Diagnostics.Debug.WriteLine"/> 
            /// if DEBUG mode is enabled, otherwise uses standard <see cref="Console.WriteLine"/>.
            /// </summary>
            public static void LineSeparator()
            {
    #if DEBUG
                Debug.WriteLine(new string('-', 20));
    #else
                Console.WriteLine(new string('-', 20));
    #endif
            }
        }
    }

    我们的大多数示例都发生在StartProcessFromPath()方法中,该方法接受一个应指向可执行文件的字符串路径值。然后,我们实例化一个新进程,并尝试用.start()方法启动它。.Start()方法返回一个布尔值,指示尝试是否成功,因此我们只需使用该布尔值来执行一些额外的逻辑,例如将一些信息输出到日志以指示成功或失败,以及一个小的Sleep()周期,以便我们有时间查看新启动的窗口(如果适用)。最后我们用.Kill()方法终止进程。

    static void StartProcessFromPath(string path)
    {
        try
        {
            // Create a new process with StartInfo.FileName set to provided path.
            var process = new Process { StartInfo = { FileName = path } };
            // Attempt to start the process using provided executable path.
            var success = process.Start();
            if (success)
            {
                Logging.Log($"Successfully launched '{process.ProcessName.ToString()}' process!");
                // Sleep for two seconds to allow time for window to be shown.
                System.Threading.Thread.Sleep(2000);
                // Kill process.
                process.Kill();
                Logging.Log($"Killed '{process.ProcessName.ToString()}' process.");
            }
            else
            {
                // This code never executes since we're catching
                // an exception from the process.Start() invocation line.
            }
        }
        catch (System.ComponentModel.Win32Exception exception)
        {
            // Indicate failure to start.
            Logging.Log($"Unable to start process with executable path '{path}'.");
            // Output caught exception.
            Logging.Log(exception);
            Logging.Log($"Native Win32 Error Code: {exception.NativeErrorCode}");
        }
    }

    为了说明成功和失败,我们的Main()方法尝试启动notepad.exe 以及invalid.exe:

    static void Main(string[] args)
    {
        StartProcessFromPath("c:/windows/notepad.exe");
        Logging.LineSeparator();
        StartProcessFromPath("c:/windows/invalid.exe");
    }
    正如您可能怀疑的那样,第一个StartProcessFromPath()调用工作正常,我们看到记事本窗口弹出两秒钟,然后由于Kill()方法调用而消失。我们还可以从控制台日志输出中获得成功确认:
    Successfully launched 'notepad' process!
    Killed 'notepad' process.

    另一方面,我们的第二个StartProcessFromPath()调用invalid.exe失败并抛出System.ComponentModel.Win32Exception我们的方式:

    Unable to start process with executable path: 'c:/windows/invalid.exe'.
    [EXPECTED] System.ComponentModel.Win32Exception (0x80004005): The system cannot find the file specified
    Native Win32 Error Code: 2
    我们还确保输出相关的Win32错误代码,方法是在System.ComponentModel.Win32Exception,因此我们可以看到win32错误代码是:2。如果我们回到Win32错误代码表,我们会发现2的值(即0x00000002)对应于Error_FILE_NOT_FOUND枚举,并说明系统找不到指定的文件。当然,这个描述与System.ComponentModel.Win32Exception输出我们收到的消息!
  • 相关阅读:
    WordPress“无法将上传的文件移动至wp-content/uploads/”的解决办法
    npm安装less和less-loadernpm或者stylus和stylus-loader
    vue-cli脚手架安装
    JavaScript 中的回调函数
    css同时满足两个类名才有效果的写法
    jQuery对象与JS原生对象之间的转换
    css3在动画完成后执行事件
    5秒让你的View变3D,ThreeDLayout使用和实现
    给大家安利一个学习angular2的视频网站
    JAVA中的常量定义在class中还是interface中比较合理?
  • 原文地址:https://www.cnblogs.com/yilang/p/13225190.html
Copyright © 2011-2022 走看看