Windows下appcontainer进程和普通进程之间有ipc的方式吗?

2024-01-09

我正在尝试在 Windows 中的 appcontainer 进程和普通进程之间建立 ipc。

我在Windows appcontainer中做了一个进程,感谢这个article https://www.malwaretech.com/2015/09/advanced-desktop-application-sandboxing.html。但是,我不知道如何在 appcontainer 中的进程和普通进程之间进行通信。

我尝试使用命名管道进行通信,但 appcontainer 进程出现错误“访问被拒绝”。 (GetLastError() 返回 5)。 然后我尝试了套接字(localhost),但它们没有连接,即使端口号相同。

我检查了很多文章来解决这个问题......但我确实失败了。 这是我查过的文章。

  • https://learn.microsoft.com/ko-kr/windows/win32/api/securityappcontainer/nf-securityappcontainer-getappcontainernamedobjectpath?redirectedfrom=MSDN https://learn.microsoft.com/ko-kr/windows/win32/api/securityappcontainer/nf-securityappcontainer-getappcontainernamedobjectpath?redirectedfrom=MSDN
  • 有没有办法在 IE11 上从 AppContainer BHO 创建命名管道? https://stackoverflow.com/questions/18982221/is-there-a-way-to-create-a-named-pipe-from-an-appcontainer-bho-on-ie11
  • https://learn.microsoft.com/en-us/windows/win32/secauthz/modifying-the-acls-of-an-object-in-c-- https://learn.microsoft.com/en-us/windows/win32/secauthz/modifying-the-acls-of-an-object-in-c--
  • 以低完整性级别打开命名管道 https://stackoverflow.com/questions/3282365/opening-a-named-pipe-in-low-integrity-level
  • https://learn.microsoft.com/en-us/windows/win32/ipc/transactions-on-named-pipes https://learn.microsoft.com/en-us/windows/win32/ipc/transactions-on-named-pipes
  • https://social.msdn.microsoft.com/Forums/Windowsapps/en-US/e92502b1-0b9f-4e02-9d72-e4e47e924a8f/accessing-named-objects-from-an-appcontainer?forum=windowssecurity https://social.msdn.microsoft.com/Forums/Windowsapps/en-US/e92502b1-0b9f-4e02-9d72-e4e47e924a8f/accessing-named-objects-from-an-appcontainer?forum=windowssecurity
  • AppContainer完整性级别 https://stackoverflow.com/questions/29611047/appcontainer-integrity-level
  • http://recxltd.blogspot.com/2012/03/windows-8-app-container-security-notes.html http://recxltd.blogspot.com/2012/03/windows-8-app-container-security-notes.html
  • https://www.malwaretech.com/2015/09/advanced-desktop-application-sandboxing.html https://www.malwaretech.com/2015/09/advanced-desktop-application-sandboxing.html

我想知道有没有一种方法可以在正常进程和 Windows 应用程序容器中的进程之间进行 ipc。

我正在以下环境中工作。

  • Windows 10
  • 视觉工作室 2019

这是我的代码。

#include <iostream>

#include <Windows.h>
#include <strsafe.h>
#include <Sddl.h>
#include <AccCtrl.h>
#include <AclAPI.h>
#include <UserEnv.h>

#pragma comment(lib, "Userenv.lib")

//List of allowed capabilities for the application
extern WELL_KNOWN_SID_TYPE app_capabilities[] =
{
    WinCapabilityInternetClientSid,
    //WinCapabilityPrivateNetworkClientServerSid,
};

WCHAR container_name[] = L"SandboxTest";
WCHAR container_desc[] = L"Sandbox Test";

BOOL IsInAppContainer();
BOOL SetSecurityCapabilities(PSID container_sid, SECURITY_CAPABILITIES* capabilities, PDWORD num_capabilities);
BOOL GrantNamedObjectAccess(PSID appcontainer_sid, HANDLE object_handle, SE_OBJECT_TYPE object_type, DWORD access_mask);
DWORD AddDACLToObject(PSID appcontainer_sid, HANDLE hObj, SE_OBJECT_TYPE seObjectType);
BOOL CreateObjectSecurityDescriptor(PSID pLogonSid, PSECURITY_DESCRIPTOR* ppSD);
BOOL GetLogonSid(HANDLE hToken, PSID* ppsid);
int ConnectClient(HANDLE hNamePipe);

BOOL IsInAppContainer()
{
    HANDLE process_token;
    BOOL is_container = 0;
    DWORD return_length;

    OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &process_token);

    if (!GetTokenInformation(process_token, TokenIsAppContainer, &is_container, sizeof is_container, &return_length))
        return false;
    return is_container;
}

HANDLE hNamePipe;

BOOL RunExecutableInContainer(CHAR* executable_path)
{
    PSID sid = NULL;
    HRESULT result;

    SECURITY_CAPABILITIES SecurityCapabilities = { 0 };

    DWORD num_capabilities = 0;
    SIZE_T attribute_size = 0;

    STARTUPINFOEXA startup_info = { 0 };
    PROCESS_INFORMATION process_info = { 0 };

    CHAR* string_sid = NULL;
    BOOL success = FALSE;
    HANDLE hToken = NULL;
    HANDLE  hNewToken = NULL;
    PSID  pIntegritySid = NULL;

    TOKEN_MANDATORY_LABEL TIL = { 0 };
    CHAR wszIntegritySid[20] = "S-1-16-4096";
    //4096
    //8192

    // HANDLE hNamePipe;
    CHAR pipe_name[] = "\\\\.\\pipe\\LOCAL";

    do {
        result = CreateAppContainerProfile(container_name, container_name, container_desc, NULL, 0, &sid);
        if (!SUCCEEDED(result))
        {
            if (HRESULT_CODE(result) == ERROR_ALREADY_EXISTS)
            {
                result = DeriveAppContainerSidFromAppContainerName(container_name, &sid);
                if (!SUCCEEDED(result))
                {
                    printf("Failed to get existing AppContainer name, error code: %d", HRESULT_CODE(result));
                    break;
                }
            }
            else {
                printf("Failed to create AppContainer, last error: %d\n", HRESULT_CODE(result));
                break;
            }
        }

        printf("[Container Info]\nname: %ws\ndescription: %ws\n", container_name, container_desc);

        if (ConvertSidToStringSidA(sid, &string_sid))
            printf("Sid: %s\n\n", string_sid);

        if (!SetSecurityCapabilities(sid, &SecurityCapabilities, &num_capabilities))
        {
            printf("Failed to set security capabilities, last error: %d\n", GetLastError());
            break;
        }
        /*
        // pipe
        hNamePipe = CreateNamedPipe(
            pipe_name,
            PIPE_ACCESS_DUPLEX,
            PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
            PIPE_UNLIMITED_INSTANCES,
            0,
            0,
            20000,
            NULL);

        if (hNamePipe == INVALID_HANDLE_VALUE)
        {
            printf("CreateNamePipe error! \n");
            break;
        }

        if (!GrantNamedObjectAccess(sid, hNamePipe, SE_KERNEL_OBJECT, FILE_ALL_ACCESS))
        {
            printf("Failed to grant explicit access to %s\n", pipe_name);
            DisconnectNamedPipe(hNamePipe);
            CloseHandle(hNamePipe);
            break;
        }
        */

        /*
        hNamePipe = CreateNamedPipe(
            pipe_name,
            PIPE_ACCESS_DUPLEX,
            PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
            PIPE_UNLIMITED_INSTANCES,
            0,
            0,
            20000,
            NULL);

        if (AddDACLToObject(sid, hNamePipe, SE_KERNEL_OBJECT))
        {
            printf("Failed to grant explicit access to %s\n", pipe_name);
            break;
        }*/

        /*
        PSID pLogonSid = NULL;
        PSECURITY_DESCRIPTOR pSd = NULL;
        SECURITY_ATTRIBUTES  SecurityAttributes;
        HANDLE hToken = NULL;

        OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken);
        pLogonSid = (PSID)malloc(sizeof(PSID));

        //Allowing LogonSid and all appcontainers. 
        if (GetLogonSid(hToken, &pLogonSid) && CreateObjectSecurityDescriptor(pLogonSid, &pSd))
        {
            SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
            SecurityAttributes.bInheritHandle = TRUE;
            SecurityAttributes.lpSecurityDescriptor = pSd;

            hNamePipe = CreateNamedPipe(
                pipe_name,
                PIPE_ACCESS_DUPLEX,
                PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
                PIPE_UNLIMITED_INSTANCES,
                0,
                0,
                20000,
                &SecurityAttributes);
            printf("pipe created\n");
        }
        */

        InitializeProcThreadAttributeList(NULL, 1, NULL, &attribute_size);
        startup_info.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)malloc(attribute_size);

        if (!InitializeProcThreadAttributeList(startup_info.lpAttributeList, 1, NULL, &attribute_size))
        {
            printf("InitializeProcThreadAttributeList() failed, last error: %d", GetLastError());
            break;
        }

        if (!UpdateProcThreadAttribute(startup_info.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES,
            &SecurityCapabilities, sizeof(SecurityCapabilities), NULL, NULL))
        {
            printf("UpdateProcThreadAttribute() failed, last error: %d", GetLastError());
            break;
        }

        if (!OpenProcessToken(GetCurrentProcess(),
            TOKEN_DUPLICATE |
            TOKEN_ADJUST_DEFAULT |
            TOKEN_QUERY |
            TOKEN_ASSIGN_PRIMARY,
            &hToken))
        {
            break;
        }

        if (!DuplicateTokenEx(hToken,
            0,
            NULL,
            SecurityImpersonation,
            TokenPrimary,
            &hNewToken))
        {
            break;
        }

        if (!ConvertStringSidToSid(wszIntegritySid, &pIntegritySid))
        {
            break;
        }
        TIL.Label.Attributes = SE_GROUP_INTEGRITY;
        TIL.Label.Sid = pIntegritySid;

        if (!SetTokenInformation(hNewToken,
            TokenIntegrityLevel,
            &TIL,
            sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(pIntegritySid)))
        {
            break;
        }

        if (!CreateProcessAsUser(hNewToken,
            executable_path,
            NULL,
            NULL,
            NULL,
            FALSE,
            EXTENDED_STARTUPINFO_PRESENT,
            NULL,
            NULL,
            (LPSTARTUPINFOA)& startup_info,
            &process_info))
        {
            printf("Failed to create process %s, last error: %d\n", executable_path, GetLastError());
            break;
        }

        printf("Successfully executed %s in AppContainer\n", executable_path);
        success = TRUE;

    } while (FALSE);

    if (startup_info.lpAttributeList)
        DeleteProcThreadAttributeList(startup_info.lpAttributeList);

    if (SecurityCapabilities.Capabilities)
        free(SecurityCapabilities.Capabilities);

    if (sid)
        FreeSid(sid);

    if (string_sid)
        LocalFree(string_sid);

    if (process_info.hProcess != NULL)
        CloseHandle(process_info.hProcess);

    if (process_info.hThread != NULL)
        CloseHandle(process_info.hThread);

    LocalFree(pIntegritySid);

    if (hNewToken != NULL)
        CloseHandle(hNewToken);

    if (hToken != NULL)
        CloseHandle(hToken);

    return success;
}

/*
    Set the security capabilities of the container to those listed in app_capabilities
*/
BOOL SetSecurityCapabilities(PSID container_sid, SECURITY_CAPABILITIES* capabilities, PDWORD num_capabilities)
{
    DWORD sid_size = SECURITY_MAX_SID_SIZE;
    DWORD num_capabilities_ = sizeof(app_capabilities) / sizeof(DWORD);
    SID_AND_ATTRIBUTES* attributes;
    BOOL success = TRUE;

    attributes = (SID_AND_ATTRIBUTES*)malloc(sizeof(SID_AND_ATTRIBUTES) * num_capabilities_);

    ZeroMemory(capabilities, sizeof(SECURITY_CAPABILITIES));
    ZeroMemory(attributes, sizeof(SID_AND_ATTRIBUTES) * num_capabilities_);

    for (unsigned int i = 0; i < num_capabilities_; i++)
    {
        attributes[i].Sid = malloc(SECURITY_MAX_SID_SIZE);
        if (!CreateWellKnownSid(app_capabilities[i], NULL, attributes[i].Sid, &sid_size))
        {
            success = FALSE;
            break;
        }
        attributes[i].Attributes = SE_GROUP_ENABLED;
    }

    if (success == FALSE)
    {
        for (unsigned int i = 0; i < num_capabilities_; i++)
        {
            if (attributes[i].Sid)
                LocalFree(attributes[i].Sid);
        }

        free(attributes);
        attributes = NULL;
        num_capabilities_ = 0;
    }

    capabilities->Capabilities = attributes;
    capabilities->CapabilityCount = num_capabilities_;
    capabilities->AppContainerSid = container_sid;
    *num_capabilities = num_capabilities_;

    return success;
}

/*
    Explicitly grants the container access to a named object (file, section, etc)
*/
BOOL GrantNamedObjectAccess(PSID appcontainer_sid, HANDLE object_handle, SE_OBJECT_TYPE object_type, DWORD access_mask)
{
    EXPLICIT_ACCESS_A explicit_access;
    PACL original_acl = NULL, new_acl = NULL;
    DWORD status;
    BOOL success = FALSE;

    do
    {
        explicit_access.grfAccessMode = GRANT_ACCESS;
        explicit_access.grfAccessPermissions = access_mask;
        explicit_access.grfInheritance = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;

        explicit_access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
        explicit_access.Trustee.pMultipleTrustee = NULL;
        explicit_access.Trustee.ptstrName = (CHAR*)appcontainer_sid;
        explicit_access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
        explicit_access.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;

        status = GetSecurityInfo(object_handle, object_type, DACL_SECURITY_INFORMATION, NULL, NULL, &original_acl,
            NULL, NULL);
        if (status != ERROR_SUCCESS)
        {
            printf("GetSecurityInfo() failed, error: %d\n", status);
            break;
        }

        status = SetEntriesInAclA(1, &explicit_access, original_acl, &new_acl);
        if (status != ERROR_SUCCESS)
        {
            printf("SetEntriesInAclA() failed, error: %d\n", status);
            break;
        }

        status = SetSecurityInfo(object_handle, object_type, DACL_SECURITY_INFORMATION, NULL, NULL, new_acl, NULL);
        if (status != ERROR_SUCCESS)
        {
            printf("SetSecurityInfo() failed, error: %d\n", status);
            break;
        }

        success = TRUE;

    } while (FALSE);

    if (original_acl)
        LocalFree(original_acl);

    if (new_acl)
        LocalFree(new_acl);

    return success;
}

DWORD AddDACLToObject(PSID appcontainer_sid, HANDLE hObj, SE_OBJECT_TYPE seObjectType)
{
    LPSTR szAddSid = (LPSTR)"S-1-15-2-1";
    // LPWSTR szAddSid = L"S-1-15-2-1";//SID_ALL_APP_PACKAGES;

    PACL pACL = NULL;
    DWORD dwRes;
    PSID pSIDAllAppPackage = NULL;

    PSECURITY_DESCRIPTOR pSDOld = NULL;
    PACL pOldDACL = NULL;
    dwRes = GetSecurityInfo(hObj, seObjectType,
        DACL_SECURITY_INFORMATION,
        NULL, NULL, &pOldDACL, NULL, &pSDOld);
    if (ERROR_SUCCESS != dwRes)
    {
        return dwRes;
    }

    if (ConvertStringSidToSid(szAddSid, &pSIDAllAppPackage) == FALSE)
    {
        dwRes = GetLastError();
        return dwRes;
    }

    const int NUM_ACES = 1;
    EXPLICIT_ACCESS ea[NUM_ACES];
    ZeroMemory(&ea, NUM_ACES * sizeof(EXPLICIT_ACCESS));

    ea[0].grfAccessPermissions = GENERIC_ALL;
    ea[0].grfAccessMode = SET_ACCESS;
    ea[0].grfInheritance = NO_INHERITANCE;
    ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[0].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
    ea[0].Trustee.ptstrName = (LPTSTR)appcontainer_sid;

    dwRes = SetEntriesInAcl(NUM_ACES, ea, pOldDACL, &pACL);
    if (ERROR_SUCCESS != dwRes)
    {
        return dwRes;
    }

    dwRes = SetSecurityInfo(
        hObj,                      // name of the object
        seObjectType,              // type of object
        DACL_SECURITY_INFORMATION, // change only the object's DACL
        NULL, NULL,                // do not change owner or group
        pACL,                      // DACL specified
        NULL);                     // do not change SACL
    return dwRes;
}

BOOL GetLogonSid(HANDLE hToken, PSID* ppsid)
{
    BOOL bSuccess = FALSE;
    DWORD dwLength = 0;
    PTOKEN_GROUPS ptg = NULL;

    // Verify the parameter passed in is not NULL.
    if (NULL == ppsid)
        goto Cleanup;

    // Get required buffer size and allocate the TOKEN_GROUPS buffer.

    if (!GetTokenInformation(
        hToken,         // handle to the access token
        TokenLogonSid,    // get information about the token's groups 
        (LPVOID)ptg,   // pointer to TOKEN_GROUPS buffer
        0,              // size of buffer
        &dwLength       // receives required buffer size
    ))
    {
        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
            goto Cleanup;

        ptg = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(),
            HEAP_ZERO_MEMORY, dwLength);

        if (ptg == NULL)
            goto Cleanup;
    }

    // Get the token group information from the access token.

    if (!GetTokenInformation(
        hToken,         // handle to the access token
        TokenLogonSid,    // get information about the token's groups 
        (LPVOID)ptg,   // pointer to TOKEN_GROUPS buffer
        dwLength,       // size of buffer
        &dwLength       // receives required buffer size
    ) || ptg->GroupCount != 1)
    {
        goto Cleanup;
    }

    // Found the logon SID; make a copy of it.

    dwLength = GetLengthSid(ptg->Groups[0].Sid);
    *ppsid = (PSID)HeapAlloc(GetProcessHeap(),
        HEAP_ZERO_MEMORY, dwLength);
    if (*ppsid == NULL)
        goto Cleanup;
    if (!CopySid(dwLength, *ppsid, ptg->Groups[0].Sid))
    {
        HeapFree(GetProcessHeap(), 0, (LPVOID)* ppsid);
        goto Cleanup;
    }

    bSuccess = TRUE;

Cleanup:

    // Free the buffer for the token groups.

    if (ptg != NULL)
        HeapFree(GetProcessHeap(), 0, (LPVOID)ptg);

    return bSuccess;
}

BOOL
CreateObjectSecurityDescriptor(PSID pLogonSid, PSECURITY_DESCRIPTOR* ppSD)
{
    BOOL bSuccess = FALSE;
    DWORD dwRes;
    PSID pAllAppsSID = NULL;
    PACL pACL = NULL;
    PSECURITY_DESCRIPTOR pSD = NULL;
    EXPLICIT_ACCESS ea[2];
    SID_IDENTIFIER_AUTHORITY ApplicationAuthority = SECURITY_APP_PACKAGE_AUTHORITY;

    // Create a well-known SID for the all appcontainers group.
    if (!AllocateAndInitializeSid(&ApplicationAuthority,
        SECURITY_BUILTIN_APP_PACKAGE_RID_COUNT,
        SECURITY_APP_PACKAGE_BASE_RID,
        SECURITY_BUILTIN_PACKAGE_ANY_PACKAGE,
        0, 0, 0, 0, 0, 0,
        &pAllAppsSID))
    {
        wprintf(L"AllocateAndInitializeSid Error %u\n", GetLastError());
        goto Cleanup;
    }

    // Initialize an EXPLICIT_ACCESS structure for an ACE.
    // The ACE will allow LogonSid generic all access
    ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS));
    ea[0].grfAccessPermissions = STANDARD_RIGHTS_ALL | MUTEX_ALL_ACCESS;
    ea[0].grfAccessMode = SET_ACCESS;
    ea[0].grfInheritance = NO_INHERITANCE;
    ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[0].Trustee.TrusteeType = TRUSTEE_IS_USER;
    ea[0].Trustee.ptstrName = (LPTSTR)pLogonSid;

    // Initialize an EXPLICIT_ACCESS structure for an ACE.
    // The ACE will allow the all appcontainers execute permission
    ea[1].grfAccessPermissions = STANDARD_RIGHTS_READ | STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | MUTEX_MODIFY_STATE;
    ea[1].grfAccessMode = SET_ACCESS;
    ea[1].grfInheritance = NO_INHERITANCE;
    ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
    ea[1].Trustee.ptstrName = (LPTSTR)pAllAppsSID;

    // Create a new ACL that contains the new ACEs.
    dwRes = SetEntriesInAcl(2, ea, NULL, &pACL);
    if (ERROR_SUCCESS != dwRes)
    {
        wprintf(L"SetEntriesInAcl Error %u\n", GetLastError());
        goto Cleanup;
    }

    // Initialize a security descriptor.  
    pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR,
        SECURITY_DESCRIPTOR_MIN_LENGTH);
    if (NULL == pSD)
    {
        wprintf(L"LocalAlloc Error %u\n", GetLastError());
        goto Cleanup;
    }

    if (!InitializeSecurityDescriptor(pSD,
        SECURITY_DESCRIPTOR_REVISION))
    {
        wprintf(L"InitializeSecurityDescriptor Error %u\n",
            GetLastError());
        goto Cleanup;
    }

    // Add the ACL to the security descriptor. 
    if (!SetSecurityDescriptorDacl(pSD,
        TRUE,     // bDaclPresent flag   
        pACL,
        FALSE))   // not a default DACL 
    {
        wprintf(L"SetSecurityDescriptorDacl Error %u\n",
            GetLastError());
        goto Cleanup;
    }

    *ppSD = pSD;
    pSD = NULL;
    bSuccess = TRUE;
Cleanup:

    if (pAllAppsSID)
        FreeSid(pAllAppsSID);
    if (pACL)
        LocalFree(pACL);
    if (pSD)
        LocalFree(pSD);

    return bSuccess;
}

int ConnectClient(HANDLE hNamePipe)
{
    TCHAR recvMessage[100];
    TCHAR sendMessage[100];
    DWORD recvSize;
    DWORD sendSize;

    while (1)
    {
        printf("Input Send Message : ");
        scanf("%s", sendMessage);

        if (!(WriteFile(
            hNamePipe,
            sendMessage,
            (strlen(sendMessage) + 1) * sizeof(TCHAR),
            &sendSize,
            NULL)))
        {
            printf("WriteFile error! \n");
            return -1;
        }
        FlushFileBuffers(hNamePipe);

        if (!(ReadFile(
            hNamePipe,
            recvMessage,
            sizeof(recvMessage) - sizeof(TCHAR) * 1,
            &recvSize,
            NULL)))
        {
            printf("ReadFile error! \n");
            return -1;
        }

        recvMessage[recvSize / sizeof(TCHAR) - 1] = '\x00';
        printf("Recv Message : %s \n", recvMessage);
    }
    return 1;
}

int main()
{
    CHAR path[] = "D:\\Projects\\Visual Studio Project\\SandboxTest\\socket.exe";
    std::cout << IsInAppContainer();
    RunExecutableInContainer(path);

    getchar();
}

None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Windows下appcontainer进程和普通进程之间有ipc的方式吗? 的相关文章

  • 访问私人成员[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 通过将类的私有成员转换为 void 指针 然后转换为结构来访问类的私有成员是否合适 我认为我无权修改包含我需要访问的数据成员的类 如果不道德 我
  • Qt-Qlist 检查包含自定义类

    有没有办法覆盖加载自定义类的 Qt QList 的比较机制 即在 java 中你只需要重写一个比较方法 我有一个带有我的自定义类模型的 QList QList
  • 获取按下的按钮的返回值

    我有一个在特定事件中弹出的表单 它从数组中提取按钮并将标签值设置为特定值 因此 如果您要按下或单击此按钮 该函数应返回标签值 我怎样才能做到这一点 我如何知道点击了哪个按钮 此时代码返回 DialogResult 但我想从函数返回 Tag
  • 如何避免情绪低落?

    我有一个实现状态模式每个状态处理从事件队列获取的事件 根据State因此类有一个纯虚方法void handleEvent const Event 事件继承基础Event类 但每个事件都包含其可以是不同类型的数据 例如 int string
  • linux perf:如何解释和查找热点

    我尝试了linux perf https perf wiki kernel org index php Main Page今天很实用 但在解释其结果时遇到了困难 我习惯了 valgrind 的 callgrind 这当然是与基于采样的 pe
  • 如何忽略“有符号和无符号整数表达式之间的比较”?

    谁能告诉我必须使用哪个标志才能使 gcc 忽略 有符号和无符号整数表达式之间的比较 警告消息 gcc Wno sign compare 但你确实应该修复它警告你的比较
  • Json.NET - 反序列化接口属性引发错误“类型是接口或抽象类,无法实例化”

    我有一个类 其属性是接口 public class Foo public int Number get set public ISomething Thing get set 尝试反序列化Foo使用 Json NET 的类给我一条错误消息
  • 指针减法混乱

    当我们从另一个指针中减去一个指针时 差值不等于它们相距多少字节 而是等于它们相距多少个整数 如果指向整数 为什么这样 这个想法是你指向内存块 06 07 08 09 10 11 mem 18 24 17 53 7 14 data 如果你有i
  • vector 超出范围后不清除内存

    我遇到了以下问题 我不确定我是否错了或者它是一个非常奇怪的错误 我填充了一个巨大的字符串数组 并希望在某个点将其清除 这是一个最小的例子 include
  • 在数据库中搜索时忽略空文本框

    此代码能够搜索数据并将其加载到DataGridView基于搜索表单文本框中提供的值 如果我将任何文本框留空 则不会有搜索结果 因为 SQL 查询是用 AND 组合的 如何在搜索 从 SQL 查询或 C 代码 时忽略空文本框 private
  • 将自定义元数据添加到 jpeg 文件

    我正在开发一个图像处理项目 C 我需要在处理完成后将自定义元数据写入 jpeg 文件 我怎样才能做到这一点 有没有可用的图书馆可以做到这一点 如果您正在谈论 EXIF 元数据 您可能需要查看exiv2 http www exiv2 org
  • 如何在 VBA 中声明接受 XlfOper (LPXLOPER) 类型参数的函数?

    我在之前的回答里发现了问题 https stackoverflow com q 19325258 159684一种无需注册即可调用 C xll 中定义的函数的方法 我之前使用 XLW 提供的注册基础结构 并且使用 XlfOper 类型在 V
  • C++ 复制初始化和直接初始化,奇怪的情况

    在继续阅读本文之前 请阅读在 C 中 复制初始化和直接初始化之间有区别吗 https stackoverflow com questions 1051379 is there a difference in c between copy i
  • 如何使我的表单标题栏遵循 Windows 深色主题?

    我已经下载了Windows 10更新包括黑暗主题 文件资源管理器等都是深色主题 但是当我创建自己的 C 表单应用程序时 标题栏是亮白色的 如何使我自己的桌面应用程序遵循我在 Windows 中设置的深色主题 你需要调用DwmSetWindo
  • C++ fmt 库,仅使用格式说明符格式化单个参数

    使用 C fmt 库 并给定一个裸格式说明符 有没有办法使用它来格式化单个参数 example std string str magic format 2f 1 23 current method template
  • 为什么 C# Math.Ceiling 向下舍入?

    我今天过得很艰难 但有些事情不太对劲 在我的 C 代码中 我有这样的内容 Math Ceiling decimal this TotalRecordCount this PageSize Where int TotalRecordCount
  • 为什么我收到“找不到编译动态表达式所需的一种或多种类型。”?

    我有一个已更新的项目 NET 3 5 MVC v2 到 NET 4 0 MVC v3 当我尝试使用或设置时编译出现错误 ViewBag Title财产 找不到编译动态表达式所需的一种或多种类型 您是否缺少对 Microsoft CSharp
  • Validation.ErrorTemplate 的 Wpf 动态资源查找

    在我的 App xaml 中 我定义了一个资源Validation ErrorTemplate 这取决于动态BorderBrush资源 我打算定义独特的BorderBrush在我拥有的每个窗口以及窗口内的不同块内
  • 限制C#中的并行线程数

    我正在编写一个 C 程序来生成并通过 FTP 上传 50 万个文件 我想并行处理4个文件 因为机器有4个核心 文件生成需要更长的时间 是否可以将以下 Powershell 示例转换为 C 或者是否有更好的框架 例如 C 中的 Actor 框
  • 恢复上传文件控制

    我确实阅读了以下帖子 C 暂停 恢复上传 https stackoverflow com questions 1048330 pause resume upload in c 使用 HTTP 恢复上传 https stackoverflow

随机推荐

  • 初始化结构体包含对结构体的引用

    是否可以有一个包含对结构的引用的结构 这些是如何初始化的 请参阅下面的简短示例 Thanks typedef struct int a typeInner1 typedef struct int b typeInner2 typedef s
  • 如何检测响应式网页设计的屏幕尺寸?

    我用谷歌搜索了这个并得到了怪异模式网站 http www quirksmode org m tests widthtest html这给了你你的屏幕尺寸 拉起控制台我看到screen width and screen height可以直接从
  • 如何使对象正确地可散列?

    这是我的代码 class Hero def init self name age self name name self age age def str self return self name str self age def hash
  • 正则表达式匹配域扩展

    我需要确认域扩展名是否存在 到目前为止 我还无法获得域名扩展的匹配项 其中域名可以包含通配符 gmail com msn com mac com comcast net DomainPartOfEmail Right temp Len te
  • C++ 从 CreateProcess() 获取 UTF-8 输出

    我无法让它工作 所以我得到 UTF 8 输出CreateProcess into wstring 目前我正在运行此方法来执行此操作 但没有 UTF 8 输出 HANDLE g hChildStd OUT Rd NULL HANDLE g h
  • 让 PEAR 在 XAMPP(Windows 上的 Apache/MySQL 堆栈)上工作

    我正在尝试安装Laconica http laconi ca 在我的 Windows 开发服务器上使用 XAMPP 的开源微博应用程序提供的说明 http laconi ca trac wiki InstallationWindows 网站
  • Perl REST 流程布局

    我正在使用 Apache 和 Perl modperl 以及处理程序来处理请求 我对此很陌生 我不太确定如何以合理的方式安排事情 现在我有以下内容 package MyClass Handler use warnings use stric
  • 在 Swift 4 中将数据转换为 DispatchData

    我正在将一个项目迁移到 Swift 4 但我无法弄清楚应该如何使用新的 API s 在 Swift 4 中执行此操作 以下代码是旧的 Swift 3 方式 从函数中间开始 因此需要保护 let formattedString A strin
  • 为什么在我的字符串末尾添加换行符?

    我有一个小问题 我注意到 出于某种原因 当我使用 连接两个变量时 Python 自动使用换行符 for i in range o a Before readline b After readline if a b lines append
  • Django 模型无线电输入

    我正在尝试将单选按钮合并到我的表单中 在我的forms py我的表单有以下字段 class ProfileForm forms ModelForm class Meta model Profile fields first name las
  • 单击 Android 中的 URL 时会打开我的应用程序

    我定义了一个意图过滤器 以便从某些类型的 URL 启动我的应用程序 重点是它是针对所有类型的链接启动的 而我只想针对具体的主机名启动 这是我的清单
  • System.InvalidOperationException:集合已修改

    我在枚举队列时遇到以下异常 系统 InvalidOperationException 集合已修改 枚举 操作可能无法执行 这是代码摘录 1 private bool extractWriteActions out List
  • Kotlin 与正则表达式的拆分工作不符合预期

    我正在尝试将字符串拆分为 16 个字符长度的块 所以首先我创建长度为 64 的字符串 val data Some string data String format 64s data 然后我用正则表达式分割它 val nameArray d
  • 带有列表理解的python三元迭代

    三元迭代可以吗 我的意思是一个简单的版本 尽管这个特定的例子可以用更好的方式来完成 c 0 list1 4 6 7 3 4 5 3 4 c 1 if 4 i for i in list1 else 0 一个更实际的例子 strList Ul
  • 复制带有选中复选框的行

    我想将三张纸 肝脏 肺 和 肾脏 中选中复选框的行合并到一张 报告 中 我想抓取 A 列中不包含单词 sample 的行 当我将数据粘贴到 Report 中时 我想通过在其间添加一行 用相应的原始工作表名称来标记每组行 其中包含A 列中的工
  • 分步天气 API 教程 [已关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 在哪里可以找到有关某些 api 天气实现的良好分步教程 我对此很陌生 因此官方文档并不总是像我需要开始理解的那样清晰 您可以使用来自各个站
  • SessionFactory.getCurrentSession() 线程安全吗?

    通过获取 Hibernate 会话是否线程安全SessionFactory getCurrentSession 假设我有一个static SessionFactory用于我的整个应用程序的对象 并且我向我的 servlet 发出了 5 个并
  • TensorFlow 专家的混合体

    我想在 TensowFlow 上实现一个通用模块 它接收 TensorFlow 模型列表 此处表示为专家 并从中构建专家混合 如下图所示http www aclweb org anthology C16 1133 http www aclw
  • OpenIdConnect 错误 - 租户标识符可能不是空 GUID

    我正在尝试使用 OWIN Open ID Connect 中间件将 ASP NET 应用程序的身份验证外包给 Azure Active Directory 应用程序在访问需要授权的页面时成功重定向到 Azure AD 登录页面 但是 在登录
  • Windows下appcontainer进程和普通进程之间有ipc的方式吗?

    我正在尝试在 Windows 中的 appcontainer 进程和普通进程之间建立 ipc 我在Windows appcontainer中做了一个进程 感谢这个article https www malwaretech com 2015