2009-12-21 1 views
4

Qt을 사용하여 크로스 플랫폼 C++ 프로그램을 작성 중이며 프로그램 내에 여러 바이너리 실행 파일을 패키지/임베드하고 싶습니다. 프로그램은 런타임에 이러한 바이너리를 실행할 수 있어야합니다.Qt 프로그램에 실행 파일을 실행 파일로 포함하려면 어떻게해야합니까?

나는 QResource와 QProcess가 start()와 ":/..."표기법을 사용하여 필요하다고 생각했지만 프로세스를 실행하지 않는 것 같습니다. 내가 누락 된 것이 있습니까? 이런 식으로 작동해야합니까? 바이너리를 실행 파일로 설정해야합니까?

배경 : Git을 사용하는 도구를 작성 중이므로 최종 사용자가 Git을 수동으로 설치하지 않아도됩니다.

(BTW, 맥 OS X에서이 작업을 시도.)

업데이트 :

나는 다음과 같은 코드를 사용하고 (C++, Qt는 맥 OS X에 대한) :

QString program = ":/git"; 
QStringList arguments; 
arguments << "help" << "commit"; 
myProcess->start(program, arguments); 

Git 실행 파일은 프로젝트 경로에 있으므로 내 resources.qrc는 다음과 같이 참조합니다.

<qresource prefix="/"> 
    <file>git</file> 
</qresource> 

오류가 발생하지 않지만 프로그램이 실행되지 않습니다. 존재하지 않는 파일에 program을 설정하면 동작이 동일합니다. ":/git"을 git의 절대 경로로 바꾸면 완벽하게 작동합니다.

+0

이 우리에게 소스 코드를 제공하십시오. 즉, 언급 한 QResource 및 QProcess를 사용하는 부분입니다. – Wildcat

+0

사용하고있는 코드로 질문을 업데이트했습니다. – jan

답변

8

리소스에서 직접 프로그램을 실행할 수 없습니다.

리소스에 프로그램이 있고이를 실행하려면 리소스에서 리소스를 읽고 파일에 쓰고 실행 파일로 만든 다음 실행해야합니다.

또한 오류가 발생하지 않는다고 말하면 오류를 제대로 검사하지 않는다는 뜻입니다.

+0

로한 감사합니다. "오류가 발생하지 않음"은 "게으르게 실패합니다"라는 게으른 말입니다. 나는 내가 제대로 체크하면 에러가 발생할 것이라고 생각한다. – jan

+0

windows : https://www.blackhat.com/presentations/bh-usa-07/Harbour/Whitepaper/bh-usa-07-harbour-WP.pdf –

1

리소스가 작동한다고 생각하지 않습니다. 프로세스는 운영 체제에서 생성되며 리소스는 응용 프로그램에서 처리됩니다.

하나의 가능한 솔루션은 응용 프로그램 디렉토리의 어딘가에 추가 실행 파일을 묶어서 해당 경로에서 실행하는 것입니다.

+0

감사합니다! 애플리케이션 번들 (osx)에 어떻게 그들을 포함 시킬지를 나타낼 수 있습니까? 설치 프로그램을 피하고 싶습니다. 간단한 사용자 인터페이스를 통해 모든 사용자가 다운로드해야합니다. – jan

0

그래서 문제는 git 실행 파일을 리소스에서 실행 파일을 추출하는 것처럼 보이지 않습니다.

git 프로그램은 don 디스크를 올바르게 생성합니다. 사용 권한을 확인할 수 있습니까?

1

몇 년 늦었지만 문제는 여전히 관련이 있습니다. rclone을 삽입하려는 경우에도 동일한 문제가 발생했습니다. .pro 파일에서

, 각 플랫폼에 약간의 차이가 얼마나

# From http://stackoverflow.com/a/37561981 
defineReplace(copyToDir) { 
    files = $$1 
    DIR = $$2 
    LINK = 

    for(FILE, files) { 
     LINK += $$QMAKE_COPY $$shell_path($$FILE) $$shell_path($$DIR) $$escape_expand(\\n\\t) 
    } 
    return($$LINK) 
} 

defineReplace(copyToBuilddir) { 
    return($$copyToDir($$1, $$OUT_PWD)) 
} 

# Copy the binary files dependent on the system architecture 
win32 { 
    message("Windows") 
    QMAKE_POST_LINK += $$copyToBuilddir($$PWD/rclone/windows/rclone.exe) 
}else: unix:!macx { 
    message("Linux") 
    QMAKE_POST_LINK += $$copyToBuilddir($$PWD/rclone/linux/rclone) 
}else: macx: { 
    # Here we want to place the binaries inside the application bundle, so the 
    # QMAKE_POST_LINK approach will not work because it places them in the same 
    # directory as the bundle and not inside it. Instead, use QMAKE_BUNDLE_DATA. 
    message("macOS") 
    MediaFiles.files += $$PWD/rclone/macOS/rclone 
    MediaFiles.path = Contents/MacOS 
    QMAKE_BUNDLE_DATA += MediaFiles 
} 

공지 사항을 추가 할 수 있지만 일반적으로 접근 방식은 동일합니다.

qmake은이 파일을 대상 디렉토리에 복사하며 로컬 상대 디렉토리에 대한 프로세스 호출만으로 액세스 할 수 있습니다.다음 코드에서

, 나는 QML에서 실행 파일을 호출하고뿐만 아니라 C++에서 매우 유사 될 것 :

var rcloneCommand 
if (Qt.platform.os === "windows") { 
    console.log("Windows") 
    rcloneCommand = "rclone.exe" 
} else { 
    console.log("OSX/Linux") 
    rcloneCommand = "./rclone" 
} 
qProcess.start(rcloneCommand, ["--config", "rclone.conf", "-v", "copy", "--stats", "1s", source, destination]);