最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#中進程的掛起與恢復

 更新時間:2017年03月27日 10:15:17   作者:楚人無衣  
這篇文章主要介紹了C#中進程的掛起與恢復操作方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下

1. 源起:

仍然是模塊化編程所引發(fā)的需求。產(chǎn)品經(jīng)理難伺候,女產(chǎn)品經(jīng)理更甚之~:p

純屬戲謔,技術方案與產(chǎn)品經(jīng)理無關,芋頭莫怪!

VCU10項目重構,要求各功能模塊以獨立進程方式實現(xiàn),比如:音視頻轉換模塊,若以獨立進程方式實現(xiàn),如何控制其暫停、繼續(xù)等功能呢?

線程可以Suspend、Resume,c#內(nèi)置的Process沒有此類方法,咋整?

山窮水盡疑無路,柳暗花明又一村。情到濃時清轉薄,此情可待成追憶!

前篇描述了進程間數(shù)據(jù)傳遞方法,此篇亦以示例演示其間控制與數(shù)據(jù)交互方法。

 2、未公開的API函數(shù):NtSuspendProcess、NtResumeProcess

此類函數(shù)在MSDN中找不到。

思其原因,概因它們介于Windows API和 內(nèi)核API之間,威力不容小覷。怕二八耙子程序員濫用而引發(fā)事端,因此密藏。

其實還有個NtTerminateProcess,因Process有Kill方法,因此可不用。

但再隱秘的東西,只要有價值,都會被人給翻出來,好酒不怕巷子深么!

好,基于其,設計一個進程管理類,實現(xiàn)模塊化編程之進程間控制這個需求。

3、ProcessMgr

直上代碼吧,封裝一個進程管理單元:

public static class ProcessMgr
 {
  /// <summary>
  /// The process-specific access rights.
  /// </summary>
  [Flags]
  public enum ProcessAccess : uint
  {
   /// <summary>
   /// Required to terminate a process using TerminateProcess.
   /// </summary>
   Terminate = 0x1,
   /// <summary>
   /// Required to create a thread.
   /// </summary>
   CreateThread = 0x2,
   /// <summary>
   /// Undocumented.
   /// </summary>
   SetSessionId = 0x4,
   /// <summary>
   /// Required to perform an operation on the address space of a process (see VirtualProtectEx and WriteProcessMemory).
   /// </summary>
   VmOperation = 0x8,
   /// <summary>
   /// Required to read memory in a process using ReadProcessMemory.
   /// </summary>
   VmRead = 0x10,
   /// <summary>
   /// Required to write to memory in a process using WriteProcessMemory.
   /// </summary>
   VmWrite = 0x20,
   /// <summary>
   /// Required to duplicate a handle using DuplicateHandle.
   /// </summary>
   DupHandle = 0x40,
   /// <summary>
   /// Required to create a process.
   /// </summary>
   CreateProcess = 0x80,
   /// <summary>
   /// Required to set memory limits using SetProcessWorkingSetSize.
   /// </summary>
   SetQuota = 0x100,
   /// <summary>
   /// Required to set certain information about a process, such as its priority class (see SetPriorityClass).
   /// </summary>
   SetInformation = 0x200,
   /// <summary>
   /// Required to retrieve certain information about a process, such as its token, exit code, and priority class (see OpenProcessToken, GetExitCodeProcess, GetPriorityClass, and IsProcessInJob).
   /// </summary>
   QueryInformation = 0x400,
   /// <summary>
   /// Undocumented.
   /// </summary>
   SetPort = 0x800,
   /// <summary>
   /// Required to suspend or resume a process.
   /// </summary>
   SuspendResume = 0x800,
   /// <summary>
   /// Required to retrieve certain information about a process (see QueryFullProcessImageName). A handle that has the PROCESS_QUERY_INFORMATION access right is automatically granted PROCESS_QUERY_LIMITED_INFORMATION.
   /// </summary>
   QueryLimitedInformation = 0x1000,
   /// <summary>
   /// Required to wait for the process to terminate using the wait functions.
   /// </summary>
   Synchronize = 0x100000
  }
  [DllImport("ntdll.dll")]
  private static extern uint NtResumeProcess([In] IntPtr processHandle);
  [DllImport("ntdll.dll")]
  private static extern uint NtSuspendProcess([In] IntPtr processHandle);
  [DllImport("kernel32.dll", SetLastError = true)]
  private static extern IntPtr OpenProcess(
   ProcessAccess desiredAccess,
   bool inheritHandle,
   int processId);
  [DllImport("kernel32.dll", SetLastError = true)]
  [return: MarshalAs(UnmanagedType.Bool)]
  private static extern bool CloseHandle([In] IntPtr handle);
  public static void SuspendProcess(int processId)
  {
   IntPtr hProc = IntPtr.Zero;
   try
   {
    // Gets the handle to the Process
    hProc = OpenProcess(ProcessAccess.SuspendResume, false, processId);
    if (hProc != IntPtr.Zero)
     NtSuspendProcess(hProc);
   }
   finally
   {
    // Don't forget to close handle you created.
    if (hProc != IntPtr.Zero)
     CloseHandle(hProc);
   }
  }
  public static void ResumeProcess(int processId)
  {
   IntPtr hProc = IntPtr.Zero;
   try
   {
    // Gets the handle to the Process
    hProc = OpenProcess(ProcessAccess.SuspendResume, false, processId);
    if (hProc != IntPtr.Zero)
     NtResumeProcess(hProc);
   }
   finally
   {
    // Don't forget to close handle you created.
    if (hProc != IntPtr.Zero)
     CloseHandle(hProc);
   }
  }
 }

4、進程控制

我權且主進程為宿主,它通過Process類調用子進程,得其ID,以此為用。其調用代碼為:

 private void RunTestProcess(bool hidden = false)
  {
   string appPath = Path.GetDirectoryName(Application.ExecutablePath);
   string testAppPath = Path.Combine(appPath, "TestApp.exe");
   var pi = new ProcessStartInfo();
   pi.FileName = testAppPath;
   pi.Arguments = this.Handle.ToString();
   pi.WindowStyle = hidden ? ProcessWindowStyle.Hidden : ProcessWindowStyle.Normal;
   this.childProcess = Process.Start(pi);
   txtInfo.Text = string.Format("子進程ID:{0}\r\n子進程名:{1}", childProcess.Id, childProcess.ProcessName);
   ...
  }

控制代碼為:    

private void btnWork_Click(object sender, EventArgs e)
  {
   if (this.childProcess == null || this.childProcess.HasExited)
    return;
   if ((int)btnWork.Tag == 0)
   {
    btnWork.Tag = 1;
    btnWork.Text = "恢復";
    ProcessMgr.SuspendProcess(this.childProcess.Id);
   }
   else
   {
    btnWork.Tag = 0;
    btnWork.Text = "掛起";
    ProcessMgr.ResumeProcess(this.childProcess.Id);
   }
  }

子進程以一定時器模擬其工作,向主進程拋進度消息:

 private void timer_Tick(object sender, EventArgs e)
  {
   if (progressBar.Value < progressBar.Maximum)
    progressBar.Value += 1;
   else
    progressBar.Value = 0;
   if (this.hostHandle != IntPtr.Zero)
    SendMessage(this.hostHandle, WM_PROGRESS, 0, progressBar.Value);
  }

代碼量就這么的少,簡單吧……

5、效果圖:

為示例,做了兩個圖,其一為顯示子進程,其二為隱藏子進程。

實際項目調用獨立進程模塊,是以隱藏方式調用的,以宿主展示其處理進度,如此圖:

后記:

擴展思路,一些優(yōu)秀的開源工具,如youtube_dl、ffmpeg等,都以獨立進程方式存在,且可通過CMD管理通信。

以此進程控制原理,可以基于這些開源工具,做出相當不錯的GUI工具出來。畢竟相對于強大的命令行,人們還是以簡單操作為方便。

相關文章

  • C#并行編程之信號量

    C#并行編程之信號量

    這篇文章介紹了C#并行編程之信號量,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • Unity3D UI Text得分數(shù)字增加的實例代碼

    Unity3D UI Text得分數(shù)字增加的實例代碼

    這篇文章主要介紹了Unity3D UI Text得分數(shù)字增加方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • C# 格式化字符首字母大寫的方法

    C# 格式化字符首字母大寫的方法

    這篇文章介紹了C# 格式化字符首字母大寫的方法,有需要的朋友可以參考一下
    2013-08-08
  • C# ManualResetEvent用法詳解

    C# ManualResetEvent用法詳解

    這篇文章主要介紹了C# ManualResetEvent用法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-12-12
  • C# Lambda 知識回顧

    C# Lambda 知識回顧

    本文主要介紹了C#中Lambda的相關知識。具有一定的參考價值,下面跟著小編一起來看下吧
    2017-01-01
  • 基于C#對用戶密碼使用MD5加密與解密

    基于C#對用戶密碼使用MD5加密與解密

    C#中常涉及到對用戶密碼的加密于解密的算法,其中使用MD5加密是最常見的的實現(xiàn)方式。本文總結了通用的算法并結合了自己的一點小經(jīng)驗,分享給大家
    2015-12-12
  • C#獲取數(shù)組中最大最小值的方法

    C#獲取數(shù)組中最大最小值的方法

    這篇文章主要介紹了C#獲取數(shù)組中最大最小值的方法,本文直接給出實例代碼,需要的朋友可以參考下
    2015-06-06
  • C#?連接本地數(shù)據(jù)庫的實現(xiàn)示例

    C#?連接本地數(shù)據(jù)庫的實現(xiàn)示例

    本文主要介紹了C#?連接本地數(shù)據(jù)庫的實現(xiàn)示例,文中根據(jù)實例編碼詳細介紹的十分詳盡,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • C#對二進制數(shù)據(jù)進行base64編碼的方法

    C#對二進制數(shù)據(jù)進行base64編碼的方法

    這篇文章主要介紹了C#對二進制數(shù)據(jù)進行base64編碼的方法,涉及C#中Convert.ToBase64String用法技巧,需要的朋友可以參考下
    2015-04-04
  • 設計模式速記

    設計模式速記

    本文主要介紹了設計模式:創(chuàng)建型模式;結構型模式;行為型模式三大類。具有很好的參考價值,相信有助于大家記憶與學習,下面跟著小編一起來看下吧
    2017-02-02

最新評論

金寨县| 老河口市| 邹城市| 枞阳县| 阳朔县| 蓝山县| 万载县| 漳州市| 奉化市| 新晃| 平乡县| 雷山县| 阿合奇县| 绥阳县| 滁州市| 古丈县| 昂仁县| 云浮市| 堆龙德庆县| 宜城市| 无为县| 高安市| 灵璧县| 江都市| 青浦区| 扎兰屯市| 新泰市| 芦溪县| 山东省| 石林| 辽阳市| 鄂伦春自治旗| 大连市| 斗六市| 嘉义市| 锡林郭勒盟| 社旗县| 邢台县| 湛江市| 大连市| 什邡市|