激活并刷新已运行例程 --> EXE

本文介绍如何在程序入口处控制运行一次EXE,并在再次启动时激活并刷新已运行例程,通过启动参数传递数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

本文介绍如何在程序入口处控制运行一次EXE,再次启动只会激活并刷新已运行例程。
刷新数据通过启动参数来传递,本文启动参数传递的是一个文件路径,详看代码:

 

入口处:

  1. static class Program  
  2. {  
  3.     /// <summary>   
  4.     /// 应用程序的主入口点。   
  5.     /// </summary>   
  6.     [STAThread]  
  7.     static void Main( string[] args )  
  8.     {  
  9.         Application.EnableVisualStyles( );  
  10.         Application.SetCompatibleTextRenderingDefault( false );  
  11.   
  12.         //通过启动参数获取文件路径   
  13.         string filePath = string.Empty;  
  14.         if ( args.Length > 0 )  
  15.         {  
  16.             filePath = args[0];  
  17.             for ( int i = 1 ; i < args.Length ; i++ )  
  18.             {  
  19.                 filePath += string.Format( " {0}" , args[i] );  
  20.             }  
  21.         }  
  22.         //获取当前例程   
  23.         Process instance = RunningInstance( );  
  24.         if ( instance == null ) //第一次启动   
  25.         {  
  26.             if ( string.IsNullOrEmpty( filePath ) )  
  27.             {  
  28.                 Application.Run( new FrmMain( "default path.." ) );  
  29.             }  
  30.             else  
  31.             {  
  32.                 Application.Run( new FrmMain( filePath ) );  
  33.             }  
  34.         }  
  35.         else //已有例程在运行,激活并传送数据   
  36.         {  
  37.             if ( !string.IsNullOrEmpty( filePath ) )  
  38.             {  
  39.                 IntPtr strPtr = Marshal.StringToHGlobalAnsi( filePath );  
  40.                 COPYDATASTRUCT copyData;  
  41.                 copyData.dwData = 0;  
  42.                 copyData.cbData = (uint)System.Text.Encoding.Default.GetByteCount(  
  43.                     filePath.ToCharArray( ) , 0 , filePath.Length );  
  44.                 copyData.lpData = strPtr;  
  45.                 IntPtr ptr = Marshal.AllocHGlobal( (IntPtr)( Marshal.SizeOf( copyData ) ) );  
  46.                 Marshal.StructureToPtr( copyData , ptr , true );  
  47.                 //给主窗体发送消息,传递新文件路径   
  48.                 FrmMain.SendMessage( instance.MainWindowHandle , FrmMain.WM_COPYPATH , -1 , (int)ptr );  
  49.             }  
  50.             HandleRunningInstance( instance ); //激活已运行例程   
  51.         }  
  52.     }  
  53.   
  54.     /// <summary>   
  55.     /// 获取当前例程   
  56.     /// </summary>   
  57.     public static Process RunningInstance( )  
  58.     {  
  59.         Process current = Process.GetCurrentProcess( );  
  60.         Process[] processes = Process.GetProcessesByName( current.ProcessName );  
  61.         //遍历正在有相同名字运行的例程   
  62.         foreach ( Process process in processes )  
  63.         {  
  64.             //忽略现有的例程    
  65.             if ( process.Id != current.Id )  
  66.             {  
  67.                 //确保例程从EXE文件运行      
  68.                 if ( Assembly.GetExecutingAssembly( ).Location.Replace( "/" , "//" ) == current.MainModule.FileName )  
  69.                 {  
  70.                     //返回另一个例程实例       
  71.                     return process;  
  72.                 }  
  73.             }  
  74.         }  
  75.         return null;  
  76.     }  
  77.   
  78.     /// <summary>   
  79.     /// 激活已运行例程   
  80.     /// </summary>   
  81.     public static void HandleRunningInstance( Process instance )  
  82.     {  
  83.         //确保窗口没有被最小化或最大化       
  84.         ShowWindowAsync( instance.MainWindowHandle , WS_SHOWNORMAL );  
  85.         //设置真实例程为foreground window    
  86.         SetForegroundWindow( instance.MainWindowHandle );  
  87.     }  
  88.   
  89.     [DllImport( "User32.dll" )]  
  90.     private static extern bool ShowWindowAsync( IntPtr hWnd , int cmdShow );  
  91.     [DllImport( "User32.dll" )]  
  92.     private static extern bool SetForegroundWindow( IntPtr hWnd );  
  93.     private const int WS_SHOWNORMAL = 1;  
  94. }  
  95.   
  96. struct COPYDATASTRUCT  
  97. {  
  98.     public uint dwData;  
  99.     public uint cbData;  
  100.     public IntPtr lpData;  
  101. }  

 

主窗体:

  1. public partial class FrmMain : Form  
  2. {  
  3.     [System.Runtime.InteropServices.DllImport( "User32.dll " )]  
  4.     public static extern int SendMessage( IntPtr hWnd , uint Msg , int wParam , int lParam );  
  5.     public const int WM_COPYPATH = 0x004A;  
  6.     private string FILE_PATH;  
  7.   
  8.     public FrmMain( string path )  
  9.     {  
  10.         InitializeComponent( );  
  11.         this.FILE_PATH = path;  
  12.     }  
  13.      
  14.     protected override void WndProc( ref Message m )  
  15.     {  
  16.         switch ( m.Msg )  
  17.         {  
  18.             case WM_COPYPATH:  
  19.                 COPYDATASTRUCT copyData = (COPYDATASTRUCT)Marshal.PtrToStructure(  
  20.                     (IntPtr)m.LParam , typeof( COPYDATASTRUCT ) );  
  21.                 string path = string.Empty;  
  22.                 //接收从入口处传过来的新文件路径   
  23.                 if ( copyData.lpData != IntPtr.Zero )  
  24.                 {  
  25.                     path = Marshal.PtrToStringAnsi( copyData.lpData , (int)copyData.cbData );  
  26.                 }  
  27.                 
  28.                 // 在这里进行界面数据的刷新   
  29.                 // this.FILE_PATH = path;   
  30.                
  31.                 break;  
  32.         }  
  33.         base.WndProc( ref m );  
  34.     }  
  35. }  

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值