普通にCreateProcessを使用して、東方を起動すれば普通に出来るのですが、Vpatchを使用して起動させるときの方法がいまいち分かりません。
というのは、Vpatchをランチャーから起動させ、東方が起動するまでの間CreateToolhelp32Snapshotを使用して東方のプロセスIDが見つかるまでやり続け、見つけた後、OpenProcessでプロセスハンドルを取得します。その後にSetPriorityClassで優先度を変更させようという感じにしています。
これがプログラムです。長くなるので必要と思われる部分だけ抜き出します。
//メインでCreateProcess(NULL,AppFullPath,NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,strPath,&StartupInfo,&ShellInfo)を実行した後。
void PriorityClassChange(void){
char temp[5]={0},ExeName[20]={0};
int count1,count2;
HANDLE hSnap,ProcessHandle;
DWORD dwProcessId = 0;
BOOL bResult;
PROCESSENTRY32 ProcessEntry;
ProcessEntry.dwSize = sizeof(ProcessEntry);
if(lstrcmpi(strExe,"vpatch.exe")==0){ //起動したのがVpatchだったら、プロセスで検索するさいの文字列をExeNameにコピー
switch(sel.x){
case 0:
switch(sel.y){
case 0:lstrcpy(ExeName,"東方紅魔郷.exe");break;
case 1:lstrcpy(ExeName,"th07.exe");break;
case 2:lstrcpy(ExeName,"th08.exe");break;
case 3:lstrcpy(ExeName,"th10.exe");break;
case 4:lstrcpy(ExeName,"th11.exe");break;
case 5:lstrcpy(ExeName,"th12.exe");break;
}
break;
case 1:
switch(sel.y){
case 0:lstrcpy(ExeName,"th09.exe");break;
case 1:lstrcpy(ExeName,"th095.exe");break;
case 2:lstrcpy(ExeName,"th125.exe");break;
case 3:lstrcpy(ExeName,"th128.exe");break;
}
break;
case 2:
switch(sel.y){
case 0:lstrcpy(ExeName,"th075.exe");break;
case 1:lstrcpy(ExeName,"th105.exe");break;
case 2:lstrcpy(ExeName,"th123.exe");break;
}
break;
}
count1=GetNowCount(); //基準のカウント値
do{
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hSnap == INVALID_HANDLE_VALUE){
MessageBox(NULL, "CreateToolhelp32Snapshot failed", PROGRAM_TITLE, MB_ICONERROR);
return;
}
bResult = Process32First(hSnap, &ProcessEntry);
while(lstrcmpi(ProcessEntry.szExeFile, ExeName)!=0 && bResult!=0){ //対象のプロセスが見つかったりbResultがNULLになったら抜ける
dwProcessId = ProcessEntry.th32ProcessID;
bResult = Process32Next(hSnap, &ProcessEntry);
}
count2=GetNowCount();
}while(bResult==NULL && (count2-count1)<1000); //1秒以上経っても対象プロセスがなければループから抜ける。
if(bResult == NULL){
MessageBox(NULL, "対象プロセスが見つかりません。", PROGRAM_TITLE, MB_ICONERROR);
return;
}
else{
ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, TRUE, dwProcessId); //プロセスハンドルを受け取る
if(ProcessHandle == NULL){ //取得に失敗したら
MessageBox(NULL, "OpenProcess failed", PROGRAM_TITLE, MB_ICONERROR);
return;
}
}
CloseHandle(hSnap);
}
else{
ProcessHandle = ShellInfo.hProcess;
}
GetPrivateProfileString("Etc","process_priority",0,temp,5,"./Launcher.ini"); //構成ファイルからどの優先度にするかを読み込む
int i=atoi(temp);
switch(i){
case 1:SetPriorityClass(ProcessHandle,IDLE_PRIORITY_CLASS);break;
case 2:SetPriorityClass(ProcessHandle,BELOW_NORMAL_PRIORITY_CLASS);break;
case 3:SetPriorityClass(ProcessHandle,NORMAL_PRIORITY_CLASS);break;
case 4:SetPriorityClass(ProcessHandle,ABOVE_NORMAL_PRIORITY_CLASS);break;
case 5:i=SetPriorityClass(ProcessHandle,HIGH_PRIORITY_CLASS);
/*デバッグ用 if(i==0){
MessageBox(NULL, "Bad!!", PROGRAM_TITLE, MB_ICONERROR);
}
else{
MessageBox(NULL, "OK", PROGRAM_TITLE, MB_ICONERROR);
}*/
break;
case 6:SetPriorityClass(ProcessHandle,REALTIME_PRIORITY_CLASS);break;
default:SetPriorityClass(ProcessHandle,NORMAL_PRIORITY_CLASS);break;
}
}
デバッグ用の部分のコメントを外して、これを実行したときにOKと出てくるのですがタスクマネージャーで確認すると通常のままになっています。先ほども言ったとおり、Vpatchを通して起動した東方の優先度を変更しようとしても通常のままになってしまいます。
原因は何でしょうか?それともVpatchの使用でしょうか?
それとついでになのですが、OpenProcess関数の第2引数がTRUEとFALSEでの違いがいまいち分かりません。あと、プロセスを検索するところのループも少し不安です。
OSはWindows7でVisual C++ 2008を使っています。
多くの方から意見を聞きたいです。
ご教授お願いします!
(ついでにVpatchの優先度を高にしてももちろん無理でした。当たり前ですがw)