可以getopt解析参数。

也实现了将参数用空格分隔,来传给进程。

注意string和LPSTR数据类型的转换方法:

LPSTR(lpCmdLine.c_str())

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string>
#include <Userenv.h>
#include <Wtsapi32.h>
#pragma comment(lib, "WtsApi32.lib")
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "userenv.lib")
using namespace std;

#define EPR                 fprintf(stderr,
#define ERR(str, chr)       if(opterr){EPR "%s%c\n", str, chr);}
int     opterr = 1;
int     optind = 1;
int    optopt;
char    *optarg;

int getopt (int argc, char *const argv[], char *opts)
{
    static int sp = 1;
    int c;
    char *cp;

    if (sp == 1)
        if (optind >= argc ||
           argv[optind][0] != '-' || argv[optind][1] == '\0')
            return -1;
        else if (strcmp(argv[optind], "--") == 0) {
            optind++;
            return -1;
        }
    optopt = c = argv[optind][sp];
    if (c == ':' || (cp=strchr(opts, c)) == 0) {
        ERR (": illegal option -- ", c);
        if (argv[optind][++sp] == '\0') {
            optind++;
            sp = 1;
        }
        return '?';
    }
    if (*++cp == ':') {
        if (argv[optind][sp+1] != '\0')
            optarg = &argv[optind++][sp+1];
        else if (++optind >= argc) {
            ERR (": option requires an argument -- ", c);
            sp = 1;
            return '?';
        } else
            optarg = argv[optind++];
        sp = 1;
    } else {
        if (argv[optind][++sp] == '\0') {
            sp = 1;
            optind++;
        }
        optarg = 0;
    }
    return c;
}

HANDLE GetUserToken(DWORD dwSessionId)
{
    HANDLE hImpersonationToken = 0;
    if (!WTSQueryUserToken(dwSessionId, &hImpersonationToken))
    {
        printf(" WTSQueryUserToken ERROR: %d\n", GetLastError());
        return FALSE;
    }
    DWORD dwNeededSize = 0;
    HANDLE *realToken = new HANDLE;
    TOKEN_USER *pTokenUser = NULL;
    PTOKEN_GROUPS pGroups = NULL;
    //twice call function
    if (!GetTokenInformation(hImpersonationToken, TokenUser, NULL, 0, &dwNeededSize))
    {
        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER && dwNeededSize > 0)
        {
            pTokenUser = (TOKEN_USER*)new BYTE[dwNeededSize];
            if (!GetTokenInformation(hImpersonationToken, TokenUser, pTokenUser, dwNeededSize, &dwNeededSize))
            {
                printf("GetTokenInformation ERROR: %d", GetLastError());
            }
        }
        return hImpersonationToken;
    }
    return hImpersonationToken;
}

bool GetSessionUserName(DWORD dwSessionId, char username[256])
{
    LPTSTR pBuffer = NULL;
    DWORD dwBufferLen;
    if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, dwSessionId, WTSUserName, &pBuffer, &dwBufferLen))
    {
        printf(" WTSQuerySessionInformation ERROR: %d\n", GetLastError());
        return FALSE;
    }
    lstrcpy(username ,pBuffer);
    WTSFreeMemory(pBuffer);
    return TRUE;
}

void Usage(void)
{
    printf("**********************usage******************\n");
    printf("USAGE: path:\\callsession.exe sxxxn path-exe-file arg1 arg2 arg3 ... \n");
    printf("**********************usage******************\n");
}

int main(int argc, char** argv)
{
    if(argc == 1)
    {
        Usage();
        return FALSE;
    }
    else if(argc > 1)
    {
        /* get opt comment if we need chengang882@pingan.com.cn at 2016-08-23
        int c;

        while ((c = getopt(argc, argv, "MNOVv+I:D:U:F:lg")) != -1)
            switch (c) {
            case 'N':

                break;
            case 'I':
                puts(optarg);

                break;
            case 'D':
            case 'U':
                puts(optarg);
                break;
            case 'M':

                break;
            case 'v':

                break;
            case 'V':

                break;
            case '+':

                break;
            default:
                break;
            }
        */
        int i;
        string lpCmdLine = "";
        LPSTR lpUsername;
        DWORD session_id = -1;
        DWORD session_count = 0;
        WTS_SESSION_INFOA *pSession = NULL;
        char username[256];
        BOOL blFound = FALSE;
        lpUsername = argv[1];
        // add all $2 $3 $4 $5 ... as second argument to program.
        for (i=2; i < argc; i++)
        {
            // printf("argument %d is %s.\n", i, argv[i]);
            lpCmdLine += argv[i];
            lpCmdLine += " ";
        }
        // printf("argument is %s\n", lpCmdLine);

        //EnumerateSessions
        if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSession, &session_count))
        {
            printf("WTSEnumerateSessions ERROR: %d", GetLastError());
            return FALSE;
        }
        //Get the right user and his session id
        for(DWORD i = 0; i < session_count; ++i)
        {
            GetSessionUserName(pSession[i].SessionId,username);
            //if( (pSession[i].State == WTSActive) && (pSession[i].State != WTSDisconnected) )
            if(!strcmp(lpUsername, username))
            {
                printf("\tSession user name = %s\n",username);
                session_id = pSession[i].SessionId;
                printf("\tsession_id = %d\n",session_id);
                blFound = TRUE;
                break;
            }
        }
        if (!blFound){
            printf("No login username %s found.", lpUsername);
            return FALSE;
        }
        WTSFreeMemory(pSession); //free meme heap
        //Duplicate User Token
        HANDLE hTokenThis = GetUserToken(session_id);
        HANDLE hTokenDup = NULL;
        if (!DuplicateTokenEx(hTokenThis, TOKEN_ALL_ACCESS, NULL, SecurityIdentification, TokenPrimary, &hTokenDup))
        {
            printf("DuplicateTokenEx ERROR: %d\n", GetLastError());
            return FALSE;
        }
        if (!SetTokenInformation(hTokenDup, TokenSessionId, &session_id, sizeof(DWORD)))
        {
             printf("SetTokenInformation Error === %d\n",GetLastError());
             return FALSE;
        }
        //init this process info
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
        ZeroMemory(&si, sizeof(STARTUPINFO));
        ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
        si.cb = sizeof(STARTUPINFO);
        si.lpDesktop = "WinSta0\\Default";
        //LPVOID pEnv = NULL;
        DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
        //CreateEnvironmentBlock(&pEnv, hTokenDup, FALSE);
        if (!CreateProcessAsUser(hTokenDup, NULL, LPSTR(lpCmdLine.c_str()), NULL, NULL, FALSE, dwCreationFlag, NULL, NULL, &si, &pi))
        {
            printf("CreateProcessAsUser Error === %d\n",GetLastError());
            return FALSE;
        }
        printf("%s--%s--%s", lpUsername, LPSTR(lpCmdLine.c_str()), "OK");
    }

    return 0;
}

  

callsession新功能版的更多相关文章

  1. VS2015预览版中的C#6.0 新功能(二)

    VS2015预览版中的C#6.0 新功能(一) VS2015预览版中的C#6.0 新功能(三) 自动属性的增强 只读自动属性 以前自动属性必须同时提供setter和getter方法,因而只读属性只能通 ...

  2. VS2015预览版中的C#6.0 新功能(三)

    VS2015预览版中的C#6.0 新功能(一) VS2015预览版中的C#6.0 新功能(二) Using static 使用using StaticClass,你可以访问StaticClass类里的 ...

  3. VS2015预览版中的C#6.0 新功能(一)

    VS2015预览版中的C#6.0 新功能(二) VS2015预览版中的C#6.0 新功能(三) VS2015的预览版在11月12日发布了,下面让我们来看看C#都提供了哪些新的功能. 字符串添写(Str ...

  4. WordPress版微信小程序3.1.5版的新功能

    产品的完善是无止境,每过段时间就会发现产品的新问题,使用的人越多,提的需求也会越多,我听得最多的一句话就是:如果加上某某功能就完美了.其实,完美是不存在的,每个人的视角不一样,完美的定义也是不一样的. ...

  5. Android Studio 2.3 正式版新功能,你不来看看?!

    2017.3.3 Google老大发布了Android Studio 2.3正式版. 在许多2.3beta版本的基础上修复了bug然后推出了正式版.提供了一些新特性,和对部分已有功能的修改完善. Bu ...

  6. Android O 正式版新功能

    ref: Android O新特性和行为变更总结zzhttp://www.cnblogs.com/bluestorm/p/7148134.html Android O正式版带来了诸多新功能,如Tens ...

  7. 【转】odoo11新功能及绿色版汇总

    昆山-Jeffery 11:34:00 ,odoo11 新功能: 评论:看到截图,感觉美工上又有所提高 官方的发布说明:https://www.odoo.com/nl_NL/page/odoo-11- ...

  8. Redis 6.0 正式版终于发布了!除了多线程还有什么新功能?

    Redis 6.0.1 于 2020 年 5 月 2 日正式发布了,如 Redis 作者 antirez 所说,这是迄今为止最"企业"化的版本,也是有史以来改动最大的一个 Redi ...

  9. .NET 6 预览版 7:新功能已完成 ,将专注于改进

    .NET 团队的项目经理 Richard Lander在宣布 .NET 6 Preview 7 时说:"这是 .NET 预览的又一季的结束.", 中文翻译:.NET 6 预览版 7 ...

随机推荐

  1. The C Programming Language (second edition) 实践代码(置于此以作备份)

    1. #include <stdio.h> #include <stdlib.h> #include <math.h> #include<time.h> ...

  2. ARP欺骗病毒,网页“篡改”,注入iframe代码!

    ---------------权威资料看这里--------------- 清华大学信息网络工程研究中心-中国教育和科研计算机网应急响应组<ARP 欺骗网页劫持攻击分析>PDF文件,直接I ...

  3. Jquery 扩展获取RUL参数

    //扩展获取url $.extend({ getUrlVars: function () { var vars = [], hash; var hashes = window.location.hre ...

  4. [bug]使用SharpZipLib遇到中文名称乱码问题

    写在前面 业务逻辑是这样的,需要导出一个app的话题,并需要把该话题下帖子的附件导出,然后需求想修改成人员的名称.jpg的格式.所以就出现了中文乱码的问题.在本地没问题,但发布到服务器上面就出问题,每 ...

  5. motto3

    在我看来,最努力的人不一定能收获最好的,但不努力的人是必定收获不到任何东西的. 所以,园主,你要会努力才行.否则,你会累死的. 用心去学,用脑去想,认真对待每一件事,聪明一点,不要太愚蠢.

  6. 你无法修改 Git 的历史记录

    转自:http://www.oschina.net/news/26241/you-can-not-change-git-history 有时候使用Git工作得小心翼翼,特别是涉及到一些高级操作,例如 ...

  7. (转)win32Application和win32ApplicationConsole

    这几天在创建MFC项目时,常常遇到一下两个连接错误,例如: 1. LIBCD.lib(crt0.obj) : error LNK2001: unresolved external symbol _ma ...

  8. Hadoop之 hdfs 系统

    一.NameNode维护着2张表: 1.文件系统的目录结构,以及元数据信息 2.文件与数据块列表的对应关系 存放在fsimage中,在运行的时候加载到内存中的. 操作日志写到edits中   二.Da ...

  9. php面试题之三——PHP网络编程(高级部分)

    三.PHP网络编程 [!!!]1.禁用COOKIE后SEESION还能用吗?(51.com笔试题) 可以,COOKIE和SESSION都是用来实现会话机制的,由于http协议是无状态的,所以要想跟踪一 ...

  10. sizeof()和strlen()的区别与联系

    参考:http://www.cnblogs.com/carekee/articles/1630789.html 1.sizeof是运算符,其值在编译时即计算好了,参数可以是数组.指针.类型.对象.函数 ...