سؤال

النظر في التعليمات البرمجية التالية وقابلة للتنفيذ - runner.exe:

#include <iostream>
#include <string>
#include <windows.h>

using namespace std;

int main(int argc, char *argv[])
{
    SHELLEXECUTEINFO shExecInfo;

    shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);

    shExecInfo.fMask = NULL;
    shExecInfo.hwnd = NULL;
    shExecInfo.lpVerb = "open";
    shExecInfo.lpFile = argv[1];

    string Params = "";
    for ( int i = 2; i < argc; ++i )
        Params += argv[i] + ' ';

    shExecInfo.lpParameters = Params.c_str();

    shExecInfo.lpDirectory = NULL;
    shExecInfo.nShow = SW_SHOWNORMAL;
    shExecInfo.hInstApp = NULL;

    ShellExecuteEx(&shExecInfo);

    return 0;
}

هذين الملفين الدفعي يفعلان ما يفترض أنه من المفترض أن يدير notepad.exe وتشغيل notepad.exe وأخبره بمحاولة فتح Test.txt:

1.
runner.exe notepad.exe

2.
runner.exe notepad.exe test.txt

الآن، فكر في هذا الملف الدفعي:

3.
runner.exe runner.exe notepad.exe

يجب أن يقوم هذا المرء بتشغيل Runner.exe وإرسال Notepad.exe كواحد من وسيطات سطر الأوامر، أليس كذلك؟ بعد ذلك، يجب تشغيل هذا المثيل الثاني من Runner.exe Notepad.exe - الذي لا يحدث، أحصل على "Windows لا يمكن العثور عليه". تأكد من كتابة الاسم بشكل صحيح، ثم حاول مرة أخرى "خطأ". إذا قمت بطباعة argc حجة، إنها 14 للمثيل الثاني من Runner.exe، وهم جميعا أشياء غريبة مثل الملفات Microsoft، SQL، الملفات الشائعة وهلم جرا. لا أستطيع معرفة سبب حدوث ذلك. أريد أن أكون قادرا على سلسلة العديد من المكالمات Runner.exe باستخدام وسيطات سطر الأوامر قدر الإمكان، أو على الأقل 2. كيف يمكنني أن أفعل ذلك؟

أنا أستخدم نظام التشغيل Windows 7 إذا كان ذلك يحدث فرقا.

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

المحلول

لديك خطأ في هذا الخط:

Params += argv[i] + ' ';

هذا سيضيف 32 إلى المؤشر argv[i], ، وهذا ليس ما تريد. يمكنك فصلها إلى سطرين:

Params += argv[i];
Params += ' ';

او استعمل:

Params += string(argv[i]) + ' ';

قد ترغب أيضا في إضافة علامات اقتباس حول كل معلمة في حالة وجود مسافات.


أنا أيضا وضعت fMask ل SEE_MASK_NOASYNC, ، لأن MSDN الولايات:

التطبيقات التي تخرج مباشرة بعد استدعاء shellexecuteex يجب أن تحدد هذه العلامة.

نصائح أخرى

المشكلة هي هذا الخط:

Params += argv[i] + ' '

لان argv[i] هو من النوع char * أن تضيف 32 إلى argv[i] لذلك سوف تعطيك مؤشر إلى منتصف الذاكرة العشوائية.

أود أن أعد كتابة ذلك إلى:

Params += std::string(argv[i]) + ' ';

أو إذا كنت ترغب في أن تكون جيدا حقيقيا، يمكنك تعديل ذلك لإضافة مساحة فقط عندما تكون ضرورية حقا:

for ( int i = 2; i < argc; ++i )
{
    if (!Params.empty())
        Params += ' ';
    Params += argv[i];
}

أعتقد أن المشكلة هي كيفية إنشاء معلمات سطر الأوامر للمكالمات التالية:

 Params += argv[i] + ' ';

لا يعمل كما هو متوقع. جرب ما يلي:

#include <windows.h>
#include <fstream>
#include <iostream>
#include <tchar.h>
using namespace std;

#ifdef _UNICODE
    typedef std::wstring tstring;
#else
    typedef std::string tstring;
#endif

int _tmain(int argc, TCHAR *argv[])
{
    {
        std::ofstream f("C:\\output.txt", std::ios::app);
        f << "app called" << std::endl;
    }
    SHELLEXECUTEINFO shExecInfo;

    shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);

    shExecInfo.fMask = NULL;
    shExecInfo.hwnd = NULL;
    shExecInfo.lpVerb = _T("open");
    shExecInfo.lpFile = argv[1];

    tstring Params(_T(""));
    for ( int i = 2; i < argc; ++i )
    {
        Params += argv[i]; 
        Params += _T(' ');
    }

    shExecInfo.lpParameters = Params.c_str();

    shExecInfo.lpDirectory = NULL;
    shExecInfo.nShow = SW_SHOWNORMAL;
    shExecInfo.hInstApp = NULL;

    ShellExecuteEx(&shExecInfo);

    return 0;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top