프로젝트

일반

사용자정보

통계
| 브랜치(Branch): | 개정판:

markus / ConvertService / ServiceBase / Markus.Service.Extensions / Exntensions / Process.cs @ 06f13e11

이력 | 보기 | 이력해설 | 다운로드 (6.7 KB)

1 53c9637d taeseongkim
using System;
2
using System.Collections.Generic;
3
using System.Diagnostics;
4
using System.Linq;
5
using System.Management;
6
using System.Text;
7
using System.Threading.Tasks;
8
9
namespace Markus.Service.Extensions
10
{
11
    public static class ProcessExtension
12
    {
13
        /// <summary>
14
        /// 프로세스의 명령줄을 가져온다.
15
        /// </summary>
16
        /// <param name="process"></param>
17
        /// <returns></returns>
18
        public static ProcessArguments Arguments(this Process process)
19
        {
20
            ProcessArguments result = new ProcessArguments();
21
22
            var commandLine = ProcessCommandLinesQuery(process.Id);
23
24
            try
25
            {
26
                result.WorkingDirectory = ProcessWorkingDirectory(commandLine);
27 06f13e11 taeseongkim
28 53c9637d taeseongkim
                result.CommandLine = SplitArguments(RemoveCommadLinesFilePath(commandLine)).ToList();
29
            }
30
            catch (Exception ex)
31
            {
32
                System.Diagnostics.Debug.WriteLine(ex.ToString());
33
            }
34
            return result;
35
        }
36 06f13e11 taeseongkim
37 53c9637d taeseongkim
        /// <summary>
38
        /// 프로세스의 실행 경로
39
        /// </summary>
40
        /// <param name="process"></param>
41
        /// <returns></returns>
42
        public static string WorkingDirectory(this Process process)
43
        {
44
            var commandLine = ProcessCommandLinesQuery(process.Id);
45
            return ProcessWorkingDirectory(commandLine);
46
        }
47
48 06f13e11 taeseongkim
        private static string ProcessCommandLinesQuery(int processId)
49 53c9637d taeseongkim
        {
50
            string result = "";
51
52
            string wmiQuery = string.Format("select CommandLine from Win32_Process where ProcessId ='{0}'", processId);
53
54
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(wmiQuery);
55
            ManagementObjectCollection retObjectCollection = searcher.Get();
56
57
            if (retObjectCollection.Count > 0)
58
            {
59
                if (retObjectCollection.Cast<ManagementObject>().First()["CommandLine"] != null)
60
                {
61
                    result = retObjectCollection.Cast<ManagementObject>().First()["CommandLine"]?.ToString();
62
                }
63
                else
64
                {
65
                    result = "";
66
                }
67
            }
68
69
            return result;
70
        }
71
72
        private static string ProcessWorkingDirectory(string commandLine)
73
        {
74
            var splitCommand = commandLine.Split(' ');
75
            string filePath = "";
76
77
            for (int i = 0; i < splitCommand.Count(); i++)
78
            {
79
                filePath += " " + splitCommand[i].Replace("\"", "");
80 06f13e11 taeseongkim
81
                if (IO.FileExists(filePath))
82 53c9637d taeseongkim
                {
83
                    System.IO.FileInfo info = new System.IO.FileInfo(filePath);
84
                    filePath = info.DirectoryName;
85
                    break;
86
                }
87 06f13e11 taeseongkim
                else if (i == splitCommand.Count() - 1)
88 53c9637d taeseongkim
                {
89
                    var firstCmd = splitCommand.First();
90
91
                    if (firstCmd.StartsWith("\"") && firstCmd.EndsWith("\""))
92
                    {
93
                        filePath = firstCmd.Replace("\"", "");
94
                    }
95
                }
96
                else
97
                {
98
                    filePath = commandLine;
99
                }
100
            }
101
102
            return filePath;
103
        }
104
105
        /// <summary>
106
        /// command line에서 처음에 있는 파일 경로가 \"로 묶여 있거나 묶여 있지 않은 경우가 있다.
107
        /// 파일 경로를 제거하기 위한 코드
108
        /// </summary>
109
        /// <param name="commandLine"></param>
110
        /// <returns></returns>
111
        private static string RemoveCommadLinesFilePath(string commandLine)
112
        {
113
            string result = "";
114
115
            var splitCommand = commandLine.Split(' ');
116
            string filePath = "";
117
118
            for (int i = 0; i < splitCommand.Count(); i++)
119
            {
120
                filePath += " " + splitCommand[i];
121
122 06f13e11 taeseongkim
                if (IO.FileExists(filePath.Replace("\"", "")))
123 53c9637d taeseongkim
                {
124 06f13e11 taeseongkim
                    result = string.Join(" ", splitCommand.Skip(i + 1).Take(splitCommand.Count() - i));
125 53c9637d taeseongkim
                    break;
126
                }
127
                else if (i == splitCommand.Count() - 1)
128
                {
129
                    var firstCmd = splitCommand.First();
130
131
                    if (firstCmd.StartsWith("\"") && firstCmd.EndsWith("\""))
132
                    {
133
                        result = string.Join(" ", splitCommand.Skip(1).Take(splitCommand.Count() - 1));
134
                    }
135
                }
136
                else
137
                {
138
                    result = commandLine;
139
                }
140
            }
141
142
            return result;
143
        }
144
145
        public static string[] SplitArguments(string commandLine)
146
        {
147
            List<string> args = new List<string>();
148
            List<char> currentArg = new List<char>();
149
            char? quoteSection = null; // Keeps track of a quoted section (and the type of quote that was used to open it)
150
            char[] quoteChars = new[] { '\'', '\"' };
151
            char previous = ' '; // Used for escaping double quotes
152
153
            for (var index = 0; index < commandLine.Length; index++)
154
            {
155
                char c = commandLine[index];
156
                if (quoteChars.Contains(c))
157
                {
158
                    if (previous == c) // Escape sequence detected
159
                    {
160
                        previous = ' '; // Prevent re-escaping
161
                        if (!quoteSection.HasValue)
162
                        {
163
                            quoteSection = c; // oops, we ended the quoted section prematurely
164
                            continue;         // don't add the 2nd quote (un-escape)
165
                        }
166
167
                        if (quoteSection.Value == c)
168
                            quoteSection = null; // appears to be an empty string (not an escape sequence)
169
                    }
170
                    else if (quoteSection.HasValue)
171
                    {
172
                        if (quoteSection == c)
173
                            quoteSection = null; // End quoted section
174
                    }
175
                    else
176
                        quoteSection = c; // Start quoted section
177
                }
178
                else if (char.IsWhiteSpace(c))
179
                {
180
                    if (!quoteSection.HasValue)
181
                    {
182
                        args.Add(new string(currentArg.ToArray()));
183
                        currentArg.Clear();
184
                        previous = c;
185
                        continue;
186
                    }
187
                }
188
189
                currentArg.Add(c);
190
                previous = c;
191
            }
192
193
            if (currentArg.Count > 0)
194
                args.Add(new string(currentArg.ToArray()));
195
196
            return args.ToArray();
197
        }
198
    }
199
}
클립보드 이미지 추가 (최대 크기: 500 MB)