diff --git a/configure b/configure
index 69b9f56..7f10544 100755
--- a/configure
+++ b/configure
@@ -689,7 +689,7 @@ EOF
   sysconfdir="\${prefix}"
   local_statedir=
   confsuffix=""
-  libs_qga="-lws2_32 -lwinmm -lpowrprof $libs_qga"
+  libs_qga="-lws2_32 -lwinmm -lpowrprof -lpsapi $libs_qga"
 fi

 werror=""
diff --git a/qga/Makefile.objs b/qga/Makefile.objs
index 1c5986c..48020ea 100644
--- a/qga/Makefile.objs
+++ b/qga/Makefile.objs
@@ -1,4 +1,4 @@
-qga-obj-y = commands.o guest-agent-command-state.o main.o
+qga-obj-y = commands.o guest-agent-command-state.o main.o proclist/process_list.o
 qga-obj-$(CONFIG_POSIX) += commands-posix.o channel-posix.o
 qga-obj-$(CONFIG_WIN32) += commands-win32.o channel-win32.o service-win32.o
 qga-obj-$(CONFIG_WIN32) += vss-win32.o
diff --git a/qga/commands.c b/qga/commands.c
index a0c2de0..aaa5e93 100644
--- a/qga/commands.c
+++ b/qga/commands.c
@@ -14,6 +14,7 @@
 #include "qga/guest-agent-core.h"
 #include "qga-qmp-commands.h"
 #include "qapi/qmp/qerror.h"
+#include "qga/proclist/process_list.h"

 /* Note: in some situations, like with the fsfreeze, logging may be
  * temporarilly disabled. if it is necessary that a command be able
@@ -70,3 +71,24 @@ struct GuestAgentInfo *qmp_guest_info(Error **err)
     qmp_for_each_command(qmp_command_info, info);
     return info;
 }
+
+GuestVmProgsList *qmp_guest_get_progs(Error **errp)
+{
+
+    ProcListT ProcList[2048];
+    int ret = getProcessList(ProcList);
+    GuestVmProgsList *progs = g_malloc0(sizeof(GuestVmProgsList));
+    GuestVmProgsList *progsRet = progs;
+    int i = 0;
+    for(i = 0; i < ret; ++i){
+        progs->value = g_malloc0(sizeof(GuestVmProgs));
+        progs->value->name = g_strdup(ProcList[i].name);
+        progs->value->path = g_strdup(ProcList[i].path);
+        progs->value->pid = ProcList[i].pid;
+        if(i < ret - 1){
+            progs->next = g_malloc0(sizeof(GuestVmProgsList));
+            progs = progs->next;
+        }
+    }
+    return progsRet;
+}
diff --git a/qga/proclist/main.c b/qga/proclist/main.c
new file mode 100644
index 0000000..5be5f35
--- /dev/null
+++ b/qga/proclist/main.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include "process_list.h"
+
+int main() 
+{ 
+        ProcListT ProcList[1024]; 
+        int ret = getProcessList(ProcList); 
+        int i; 
+        for(i = 0; i < ret; ++i) 
+                printf("%s %s %d\n", ProcList[i].name, ProcList[i].path, ProcList[i].pid); 
+}
diff --git a/qga/proclist/process_list.c b/qga/proclist/process_list.c
new file mode 100644
index 0000000..f15b2de
--- /dev/null
+++ b/qga/proclist/process_list.c
@@ -0,0 +1,77 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "process_list.h"
+#ifdef _WIN32
+#include <windows.h>
+#include <tlhelp32.h>
+#include <psapi.h>
+
+void EnableDebugPriv()
+{
+    HANDLE hToken;
+    LUID luid;
+    TOKEN_PRIVILEGES tkp;
+
+    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
+
+    LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid);
+
+    tkp.PrivilegeCount = 1;
+    tkp.Privileges[0].Luid = luid;
+    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+    AdjustTokenPrivileges(hToken, 0, &tkp, sizeof(tkp), NULL, NULL);
+
+    CloseHandle(hToken); 
+}
+
+#endif
+
+int getProcessList(ProcListT *ProcList)
+{
+       int cnt = 0;
+#ifndef _WIN32
+       char cmd_pid_name[] = "ps --ppid 2 -p 2 -p 1 --deselect | awk '{if (NR!=1){print $1, $4}}'";
+       char cmd_path[] = "readlink -f /proc/%d/exe";
+       FILE *fp_pid_name, *fp_path ; if((fp_pid_name = popen(cmd_pid_name, "r")) == NULL){ return -1;
+       }
+       while(cnt < MAX_PROC_NUM && 
+               fscanf(fp_pid_name, "%d%s", &ProcList[cnt].pid, ProcList[cnt].name) == 2){
+               char tmp[50] = {0};
+               sprintf(tmp, cmd_path, ProcList[cnt].pid);
+               if((fp_path = popen(tmp, "r")) == NULL){
+                       return -1;
+               }
+               if(!fgets(ProcList[cnt].path, MAX_PATH_LEN, fp_path)) 
+                       sprintf(ProcList[cnt].path, "CANNOT FIND PATH!");
+               if(ProcList[cnt].path[strlen(ProcList[cnt].path)-1] == '\n')
+                       ProcList[cnt].path[strlen(ProcList[cnt].path)-1] = '\0';
+               pclose(fp_path);
+               ++cnt;
+       }
+       pclose(fp_pid_name);
+#else
+       EnableDebugPriv();
+       PROCESSENTRY32 entry;
+       entry.dwSize = sizeof(PROCESSENTRY32);
+       HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
+       if (Process32First(snapshot, &entry) == TRUE)
+       {
+           while (Process32Next(snapshot, &entry) == TRUE)
+           {
+               HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
+               char path[MAX_PATH] = {0};
+               GetModuleFileNameEx(hProcess, NULL, path, MAX_PATH);
+               sprintf(ProcList[cnt].name, "%s", entry.szExeFile);
+               sprintf(ProcList[cnt].path, "%s", path);
+               ProcList[cnt].pid = entry.th32ProcessID;
+               //printf("%s %d %s\n", entry.szExeFile, entry.th32ProcessID, path);
+               CloseHandle(hProcess);
+               ++cnt;
+           }
+       }
+       CloseHandle(snapshot);
+#endif
+       return cnt;
+}
diff --git a/qga/proclist/process_list.h b/qga/proclist/process_list.h
new file mode 100644
index 0000000..d670006
--- /dev/null
+++ b/qga/proclist/process_list.h
@@ -0,0 +1,20 @@
+#ifndef PROCESS_LIST_H
+#define PROCESS_LIST_H
+
+#define MAX_PATH_LEN 256
+#define MAX_PROC_LEN 256
+#define MAX_PROC_NUM 1024
+
+typedef struct{
+       char path[MAX_PATH_LEN];
+       char name[MAX_PROC_LEN];
+       int pid;
+}ProcListT;
+
+/*
+ *ProcList: process list
+ *return: number of process, 0 if error
+*/
+int getProcessList(ProcListT *ProcList);
+
+#endif
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index 80edca1..25cbb0e 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -642,3 +642,9 @@
 { 'command': 'guest-set-vcpus',
   'data':    {'vcpus': ['GuestLogicalProcessor'] },
   'returns': 'int' }
+
+{ 'type': 'GuestVmProgs',
+  'data': { 'name': 'str', 'path': 'str', 'pid': 'int'}}
+
+{ 'command': 'guest-get-progs',
+  'returns': ['GuestVmProgs']}