当前位置: 首页>>代码示例>>C#>>正文


C# NamedPipeClientStream.WaitForPipeDrain方法代码示例

本文整理汇总了C#中System.IO.Pipes.NamedPipeClientStream.WaitForPipeDrain方法的典型用法代码示例。如果您正苦于以下问题:C# NamedPipeClientStream.WaitForPipeDrain方法的具体用法?C# NamedPipeClientStream.WaitForPipeDrain怎么用?C# NamedPipeClientStream.WaitForPipeDrain使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在System.IO.Pipes.NamedPipeClientStream的用法示例。


在下文中一共展示了NamedPipeClientStream.WaitForPipeDrain方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。

示例1: SendToPipe

    void SendToPipe()
    {
        byte[] buffer = ASCIIEncoding.ASCII.GetBytes ("done");
        System.IO.Pipes.NamedPipeClientStream clientStream = new System.IO.Pipes.NamedPipeClientStream ("mypipe");
        clientStream.Connect (System.TimeSpan.MaxValue.Seconds);
        clientStream.WaitForPipeDrain();
        clientStream.Write (buffer, 0, buffer.Length);

        clientStream.Flush ();
        clientStream.Dispose();
        clientStream.Close();
    }
开发者ID:Lucasvo1,项目名称:FHVGame,代码行数:12,代码来源:PipeClient.cs

示例2: Main

        private static void Main(string[] args)
        {
            try
            {
                if (args.Length > 1)
                {
                    var pipeGuid = args[0];

                    NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", pipeGuid, PipeDirection.InOut);

                    pipeClient.Connect();

                    var dlls = args.Skip(2).ToArray();

                    var nunit3ConsoleExePath = Encoding.UTF8.GetString(Convert.FromBase64String(args[1]));

                    Write(pipeClient, Discover(dlls, pipeClient, nunit3ConsoleExePath));

                    pipeClient.WaitForPipeDrain();

                    pipeClient.Close();
                }
            }
            catch (Exception ex)
            {
                var sb = new StringBuilder();

                sb.AppendLine(ex.Message);
                sb.AppendLine(ex.StackTrace);

                foreach (var arg in args)
                    sb.AppendLine(arg);

                string fileName = DateTime.Now.ToString("YYYY-MM-DD hh:mm:ss");

                Guid parsedGuid;

                if (args.Length > 0 && Guid.TryParse(args[0], out parsedGuid))
                    fileName = parsedGuid.ToString();

                try
                {
                    File.WriteAllText(fileName, sb.ToString());
                }
                catch (Exception) { }

                Console.WriteLine(sb.ToString());
            }
        }
开发者ID:pavzaj,项目名称:OpenCover.UI,代码行数:49,代码来源:Program.cs

示例3: SendMessage

        public static bool SendMessage(Command cmd)
        {
            try
            {
                using (NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", PipeServer.SERVERNAME, PipeDirection.InOut))
                {
                    // Connect to the pipe or wait until the pipe is available.
                    Log.Write("Attempting to connect to pipe: " + PipeServer.SERVERNAME);
                    pipeClient.Connect(1000);
                    Log.Write("Connected to pipe.");

                    StreamWriter sw = new StreamWriter(pipeClient);
                    {
                        sw.AutoFlush = true;

                        sw.WriteLine(cmd.ToString());
                        pipeClient.WaitForPipeDrain();

                        Log.Write("Pipe Message Sent: " + cmd.ToString());
                    }

                    StreamReader sr = new StreamReader(pipeClient);
                    {
                        string temp;
                        while ((temp = sr.ReadLine()) != null)
                        {
                            Log.Write("Pipe Message Received: " + temp);

                            if (temp == "done")
                                return true;
                            else if (temp == "failed")
                                return false;
                        }
                    }

                    sw.Close();
                    sr.Close();
                }
            }
            catch (Exception exc)
            {
                Log.Write(exc.ToString(), true);
                return false;
            }

            return false;
        }
开发者ID:francoisvdv,项目名称:PwTouch,代码行数:47,代码来源:PipeClient.cs

示例4: pipeWorker

 private void pipeWorker (object args)
 {
     try
     {
         string value = args.ToString();
         _pipeStream = new NamedPipeClientStream( ".", _pipeName, PipeDirection.Out );
         _pipeStream.Connect();
         byte[] messageBytes = Encoding.UTF8.GetBytes( value );
         _pipeStream.Write( messageBytes, 0, messageBytes.Length );
         _pipeStream.WaitForPipeDrain();
         _pipeStream.Close();
         Thread.Sleep( 5000 );
         _sendingFinished.Set();
     }
     catch
     {
     }
 }
开发者ID:humanosc,项目名称:Work,代码行数:18,代码来源:PipeClient.cs

示例5: Main

		static void Main(string[] args)
		{
			try
			{
				if (args.Length > 1)
				{
					NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", args[0], PipeDirection.InOut);
					pipeClient.Connect();
					Discover(args, pipeClient);

					pipeClient.WaitForPipeDrain();

					pipeClient.Close();
				}
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.Message);
			}
		}
开发者ID:pkelbern,项目名称:OpenCover.UI,代码行数:20,代码来源:Program.cs

示例6: RunProperMode

        public static void RunProperMode(Command command)
        {
            if (command.ContainsCommandArg("/Uninstall")) { // Are we in uninstall-mode?
                UninstallHelper uninstallHelper = new UninstallHelper();
                uninstallHelper.RunUninstall();
            } else if (command.ContainsCommandArg("-silentinstall")) {
                Globals.InPortableMode = command["-portable"].ToBool();
                Globals.IsSilentInstall = true;
                NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", "www.pmuniverse.net-installer", PipeDirection.InOut, PipeOptions.None, System.Security.Principal.TokenImpersonationLevel.Impersonation);
                pipeClient.Connect();
                Pipes.StreamString clientStream = new Pipes.StreamString(pipeClient);
                Globals.SilentInstallCommunicationPipeStream = clientStream;
                Globals.SilentInstallCommunicationPipe = pipeClient;
                installWaitEvent = new ManualResetEvent(false);
                Installer installer = new Installer(command);
                installer.InstallComplete += new EventHandler(installer_InstallComplete);
                installer.Install(clientStream);

                installWaitEvent.WaitOne();

                clientStream.WriteString("[InstallComplete]");

                pipeClient.WaitForPipeDrain();
                pipeClient.Close();

                System.Environment.Exit(0);
            } else {
                // There are no special command line arguments, run the installer in install mode
                // Let's check if we elevated ourselves
                if (!Globals.CommandLine.ContainsCommandArg("/skipwelcome") || !VistaSecurity.IsAdmin()) {
                    // Show the welcome page
                    PageManager.ActivePage = new Pages.pgeWelcome();
                } else {
                    // Show the license page
                    PageManager.ActivePage = new Pages.pgeLicense();
                }
            }
        }
开发者ID:ChaotixBluix,项目名称:Installer,代码行数:38,代码来源:MaintenanceHelper.cs

示例7: IfAlreadyRunningDoSwitch

        /// <summary>
        /// check if given exe already running or not
        /// </summary>
        /// <returns>returns true if already running</returns>
        public static bool IfAlreadyRunningDoSwitch()
        {
            string strLoc = Assembly.GetExecutingAssembly().Location;
            FileSystemInfo fileInfo = new FileInfo(strLoc);
            string sExeName = fileInfo.Name;
            bool bCreatedNew = false;

            _mutex = new Mutex(true, "Global\\"+sExeName, out bCreatedNew);
            if (bCreatedNew)
            {
                _mutex.ReleaseMutex();
                _PipeThread = new Thread(new System.Threading.ThreadStart(PipeThread));
                _PipeThread.Name = "Pipe";
                _PipeThread.Start();

                Application.ApplicationExit += new EventHandler(Application_ApplicationExit);
            }
            else
            {
                using (NamedPipeClientStream pipeStream = new NamedPipeClientStream(NamedPipeName))
                {
                    // The connect function will indefinitely wait for the pipe to become available
                    // If that is not acceptable specify a maximum waiting time (in ms)
                    pipeStream.Connect();

                    using (StreamWriter sw = new StreamWriter(pipeStream))
                    {
                        string[] Args = Environment.GetCommandLineArgs();

                        sw.AutoFlush = true;
                        sw.WriteLine(Args.Length >= 2 ? Args[1] : string.Empty);
                        pipeStream.WaitForPipeDrain();
                    }
                }
            }

            return !bCreatedNew;
        }
开发者ID:Heimiko,项目名称:NzbSearcher,代码行数:42,代码来源:SingleApplication.cs

示例8: Init

 private void Init()
 {
     if (PipeExists(PIPENAME)) {
         using (NamedPipeClientStream client = new NamedPipeClientStream(PIPENAME)) {
             try {
                 client.Connect(2000);
                 client.Write(SHOW, 0, SHOW.Length);
                 client.WaitForPipeDrain();
             }
             catch {
             }
         }
         Environment.Exit(1);
     }
     using (NamedPipeServerStream server = new NamedPipeServerStream(PIPENAME)) {
         while (true) {
             server.WaitForConnection();
             byte[] data = new byte[255];
             int count = server.Read(data, 0, data.Length);
             string msg = Encoding.ASCII.GetString(data, 0, count).ToUpper();
             if (msg.Equals("SHOW")) {
                 main.Invoke(new MethodInvoker(delegate
                 {
                     main.Show();
                     main.WindowState = FormWindowState.Normal;
                 }));
             }
             else if (msg.Equals("BREAK")) {
                 break;
             }
             else if (msg.Equals("EXIT")) {
                 Environment.Exit(0);
             }
             server.Disconnect();
         }
     }
 }
开发者ID:pcluddite,项目名称:WinMonkey,代码行数:37,代码来源:PipeWatcher.cs

示例9: NotifYUser

        public static void NotifYUser(Settings settings, SettingsPrinter printer, List<InkLevel> inkLevel)
        {
            string title = "Printer Ink is at low level";
            string body = "";
            //body += title + "\n\r\n\r";
            body += "Printer Details:\n\r";
            body += printer.Name + "\n\r";

            foreach (var level in inkLevel)
            {
                if (level.Value <= printer.Level)
                {
                    body += string.Format("{0} - {1:00%}\n\r", level.Name, level.Value);
                }
            }
            body += "\n\r\n\r*****";

            try
            {
                var pipeClient = new NamedPipeClientStream("InkMonPipe");

                pipeClient.Connect(3000);

                if (pipeClient.IsConnected)
                {
                    var buf = Encoding.ASCII.GetBytes(body);
                    pipeClient.Write(buf, 0, buf.Length);
                    pipeClient.WaitForPipeDrain();
                    pipeClient.Close();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
开发者ID:SameerOmar,项目名称:InkMon,代码行数:36,代码来源:UserInterfaceHelper.cs

示例10: OnStartup

        protected override void OnStartup(StartupEventArgs e)
        {
            if (e.Args == null)
                _exeArguments = new string[0];
            else
                _exeArguments = e.Args;

            AppDomain.CurrentDomain.UnhandledException += UncaughtThreadException;
            DispatcherUnhandledException += UncaughtUiThreadException;

            using (WindowsIdentity identity = WindowsIdentity.GetCurrent())
                _pipeName = String.Format("DayZeroLauncher_{{{0}}}_Instance", identity.User);

            bool secondInstance = false;
            using (var pipeConn = new NamedPipeClientStream(".", _pipeName, PipeDirection.Out))
            {
                try
                {
                    const int timeoutMs = 100;
                    pipeConn.Connect(timeoutMs);
                    pipeConn.ReadMode = PipeTransmissionMode.Message;

                    string queryString = GetQueryParams();
                    if (!string.IsNullOrEmpty(queryString))
                    {
                        byte[] bytesToWrite = Encoding.UTF8.GetBytes(queryString);
                        pipeConn.Write(bytesToWrite, 0, bytesToWrite.Length);
                        pipeConn.WaitForPipeDrain();
                    }
                    secondInstance = true;

                    pipeConn.Close();
                }
                catch (TimeoutException)
                {
                }
            }

            if (secondInstance) //already sent message to pipe
            {
                Shutdown();
                return;
            }

            //we are the only app, start the server
            StartPipeServer();

            LocalMachineInfo.Current.Update();
            base.OnStartup(e);
        }
开发者ID:rajkosto,项目名称:DayZeroLauncher,代码行数:50,代码来源:App.xaml.cs

示例11: SendMessageAsync

        public static Task<bool> SendMessageAsync(object message, string pipeName, bool wait = true)
        {
            return Task.Run<bool>(new Func<bool>(() =>
               {
                   try
                   {
                       using (NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", pipeName, PipeDirection.Out, PipeOptions.None, TokenImpersonationLevel.None))
                       {
                           using (MemoryStream ms = new MemoryStream())
                           {
                               if (wait)
                               {
                                   int i = 0;
                                   for (; i != 20; i++)
                                   {
                                       if (!NamedPipeDoesNotExist(pipeName)) break;
                                       Thread.Sleep(50);
                                   }
                                   if (i == 20) return false;
                               }
                               if (NamedPipeDoesNotExist(pipeName)) return false;

                               pipeClient.Connect(10);

                               BinaryFormatter bf = new BinaryFormatter();

                               bf.Serialize(ms, message);
                               ms.Seek(0, SeekOrigin.Begin);
                               ms.CopyTo(pipeClient);
                               pipeClient.Flush();

                               pipeClient.WaitForPipeDrain();
                           }
                       }
                       return true;
                   }
                   catch (Exception e)
                   {
                       Logging.LogException(e);
                       return false;
                   }
               }));
        }
开发者ID:YashMaster,项目名称:GestureSign,代码行数:43,代码来源:NamedPipe.cs

示例12: HandleCommandLine

        public static void HandleCommandLine (int connectTimeoutMs = 2500) {
            var commandLineArgs = Environment.GetCommandLineArgs();
            if ((commandLineArgs.Length == 3) && (commandLineArgs[1] == "--buildSolution")) {
                try {
                    var jss = new JavaScriptSerializer {
                        MaxJsonLength = 1024 * 1024 * 64
                    };

                    var pipeId = commandLineArgs[2];

                    using (var pipe = new NamedPipeClientStream(pipeId)) {
                        pipe.Connect(connectTimeoutMs);

                        using (var sr = new StreamReader(pipe))
                        using (var sw = new StreamWriter(pipe)) {
                            var argsJson = sr.ReadLine();
                            var argsDict = jss.Deserialize<Dictionary<string, object>>(argsJson);

                            var buildResult = Build(
                                (string)argsDict["solutionFile"],
                                (string)argsDict["buildConfiguration"],
                                (string)argsDict["buildPlatform"],
                                (string)argsDict["buildTarget"],
                                (string)argsDict["logVerbosity"],
                                true
                            );

                            var resultJson = jss.Serialize(buildResult);

                            sw.WriteLine(resultJson);
                            sw.Flush();
                            pipe.Flush();
                            pipe.WaitForPipeDrain();
                        }
                    }
                } catch (Exception exc) {
                    Console.Error.WriteLine(exc.ToString());
                    Environment.Exit(1);
                }

                Environment.Exit(0);
            }
        }
开发者ID:sq,项目名称:JSIL,代码行数:43,代码来源:SolutionBuilder.cs

示例13: Main

        static void Main(string[] args)
        {
            // get application GUID as defined in AssemblyInfo.cs
            string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value.ToString();

            // unique id for global mutex - Global prefix means it is global to the machine
            string mutexId = string.Format("Global\\{{{0}}}", appGuid);

            using (var mutex = new Mutex(false, mutexId))
            {
                // edited by Jeremy Wiebe to add example of setting up security for multi-user usage
                // edited by 'Marc' to work also on localized systems (don't use just "Everyone")
                var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow);
                var securitySettings = new MutexSecurity();
                securitySettings.AddAccessRule(allowEveryoneRule);
                mutex.SetAccessControl(securitySettings);

                // edited by acidzombie24
                var hasHandle = false;
                try
                {
                    try
                    {
                        // note, you may want to time out here instead of waiting forever
                        // edited by acidzombie24
                        // mutex.WaitOne(Timeout.Infinite, false);
                        hasHandle = mutex.WaitOne(500, false);
                        if (hasHandle == false)
                        {
                            if (args.Count() == 1)
                            {
                                if (args[0] == "update")
                                {
                                    //TODO: send message to pipe
                                    NamedPipeClientStream pipe = new NamedPipeClientStream(".", "NXTLibTesterGUI_forceupdatepipe", PipeDirection.Out);
                                    StreamWriter sw = new StreamWriter(pipe);
                                    pipe.Connect();
                                    sw.AutoFlush = true;
                                    sw.WriteLine("Force Update Now!");
                                    pipe.WaitForPipeDrain();
                                    pipe.Dispose();
                                }
                                return;
                            }

                            MessageBox.Show("Application already running!  Close the other instance and try again.",
                                   "Application Running", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            return;
                        }
                    }
                    catch (AbandonedMutexException)
                    {
                        // Log the fact the mutex was abandoned in another process, it will still get aquired
                        hasHandle = true;
                    }

                    FindNXT.updatewaiting = false;
                    if (args.Count() == 1)
                    {
                        if (args[0] == "update")
                        {
                            FindNXT.updatewaiting = true;
                        }
                    }

                    // Perform your work here.
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new FindNXT());
                }
                finally
                {
                    // edited by acidzombie24, added if statemnet
                    if (hasHandle)
                        mutex.ReleaseMutex();
                }
            }
        }
开发者ID:smo-key,项目名称:NXTLib,代码行数:78,代码来源:Program.cs

示例14: QvxCommandWorker

        private void QvxCommandWorker()
        {
            try
            {
                if (pipeName == null) return;

                object state = new object();
                object connection = null;

                using (NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut))
                {
                    var buf = new byte[4];
                    var buf2 = new byte[4];
                    Int32 count = 0;
                    Int32 datalength = 0;
                    pipeClient.Connect(1000);
                    while (pipeClient.IsConnected)
                    {
                        try
                        {
                            #region Get QvxRequest
                            var iar = pipeClient.BeginRead(buf, 0, 4, null, state);
                            while (!iar.IsCompleted) Thread.Sleep(1);
                            count = pipeClient.EndRead(iar);
                            if (count != 4) throw new Exception("Invalid Count Length");
                            buf2[0] = buf[3];
                            buf2[1] = buf[2];
                            buf2[2] = buf[1];
                            buf2[3] = buf[0];
                            datalength = BitConverter.ToInt32(buf2, 0);
                            var data = new byte[datalength];
                            count = pipeClient.Read(data, 0, datalength);
                            if (count != datalength) throw new Exception("Invalid Data Length");

                            var sdata = ASCIIEncoding.ASCII.GetString(data);
                            sdata = sdata.Replace("\0", "");
                            QvxRequest request;
                            try
                            {
                                request = QvxRequest.Deserialize(sdata);

                            }
                            catch (Exception ex)
                            {
                                logger.Error(ex);
                                throw ex;
                            }
                            request.QVWindow = QVWindow;
                            request.Connection = connection;
                            #endregion

                            #region Handle QvxRequets
                            QvxReply result = null;
                            if (HandleQvxRequest != null)
                                result = HandleQvxRequest(request);

                            if (result == null)
                                result = new QvxReply() { Result = QvxResult.QVX_UNKNOWN_ERROR };
                            #endregion

                            #region Send QvxReply
                            sdata = "    " + result.Serialize() + "\0";
                            datalength = sdata.Length - 4;
                            buf2 = ASCIIEncoding.ASCII.GetBytes(sdata);
                            buf = BitConverter.GetBytes(datalength);
                            buf2[0] = buf[3];
                            buf2[1] = buf[2];
                            buf2[2] = buf[1];
                            buf2[3] = buf[0];
                            pipeClient.Write(buf2, 0, buf2.Length);
                            pipeClient.WaitForPipeDrain();
                            #endregion

                            #region Handle result States
                            if (result.Terminate)
                                close = true;
                            if (result.Connection != null)
                                connection = result.Connection;
                            if (result.SetConnectionNULL)
                                connection = null;
                            #endregion
                        }
                        catch (Exception ex)
                        {
                            logger.Error(ex);
                            Thread.Sleep(500);
                            close = true;
                        }

                        if (close)
                        {
                            close = false;
                            pipeClient.Close();
                        }

                        Thread.Sleep(5);
                    }
                }
                running = false;
            }
//.........这里部分代码省略.........
开发者ID:TonyWu,项目名称:QvxLib,代码行数:101,代码来源:QvxCommandClient.cs

示例15: ClientPInvokeChecks

    public static async Task ClientPInvokeChecks()
    {
        using (NamedPipeServerStream server = new NamedPipeServerStream("foo", PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.None, 4096, 4096))
        {
            using (NamedPipeClientStream client = new NamedPipeClientStream(".", "foo", PipeDirection.Out))
            {
                Task serverTask = DoServerOperationsAsync(server);
                client.Connect();

                Assert.False(client.CanRead);
                Assert.False(client.CanSeek);
                Assert.False(client.CanTimeout);
                Assert.True(client.CanWrite);
                Assert.False(client.IsAsync);
                Assert.True(client.IsConnected);
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    Assert.Equal(0, client.OutBufferSize);
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    Assert.True(client.OutBufferSize > 0);
                }
                else
                {
                    Assert.Throws<PlatformNotSupportedException>(() => client.OutBufferSize);
                }
                Assert.Equal(PipeTransmissionMode.Byte, client.ReadMode);
                Assert.NotNull(client.SafePipeHandle);
                Assert.Equal(PipeTransmissionMode.Byte, client.TransmissionMode);

                client.Write(new byte[] { 123 }, 0, 1);
                await client.WriteAsync(new byte[] { 124 }, 0, 1);
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    client.WaitForPipeDrain();
                }
                else
                {
                    Assert.Throws<PlatformNotSupportedException>(() => client.WaitForPipeDrain());
                }
                client.Flush();

                await serverTask;
            }
        }

        using (NamedPipeServerStream server = new NamedPipeServerStream("foo", PipeDirection.Out))
        {
            using (NamedPipeClientStream client = new NamedPipeClientStream(".", "foo", PipeDirection.In))
            {
                Task serverTask = DoServerOperationsAsync(server);
                client.Connect();

                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    Assert.Equal(0, client.InBufferSize);
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    Assert.True(client.InBufferSize > 0);
                }
                else
                {
                    Assert.Throws<PlatformNotSupportedException>(() => client.InBufferSize);
                }
                byte[] readData = new byte[] { 0, 1 };
                Assert.Equal(1, client.Read(readData, 0, 1));
                Assert.Equal(1, client.ReadAsync(readData, 1, 1).Result);
                Assert.Equal(123, readData[0]);
                Assert.Equal(124, readData[1]);

                await serverTask;
            }
        }
    }
开发者ID:nuskarthik,项目名称:corefx,代码行数:76,代码来源:NamedPipesSimpleTest.cs


注:本文中的System.IO.Pipes.NamedPipeClientStream.WaitForPipeDrain方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。