프로젝트

일반

사용자정보

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

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

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

1
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

    
28
                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

    
37
        /// <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
        private static string ProcessCommandLinesQuery(int processId)
49
        {
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
           if (IO.FileExists(commandLine.Replace("\"", "")))
75
            {
76
                var file = new System.IO.FileInfo(commandLine.Replace("\"", ""));
77
                return file.DirectoryName;
78
            }
79

    
80
            var splitCommand = commandLine.Split(' ');
81
            string filePath = "";
82

    
83
            for (int i = 0; i < splitCommand.Count(); i++)
84
            {
85
                filePath += " " + splitCommand[i].Replace("\"", "");
86

    
87
                if (IO.FileExists(filePath))
88
                {
89
                    System.IO.FileInfo info = new System.IO.FileInfo(filePath);
90
                    filePath = info.DirectoryName;
91
                    break;
92
                }
93
                else if (i == splitCommand.Count() - 1)
94
                {
95
                    var firstCmd = splitCommand.First();
96

    
97
                    if (firstCmd.StartsWith("\"") && firstCmd.EndsWith("\""))
98
                    {
99
                        filePath = firstCmd.Replace("\"", "");
100
                    }
101
                }
102
                else
103
                {
104
                    filePath = commandLine;
105
                }
106
            }
107

    
108
            return filePath;
109
        }
110

    
111
        /// <summary>
112
        /// command line에서 처음에 있는 파일 경로가 \"로 묶여 있거나 묶여 있지 않은 경우가 있다.
113
        /// 파일 경로를 제거하기 위한 코드
114
        /// </summary>
115
        /// <param name="commandLine"></param>
116
        /// <returns></returns>
117
        private static string RemoveCommadLinesFilePath(string commandLine)
118
        {
119
            string result = "";
120

    
121
            var splitCommand = commandLine.Split(' ');
122
            string filePath = "";
123

    
124
            for (int i = 0; i < splitCommand.Count(); i++)
125
            {
126
                filePath += " " + splitCommand[i];
127

    
128
                if (IO.FileExists(filePath.Replace("\"", "")))
129
                {
130
                    result = string.Join(" ", splitCommand.Skip(i + 1).Take(splitCommand.Count() - i));
131
                    break;
132
                }
133
                else if (i == splitCommand.Count() - 1)
134
                {
135
                    var firstCmd = splitCommand.First();
136

    
137
                    if (firstCmd.StartsWith("\"") && firstCmd.EndsWith("\""))
138
                    {
139
                        result = string.Join(" ", splitCommand.Skip(1).Take(splitCommand.Count() - 1));
140
                    }
141
                }
142
                else
143
                {
144
                    result = commandLine;
145
                }
146
            }
147

    
148
            return result;
149
        }
150

    
151
        public static string[] SplitArguments(string commandLine)
152
        {
153
            List<string> args = new List<string>();
154
            List<char> currentArg = new List<char>();
155
            char? quoteSection = null; // Keeps track of a quoted section (and the type of quote that was used to open it)
156
            char[] quoteChars = new[] { '\'', '\"' };
157
            char previous = ' '; // Used for escaping double quotes
158

    
159
            for (var index = 0; index < commandLine.Length; index++)
160
            {
161
                char c = commandLine[index];
162
                if (quoteChars.Contains(c))
163
                {
164
                    if (previous == c) // Escape sequence detected
165
                    {
166
                        previous = ' '; // Prevent re-escaping
167
                        if (!quoteSection.HasValue)
168
                        {
169
                            quoteSection = c; // oops, we ended the quoted section prematurely
170
                            continue;         // don't add the 2nd quote (un-escape)
171
                        }
172

    
173
                        if (quoteSection.Value == c)
174
                            quoteSection = null; // appears to be an empty string (not an escape sequence)
175
                    }
176
                    else if (quoteSection.HasValue)
177
                    {
178
                        if (quoteSection == c)
179
                            quoteSection = null; // End quoted section
180
                    }
181
                    else
182
                        quoteSection = c; // Start quoted section
183
                }
184
                else if (char.IsWhiteSpace(c))
185
                {
186
                    if (!quoteSection.HasValue)
187
                    {
188
                        args.Add(new string(currentArg.ToArray()));
189
                        currentArg.Clear();
190
                        previous = c;
191
                        continue;
192
                    }
193
                }
194

    
195
                currentArg.Add(c);
196
                previous = c;
197
            }
198

    
199
            if (currentArg.Count > 0)
200
                args.Add(new string(currentArg.ToArray()));
201

    
202
            return args.ToArray();
203
        }
204
    }
205
}
클립보드 이미지 추가 (최대 크기: 500 MB)