2014-01-08 1 views
0

다음은 Windows에서 현재 실행중인 프로세스의 목록을 가져 오는 코드입니다.Java에서 Windows 프로세스 설명을받는 방법?

import com.sun.jna.platform.win32.Kernel32; 
import com.sun.jna.platform.win32.Tlhelp32; 
import com.sun.jna.platform.win32.WinDef; 
import com.sun.jna.platform.win32.WinNT; 
import com.sun.jna.win32.W32APIOptions; 
import com.sun.jna.Native; 

public class ListProcesses { 
    public static void main(String[] args) { 
     Kernel32 kernel32 = (Kernel32) Native.loadLibrary(Kernel32.class, W32APIOptions.UNICODE_OPTIONS); 

     Tlhelp32.PROCESSENTRY32.ByReference processEntry = new Tlhelp32.PROCESSENTRY32.ByReference();   
     WinNT.HANDLE snapshot = kernel32.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPPROCESS, new WinDef.DWORD(0)); 
     try { 
      while (kernel32.Process32Next(snapshot, processEntry)) {    
       System.out.println(processEntry.th32ProcessID + "\t" + Native.toString(processEntry.szExeFile)+"\t"+processEntry.readField("")); 
      } 

     } 

     finally { 
      kernel32.CloseHandle(snapshot); 
     } 
    } 
} 

는하지만 실행중인 각 proceess의 프로세스에 대한 설명을 얻을 솔루션을 제공 output.Kindly의 프로세스/서비스의 설명을 얻을 수 없습니다입니다. 미리 감사드립니다.

답변

2

대신로드 단순히 기본 프로세스를 실행하는 런타임을 사용하는 창에 다음 코드를 사용할 수의 Kernal32을 호출 :

: 명령을 실행 한 후

public List<String> execCommand(String ... command) 
{ 
    try 
    { 
     // execute the desired command 
     Process proc = null; 
     if (command.length > 1) 
      proc = Runtime.getRuntime().exec(command); 
     else 
      proc = Runtime.getRuntime().exec(command[0]); 

     // process the response 
     String line = ""; 
     List<String> output = new ArrayList<>(); 
     try (BufferedReader input = new BufferedReader(new InputStreamReader(proc.getInputStream()))) 
     { 
      while ((line = input.readLine()) != null) 
      { 
       output.add(line); 
      } 
     } 
     return output; 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 
    return Collections.<String>emptyList(); 
} 

을하고는 Windows Management Information Command-line 호출하는

List<String> output = execCommand("wmic.exe PROCESS where name='"+processName+"'"); 

processName에는 실행중인 응용 프로그램의 이름 또는 정보를 얻으려고하는 exe가 포함되어야합니다.

반환 된 목록에는 실행중인 응용 프로그램의 상태 정보가 출력됩니다. 첫 번째 항목에는 해당 필드의 헤더 정보가 들어 있고, 다음 항목에는 일치하는 모든 프로세스 이름에 대한 정보가 들어 있습니다. WMIC에

추가 정보를 정기적으로 :

HTH

+0

정말 고맙습니다. me.Actually 원격 웹 사이트에서 실행중인 일부 다운로드 서비스를 차단하기 위해 Java 웹 시작으로 실행합니다. 모든 버전의 Windows OS에서 사용할 수 있습니까? –

+0

WMIC의 최소 요구 사항은 클라이언트 측 Windows XP 및 서버 측 Windows Server 2003 ([Source] (http://msdn.microsoft.com/en-us/library/aa394531%28v=vs.85%29. aspx)) - Windows 3.1, 95, ME 또는 NT를 지원해야하는 경우 (현재 자주 사용되는 것은 아닌 것 같지만) 다른 솔루션이 필요합니다. –

+0

감사합니다. 나는 wmic.exe 프로세스를 시도하고 있는데 (이름 = "dap.exe") Processid, Caption, Command line을 얻습니다. 설명은 캡션 (DAP.exe)과 같은 설명을 제공합니다. 즉, 프로세스/exe에 대한 실제 설명을 제공합니다. 실제 설명은 DAP (Accelerator Plus)입니다. –

1

내가로부터 버전 정보를 추출하는 방법을 전시 this post here를 통해 오늘 발견으로 실행 파일, 포스트가 내 마음으로 돌아 왔고 그래서 나는 약간의 조사를 시작했다.

This further post은 프로세스 설명을 실행 파일 자체에서만 추출 할 수 있으므로 WMIC 또는 TASKLIST의 일부 출력을 구문 분석하는 대신 JNA를 직접 사용해야한다고 나와 있습니다. 이 게시물은 프로세스 설명을 추출하는 C 방법을 제공하는 MSDN page for VerQueryValue 함수를 더 링크합니다. 여기서 특히 두 번째 매개 변수는 반환 할 항목을 정의 할 때 관심을 가져야합니다.

첫 번째 게시물에서 언급 한 코드를 사용하여 이제 C 구조체 typedef를 Java에 해당하는 것으로 변환합니다.

메이븐의 pom.xml : - 사람이 읽을 수있는 출력에 추출 된 육각 값을 매핑하는 헬퍼 클래스

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>at.rovo.test</groupId> 
    <artifactId>JNI_Test</artifactId> 
    <version>1.0-SNAPSHOT</version> 
    <packaging>jar</packaging> 

    <name>JNI_Test</name> 
    <url>http://maven.apache.org</url> 
    <build> 
     <plugins> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-compiler-plugin</artifactId> 
       <version>2.3.2</version> 
       <configuration> 
        <source>1.7</source> 
        <target>1.7</target> 
       </configuration> 
      </plugin> 
     </plugins> 
    </build> 
    <properties> 
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
    </properties> 

    <dependencies> 
    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>3.8.1</version> 
     <scope>test</scope> 
    </dependency>  
    <!-- JNA 3.4 
    <dependency> 
     <groupId>net.java.dev.jna</groupId> 
     <artifactId>jna</artifactId> 
     <version>3.4.0</version> 
    </dependency> 
    <dependency> 
    <groupId>net.java.dev.jna</groupId> 
    <artifactId>platform</artifactId> 
    <version>3.4.0</version> 
    </dependency> 
    --> 
    <!-- JNA 4.0.0 --> 
    <dependency> 
     <groupId>net.java.dev.jna</groupId> 
     <artifactId>jna</artifactId> 
     <version>4.0.0</version> 
    </dependency> 
    <dependency> 
     <groupId>net.java.dev.jna</groupId> 
     <artifactId>jna-platform</artifactId> 
     <version>4.0.0</version> 
    </dependency> 
    <!-- --> 
    </dependencies> 
</project> 

LangAndCodePage.java 나는 적어도 Windows 7 64bit에 나를 위해 작동 여기에 전체 코드를 게시 할 예정입니다 변환 테이블에 포함 된 언어 및 코드 페이지 정보 값 따라서 this page here에서 가져옵니다 :

package at.rovo.test.jni_test; 

import java.util.HashMap; 
import java.util.Map; 

public final class LangAndCodePage 
{ 
    private final static Map<String, String> languages = new HashMap<>(); 
    private final static Map<String, String> codePage = new HashMap<>(); 

    static 
    { 
     languages.put("0000", "Language Neutral"); 
     languages.put("0401", "Arabic"); 
     languages.put("0402", "Bulgarian"); 
     languages.put("0403", "Catalan"); 
     languages.put("0404", "Traditional Chinese"); 
     languages.put("0405", "Czech"); 
     languages.put("0406", "Danish"); 
     languages.put("0407", "German"); 
     languages.put("0408", "Greek"); 
     languages.put("0409", "U.S. English"); 
     languages.put("040A", "Castilian Spanish"); 
     languages.put("040B", "Finnish"); 
     languages.put("040C", "French"); 
     languages.put("040D", "Hebrew"); 
     languages.put("040E", "Hungarian"); 
     languages.put("040F", "Icelandic"); 
     languages.put("0410", "Italian"); 
     languages.put("0411", "Japanese"); 
     languages.put("0412", "Korean"); 
     languages.put("0413", "Dutch");  
     languages.put("0414", "Norwegian ? Bokmal");  
     languages.put("0810", "Swiss Italian");  
     languages.put("0813", "Belgian Dutch");  
     languages.put("0814", "Norwegian ? Nynorsk"); 
     languages.put("0415", "Polish"); 
     languages.put("0416", "Portuguese (Brazil)"); 
     languages.put("0417", "Rhaeto-Romanic"); 
     languages.put("0418", "Romanian"); 
     languages.put("0419", "Russian"); 
     languages.put("041A", "Croato-Serbian (Latin)"); 
     languages.put("041B", "Slovak"); 
     languages.put("041C", "Albanian"); 
     languages.put("041D", "Swedish"); 
     languages.put("041E", "Thai"); 
     languages.put("041F", "Turkish"); 
     languages.put("0420", "Urdu"); 
     languages.put("0421", "Bahasa"); 
     languages.put("0804", "Simplified Chinese"); 
     languages.put("0807", "Swiss German"); 
     languages.put("0809", "U.K. English"); 
     languages.put("080A", "Spanish (Mexico)"); 
     languages.put("080C", "Belgian French"); 
     languages.put("0C0C", "Canadian French"); 
     languages.put("100C", "Swiss French"); 
     languages.put("0816", "Portuguese (Portugal)"); 
     languages.put("081A", "Serbo-Croatian (Cyrillic)"); 

     codePage.put("0000", "7-bit ASCII"); 
     codePage.put("03A4", "Japan (Shift ? JIS X-0208)"); 
     codePage.put("03B5", "Korea (Shift ? KSC 5601)"); 
     codePage.put("03B6", "Taiwan (Big5)"); 
     codePage.put("04B0", "Unicode"); 
     codePage.put("04E2", "Latin-2 (Eastern European)"); 
     codePage.put("04E3", "Cyrillic"); 
     codePage.put("04E4", "Multilingual"); 
     codePage.put("04E5", "Greek"); 
     codePage.put("04E6", "Turkish"); 
     codePage.put("04E7", "Hebrew"); 
     codePage.put("04E8", "Arabic"); 
    } 

    // prohibit instantiation 
    private LangAndCodePage() 
    { 

    } 

    public static void printTranslationInfo(String lang, String cp) 
    { 
     StringBuilder builder = new StringBuilder(); 
     builder.append("Language: "); 
     builder.append(languages.get(lang)); 
     builder.append(" ("); 
     builder.append(lang); 
     builder.append("); "); 

     builder.append("CodePage: "); 
     builder.append(codePage.get(cp)); 
     builder.append(" ("); 
     builder.append(cp); 
     builder.append(");"); 

     System.out.println(builder.toString()); 
    } 
} 

마지막으로 파일 버전 및 Windows 탐색기의 파일 설명을 추출 코드가 아닙니다 적어도.

[exec:exec] 
Version: 6.1.7601.17567 
Found 1 translation(s) (length of cbTranslate: 4 bytes) 
Language: German (0407); CodePage: Unicode (04B0); 
File-Description: "Windows-Explorer" 

HTH

을 :) 마지막으로

package at.rovo.test.jni_test; 

import java.io.IOException; 

import com.sun.jna.Memory; 
import com.sun.jna.Pointer; 
import com.sun.jna.platform.win32.VerRsrc.VS_FIXEDFILEINFO; 
import com.sun.jna.platform.win32.Version; 
import com.sun.jna.ptr.IntByReference; 
import com.sun.jna.ptr.PointerByReference; 
import java.math.BigInteger; 
import java.nio.charset.StandardCharsets; 
import java.util.ArrayList; 
import java.util.List; 

public class FileVersion 
{ 
    // The structure as implemented by the MSDN article 
    public static class LANGANDCODEPAGE extends Structure 
    { 
     /** The language contained in the translation table **/ 
     public short wLanguage; 
     /** The code page contained in the translation table **/ 
     public short wCodePage; 

     public LANGANDCODEPAGE(Pointer p) 
     { 
      useMemory(p); 
     } 

     public LANGANDCODEPAGE(Pointer p, int offset) 
     { 
      useMemory(p, offset); 
     } 

     public static int sizeOf() 
     { 
      return 4; 
     } 

     // newer versions of JNA require a field order to be set 
     @Override 
     protected List getFieldOrder() 
     { 
      List fieldOrder = new ArrayList(); 
      fieldOrder.add("wLanguage"); 
      fieldOrder.add("wCodePage"); 
      return fieldOrder; 
     } 
    } 

    public static void main(String[] args) throws IOException 
    { 
     // http://msdn.microsoft.com/en-us/library/ms647464%28v=vs.85%29.aspx 
     // 
     // VerQueryValue will take two input and two output parameters 
     // 1. parameter: is a pointer to the version-information returned 
     //    by GetFileVersionInfo 
     // 2. parameter: will take a string and return an output depending on 
     //    the string: 
     //  "\\" 
     //   Is the root block and retrieves a VS_FIXEDFILEINFO struct 
     //  "\\VarFileInfo\Translation" 
     //   will return an array of Var variable information structure 
     //   holding the language and code page identifier 
     //  "\\StringFileInfo\\{lang-codepage}\\string-name" 
     //   will return a string value of the language and code page 
     //   requested. {lang-codepage} is a concatenation of a language 
     //   and the codepage identifier pair found within the translation 
     //   array in a hexadecimal string! string-name must be one of the 
     //   following values: 
     //    Comments, InternalName, ProductName, CompanyName, 
     //    LegalCopyright, ProductVersion, FileDescription, 
     //    LegalTrademarks, PrivateBuild, FileVersion, 
     //    OriginalFilename, SpecialBuild 
     // 3. parameter: contains the address of a pointer to the requested 
     //    version information in the buffer of the 1st parameter. 
     // 4. parameter: contains a pointer to the size of the requested data 
     //    pointed to by the 3rd parameter. The length depends on 
     //    the input of the 2nd parameter: 
     //    *) For root block, the size in bytes of the structure 
     //    *) For translation array values, the size in bytes of 
     //     the array stored at lplpBuffer; 
     //    *) For version information values, the length in 
     //     character of the string stored at lplpBuffer; 

     String filePath = "C:\\Windows\\explorer.exe"; 

     IntByReference dwDummy = new IntByReference(); 
     dwDummy.setValue(0); 

     int versionlength = 
       Version.INSTANCE.GetFileVersionInfoSize(filePath, dwDummy); 

     if (versionlength > 0) 
     { 
      // will hold the bytes of the FileVersionInfo struct 
      byte[] bufferarray = new byte[versionlength]; 
      // allocates space on the heap (== malloc in C/C++) 
      Pointer lpData = new Memory(bufferarray.length); 
      // will contain the address of a pointer to the requested version 
      // information 
      PointerByReference lplpBuffer = new PointerByReference(); 
      // will contain a pointer to the size of the requested data pointed 
      // to by lplpBuffer. 
      IntByReference puLen = new IntByReference(); 

      // reads versionLength bytes from the executable file into the FileVersionInfo struct buffer 
      boolean fileInfoResult = 
        Version.INSTANCE.GetFileVersionInfo(
          filePath, 0, versionlength, lpData); 

      // retrieve file description for language and code page "i" 
      boolean verQueryVal = 
        Version.INSTANCE.VerQueryValue(
          lpData, "\\", lplpBuffer, puLen); 

      // contains version information for a file. This information is 
      // language and code page independent 
      VS_FIXEDFILEINFO lplpBufStructure = 
       new VS_FIXEDFILEINFO(lplpBuffer.getValue()); 
      lplpBufStructure.read(); 

      int v1 = (lplpBufStructure.dwFileVersionMS).intValue() >> 16; 
      int v2 = (lplpBufStructure.dwFileVersionMS).intValue() & 0xffff; 
      int v3 = (lplpBufStructure.dwFileVersionLS).intValue() >> 16; 
      int v4 = (lplpBufStructure.dwFileVersionLS).intValue() & 0xffff; 

      System.out.println(
        String.valueOf(v1) + "." + 
          String.valueOf(v2) + "." + 
          String.valueOf(v3) + "." + 
          String.valueOf(v4)); 

      // creates a (reference) pointer 
      PointerByReference lpTranslate = new PointerByReference(); 
      IntByReference cbTranslate = new IntByReference(); 
      // Read the list of languages and code pages 
      verQueryVal = Version.INSTANCE.VerQueryValue(
         lpData, "\\VarFileInfo\\Translation", lpTranslate, cbTranslate); 

      if (cbTranslate.getValue() > 0) 
      { 
       System.out.println("Found "+(cbTranslate.getValue()/4) 
        + " translation(s) (length of cbTranslate: " 
        + cbTranslate.getValue()+" bytes)"); 
      } 
      else 
      { 
       System.err.println("No translation found!"); 
       return; 
      } 

      // Read the file description 
      // msdn has this example here: 
      // for(i=0; i < (cbTranslate/sizeof(struct LANGANDCODEPAGE)); i++) 
      // where LANGANDCODEPAGE is a struct holding two WORDS. A word is 
      // 16 bits (2x 8 bit = 2 bytes) long and as the struct contains two 
      // words the length of the struct should be 4 bytes long 
      for (int i=0; i < (cbTranslate.getValue()/LANGANDCODEPAGE.sizeOf()); i++)) 
      { 
       // writes formatted data to the specified string 
       // out: pszDest - destination buffer which receives the formatted, null-terminated string created from pszFormat 
       // in: ccDest - the size of the destination buffer, in characters. This value must be sufficiently large to accomodate the final formatted string plus 1 to account for the terminating null character. 
       // in: pszFormat - the format string. This string must be null-terminated 
       // in: ... The arguments to be inserted into the pszFormat string 
       // hr = StringCchPrintf(SubBlock, 50, 
       //      TEXT("\\StringFileInfo\\%04x%04x\\FileDescription"), 
       //      lpTranslate[i].wLanguage, 
       //      lpTranslate[i].wCodePage); 

       // fill the structure with the appropriate values 
       LANGANDCODEPAGE langCodePage = 
        new LANGANDCODEPAGE(lpTranslate.getValue(), i*LANGANDCODEPAGE.sizeOf()); 
       langCodePage.read(); 

       // convert short values to hex-string: 
       // https://stackoverflow.com/questions/923863/converting-a-string-to-hexadecimal-in-java 
       String lang = String.format("%04x", langCodePage.wLanguage); 
       String codePage = String.format("%04x",langCodePage.wCodePage); 

       // see http://msdn.microsoft.com/en-us/library/windows/desktop/aa381058.aspx 
       // for proper values for lang and codePage 

       LangAndCodePage.printTranslationInfo(lang.toUpperCase(), codePage.toUpperCase()); 

       // build the string for querying the file description stored in 
       // the executable file 
       StringBuilder subBlock = new StringBuilder(); 
       subBlock.append("\\StringFileInfo\\"); 
       subBlock.append(lang); 
       subBlock.append(codePage); 
       subBlock.append("\\FileDescription"); 

       printDescription(lpData, subBlock.toString()); 
      } 
     } 
     else 
      System.out.println("No version info available"); 
    } 

    private static void printDescription(Pointer lpData, String subBlock) 
    { 
     PointerByReference lpBuffer = new PointerByReference(); 
     IntByReference dwBytes = new IntByReference(); 

     // Retrieve file description for language and code page "i" 
     boolean verQueryVal = Version.INSTANCE.VerQueryValue(
      lpData, subBlock, lpBuffer, dwBytes); 

     // a single character is represented by 2 bytes! 
     // the last character is the terminating "\n" 
     byte[] description = 
      lpBuffer.getValue().getByteArray(0, (dwBytes.getValue()-1)*2); 
     System.out.println("File-Description: \"" 
      + new String(description, StandardCharsets.UTF_16LE)+"\""); 
    } 
} 

, 내 독일어 윈도우 7 64 비트에 받고있어 출력, 나는 물건 자신을 학습하는 데 사용되는 코드는 문서 많이 들어


@Edit : 값 추출을 단순화하기 위해 구조체의 클래스 표현을 사용하도록 코드를 업데이트했습니다. 바이트를 처리하면 바이트 순서를 변경해야합니다. 큰 문자와 작은 문자 전자 엔디안 문제)

여러 번역 결과를 테스트 할 수있는 파일 내에서 여러 언어와 코드 페이지를 사용하는 응용 프로그램을 시도한 후 발견되었습니다.


@ Edit2 : 코드를 리팩토링하여 github에 올려주십시오. 주석에서 언급 한 바와 같이, 로지텍 윙맨 이벤트 모니터에 대한 github의의의 repo에서 코드를 실행하는 출력은 여러 언어와 코드 페이지 세그먼트를 반환

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 
XXX Information contained in: C:\Program Files\Logitech\Gaming Software\LWEMon.exe 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 
File: C:\Program Files\Logitech\Gaming Software\LWEMon.exe 
Version: 5.10.127.0 
Language: U.S. English 
CodePage: Multilingual 
Original-Filename: LWEMon.exe 
Company-Name: Logitech Inc. 
File-Description: Logitech WingMan Event Monitor 
File-Version: 5.10.127 
Product-Version: 5.10.127 
Product-Name: Logitech Gaming Software 
Internal-Name: LWEMon 
Private-Build: 
Special-Build: 
Legal-Copyright: © 1999-2010 Logitech. All rights reserved. 
Legal-Trademark: Logitech, the Logitech logo, and other Logitech marks are owned by Logitech and may be registered. All other trademarks are the property of their respective owners. 
Comment: Created by the WingMan Team. 

File: C:\Program Files\Logitech\Gaming Software\LWEMon.exe 
Version: 5.10.127.0 
Language: Japanese 
CodePage: Multilingual 
Original-Filename: LWEMon.exe 
Company-Name: Logicool Co. Ltd. 
File-Description: Logicool WingMan Event Monitor 
File-Version: 5.10.127 
Product-Version: 5.10.127 
Product-Name: Logicool Gaming Software 
Internal-Name: LWEMon 
Private-Build: 
Special-Build: 
Legal-Copyright: © 1999-2010 Logicool Co. Ltd. All rights reserved. 
Legal-Trademark: Logicool, the Logicool logo, and other Logicool marks are owned by Logicool and may be registered. All other trademarks are the property of their respective owners. 
Comment: Created by the WingMan Team. 
+0

고마워요. 사실 나는 다른 방법을 알아 낸다. Windows PowerShell 명령 ** get-process notepad | 선택 개체 설명 **. 따라서 현재 실행중인 프로세스에 대한 설명을 얻으려면 명령 줄을 사용하고 있습니다. 서비스와 마찬가지로 ** get-service | where {$ _. status -eq 'running'} ** 귀하의 제안을 친절히 제공하십시오. –

+0

파일 설명 만 추출하기 위해 (int i = 0; i <(cbTranslate.getValue()/LANGANDCODEPAGE.sizeOf()); i ++)에 대한 루프를 실제로 사용해야합니까? – ANTARA

+1

단일 언어 및 코드 페이지 항목이있는 .exe 파일 만 있으면 루프가 필요하지 않습니다. 그러나 여러 언어와 codePages가 포함 된 실행 파일을 갖고 있고 모두 나열하려면 루프를 사용하는 것이 좋습니다. 단일 언어 및 코드 페이지 세그먼트 만있는 경우에도 루프 자체가 손상되지 않습니다 –

0

(답변 응답의 영업 이익으로 답변 커뮤니티에 변환됩니다. 위키 답변. Question with no answers, but issue solved in the comments (or extended in chat)을 참조하십시오.

사실 나는 다른 방법을 발견합니다. Windows PowerShell 명령 :
get-process notepad | select-object description.

따라서 현재 실행중인 프로세스에 대한 설명을 보려면 명령 줄을 사용하고 있습니다. 서비스에 대해서도 마찬가지로 :
get-service | where {$_.status -eq 'running'}.