لا يتم تحليل الوسيطات التي يتم تمريرها إلى CreateProcess كما كنت أتوقع

StackOverflow https://stackoverflow.com//questions/9690508

سؤال

أحاول استخدام devcon.exe للتحقق من حالة الأجزاء المختلفة من الأجهزة.في المثال أحاول التحقق من حالة SATA HBA الخاصة بي ولكن devcon يتذمر بشأن ذلك.إليك الكود:

int main(int argc, char** argv) {
    std::string cmdLine("\"C:\\Users\\afalanga\\Documents\\Visual Studio 2010\\Projects\\PlayGround\\Debug\\devcon.exe\" status PCI\\VEN_8086^&DEV_3A22^&SUBSYS_75201462^&REV_00");

    char* pCmdLine(new char[cmdLine.length() + 10]);
    memset(pCmdLine, 0, cmdLine.length() + 10);

    for(int i(0); i < cmdLine.length(); i++)
        pCmdLine[i] = cmdLine.at(i);

    STARTUPINFO si = { sizeof(STARTUPINFO) };
    PROCESS_INFORMATION pi = {0};

    if(!CreateProcess(NULL, pCmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
        std::cout << "Create child process failed.  Error code: "
                  << GetLastError() << std::endl;
        return 1;
    }

    WaitForSingleObject(pi.hProcess, INFINITE);
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);

    return 0;
}

المشكلة هي أنه عندما ينفذ أعلاه ، يشكو Devcon من أنه "لم يتم العثور على أجهزة مطابقة". ومع ذلك ، إذا قمت بنسخ/لصق سطر الأوامر هذا من مصحح الأخطاء في موجه الأوامر الخاص بي وضغط على مفتاح Enter (أو حذف جميع عروض الأسعار الشاملة التي يضعها مصحح الأخطاء حوله) ، يتم تنفيذ الأمر تمامًا كما هو متوقع.

ما الخطأ الذي أرتكبه في تسليم السلسلة؟ما ورد أعلاه هو نتيجة قراءة مستندات CreateProcess() على MSDN (اكتشف أن الوسيطة الأولى ليست مطلوبة بالضرورة وأن وسيطات cmd لا ينبغي أن تذهب إلى هناك على الإطلاق).السبب وراء تخصيص 10 بايتات إضافية من الذاكرة لنسخ السلسلة إليها هو أن "أي شيء" قد يتغير في أحشاء وظيفة CreateProcess() يمكنه القيام بذلك دون الدوس على ذاكرة أخرى.على الأقل هذا كان تفكيري عندما فعلت ذلك.

هل كانت مفيدة؟

المحلول

سطر الأوامر metacharacters يتم تحليلها من قبل المعالج الأمر.ولا سيما أنك تستخدم ^ لمنع CMD.EXE من كسر الأمر في العطف.ولكن يتم تنفيذ البرنامج مباشرة ، وتجاوز CMD.EXE.لذلك ، ^ يمر من خلال devcon.exe الذي يحصل الخلط بها.

الحل:إزالة ^ الأحرف.

مشكلتك هي في الواقع عكس العنوان الخاص بك.سطر الأوامر يمكنك تمرير إلى CreateProcess يتم تمرير مباشرة إلى التطبيق بالضبط كما يمكنك تحديد ذلك.

نصائح أخرى

std::string cmdLine("\"C:\\Users\\afalanga\\Documents\\Visual Studio 2010\\Projects\\PlayGround\\Debug\\devcon.exe\" status PCI\\VEN_8086^&DEV_3A22^&SUBSYS_75201462^&REV_00

من المفترض أن ^ توجد بقايا من أمر تم إدخاله في مترجم سطر الأوامر، حيث تعمل على إيقاف تشغيل المعنى الخاص لـ &.

ببساطة قم بإزالة علامات الإقحام.

لاحظ أيضًا أن التعليمات البرمجية الحالية الخاصة بك تتسرب من الذاكرة.

لتجنب ذلك، افعل على سبيل المثال.

string commandLineArg = cmdLine + '\0';

... CreateProcess( 0, &commandLineArg[0], ... )

هل يمكنك تجربة مثل هذا:

CreateProcess(NULL, pCmdLine.c_str(), ...);

إستعملت:

TCHAR var[] = _T(" C:\\filepathe\\foo");

CreateProcess(NULL, var,...);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top