我现在在做一个项目,一个可执行文件是一个windows服务,但也要求它能在命令行执行不同的任务。所以需要在程序启动时判断这个程序是由Service Manager启动的还是由Console启动的,由于Service Manager的进程名字是固定的,那很显然最简单的方法就是看启动该程序的父进程的名字是不是Service Manager。但我查了一下Process类,没发现类似的功能。那在C#中有没有方法获取到父进程的名字呢?谢谢!

解决方案 »

  1.   

    使用命令行参数来识别就可以了。在Service Manager启动该程序时提供一个参数。程序启动时检查一下就可以了。如下,在Service Manager启动时使用注释中的方式即可。        static void Main(string[] args)
            {
                bool startBySM = args.Length > 0 && args[0] == "SM";            /* ...
                 Process.Start("...", "SM");
                 */
            }
      

  2.   

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Diagnostics;namespace ConsoleApplication1
    {
        public static class ProcessExtensions 
        { 
            private static string FindIndexedProcessName(int pid) 
            { 
                var processName = Process.GetProcessById(pid).ProcessName; 
                var processesByName = Process.GetProcessesByName(processName); 
                string processIndexdName = null; 
                for (var index = 0; index < processesByName.Length; index++)
                { 
                    processIndexdName = index == 0 ? processName : processName + "#" + index;
                    var processId = new PerformanceCounter("Process", "ID Process", processIndexdName); 
                    if ((int)processId.NextValue() == pid) 
                    { 
                        return processIndexdName; 
                    } 
                } 
                return processIndexdName; 
            }         private static Process FindPidFromIndexedProcessName(string indexedProcessName) 
            { 
                var parentId = new PerformanceCounter("Process", "Creating Process ID", indexedProcessName); 
                return Process.GetProcessById((int)parentId.NextValue()); 
            }         public static Process Parent(this Process process) 
            { 
                return FindPidFromIndexedProcessName(FindIndexedProcessName(process.Id));
            } 
        }
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine(Process.GetCurrentProcess().Parent().ProcessName); 
            }
        }
    }
      

  3.   


    这个方法确实有用,但怎么创建Perf counter的时候这么慢
      

  4.   

            public static class ProcessExtensions
            {
                private static string FindIndexedProcessName(int pid)
                {
                    string processName = Process.GetProcessById(pid).ProcessName;
                    Process[] processesByName = Process.GetProcessesByName(processName);
                    string processIndexdName = null;
                    for (var index = 0; index < processesByName.Length; index++)
                    {
                        processIndexdName = index == 0 ? processName : processName + "#" + index;
                        PerformanceCounter processId = new PerformanceCounter("Process", "ID Process", processIndexdName);
                        if ((int)processId.NextValue() == pid)
                        {
                            return processIndexdName;
                        }
                    }
                    return processIndexdName;
                }
                private static Process FindPidFromIndexedProcessName(string indexedProcessName)
                {
                    PerformanceCounter parentId = new PerformanceCounter("Process", "Creating Process ID", indexedProcessName);
                    return Process.GetProcessById((int)parentId.NextValue());
                }
                public static Process Parent(Process process)
                {
                    return FindPidFromIndexedProcessName(FindIndexedProcessName(process.Id));
                }
            }调用 
       #region 向进程发送消息
            const int WM_COPYDATA = 0x500;
            [DllImport("User32.dll", EntryPoint = "SendMessage")]
            private static extern int SendMessage(
                int hWnd, // handle to destination window    
                int Msg, // message           
                int wParam, // first message parameter        
                ref COPYDATASTRUCT lParam // second message parameter   
                );        [DllImport("User32.dll", EntryPoint = "SendMessage")]
            private static extern int SendMessage(
                int hWnd, // handle to destination window    
                int Msg, // message           
                int wParam, // first message parameter 
                int lParam // second message parameter 
            );
            [DllImport("User32.dll", EntryPoint = "FindWindow")]
            private static extern int FindWindow(string lpClassName, string lpWindowName);
            public struct COPYDATASTRUCT
            {
                public IntPtr dwData;
                public int cbData;
                [MarshalAs(UnmanagedType.LPStr)]
                public string lpData;
            }
            #endregion
            static int WINDOW_HANDLER = 0;
            private void button1_Click(object sender, EventArgs e)
            {
                IntPtr ip = (IntPtr)0;
                Process[] ppArr = System.Diagnostics.Process.GetProcessesByName(ProcessExtensions.Parent(Process.GetCurrentProcess()).ProcessName);
                if (ppArr.Length > 0)
                {
                    Process p = ppArr[0];
                    ip = p.MainWindowHandle;//获取主线程窗体句柄
                }            WINDOW_HANDLER = (int)ip;//主线程窗体句柄 接收窗体的句柄 这样子线程可以向主窗体发送消息了呵呵        
                if (WINDOW_HANDLER != 0)
                {
                    byte[] sarr = System.Text.Encoding.Default.GetBytes(this.txtData.Text);
                    int len = sarr.Length;
                    COPYDATASTRUCT cds;
                    cds.dwData = (IntPtr)100;
                    cds.lpData = this.txtData.Text;
                    cds.cbData = len + 1;
                    SendMessage(WINDOW_HANDLER, WM_COPYDATA, 0, 010);
                }
            }
    非常感谢3楼的回复