by イグトランス » 2006年8月14日(月) 11:02
最新のAB5をダウンロード
動作環境に書かれているとおり,AB5はWindows NT系でしか動かないことになっています。
しかし,今のところ裏技的に9x系でも動かす方法があります。
現在AB5がNTを要求している理由は,PSAPI.DLLを使用しているからです。つまりPSAPI.DLLの代わりを用意すればよいわけです。
AB 4.24で新しくDLLプロジェクトを作成し,次のコードを書きます。
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: 全て選択
#include <api_tlhelp32.sbp>
Dim OSVersionInfo As OSVERSIONINFO
Dim hmodPsapi As HMODULE
Function Export DllMain(hinstDLL As HINSTANCE, fdwReason As DWord, lpvReserved As VoidPtr) As Long
'DLLエントリポイント
Select Case fdwReason
Case DLL_PROCESS_ATTACH
'DLLがプロセス空間にロードされた時に実行されます。
_System_StartupProgram()
' DisableThreadLibraryCalls(hinstDLL)
OSVersionInfo.dwOSVersionInfoSize = Len (OSVersionInfo)
GetVersionEx(OSVersionInfo)
DllMain=TRUE
End Select
End Function
Function IsRunningOnNT() As BOOL
If OSVersionInfo.dwPlatformId = VER_PLATFORM_WIN32_NT Then
IsRunningOnNT = TRUE
Else
IsRunningOnNT = FALSE
End If
End Function
TypeDef PGetModuleFileNameExA = *Function(
hProcess As HANDLE,
hModule As HMODULE,
pFilename As PSTR,
nSize As DWord
) As DWord
TypeDef PEnumProcessModules = *Function(
hProcess As HANDLE,
phModule As *HMODULE,
cb As DWord,
pcbNeeded As *DWord
) As BOOL
TypeDef PEnumProcesses = *Function(
pidProcess As *DWord,
cb As DWord,
cbNeeded As *DWord
) As BOOL
Dim pGetModuleFileNameExA As PGetModuleFileNameExA
Dim pEnumProcessModules As PEnumProcessModules
Dim pEnumProcesses As PEnumProcesses
Sub PsapiInit()
If IsRunningOnNT() <> FALSE And hmodPsapi = 0 Then
Dim systemPath[ELM(MAX_PATH)] As Byte
GetSystemDirectory(systemPath, MAX_PATH)
lstrcat(systemPath, "\psapi.dll")
hmodPsapi = LoadLibrary(systemPath)
pGetModuleFileNameExA = GetProcAddress(hmodPsapi, "GetModuleFileNameExA") As PGetModuleFileNameExA
pEnumProcessModules = GetProcAddress(hmodPsapi, "EnumProcessModules") As PEnumProcessModules
pEnumProcesses = GetProcAddress(hmodPsapi, "EnumProcesses") As PEnumProcesses
End If
End Sub
TypeDef HMODULE = HINSTANCE
TypeDef PSTR = BytePtr
Function Export GetModuleFileNameExA(
hProcess As HANDLE,
hModule As HMODULE,
pFilename As PSTR,
nSize As DWord
) As DWord
If IsRunningOnNT() Then
PsapiInit()
GetModuleFileNameExA = pGetModuleFileNameExA(hProcess, hModule, pFilename, nSize)
Else
GetModuleFileNameExA = GetModuleFileName(hModule, pFilename, nSize)
End If
End Function
Function Export EnumProcessModules(
hProcess As HANDLE,
phModule As *HMODULE,
cb As DWord,
pcbNeeded As *DWord
) As BOOL
If IsRunningOnNT() Then
PsapiInit()
EnumProcessModules = pEnumProcessModules(hProcess, phModule, cb, pcbNeeded)
Else
End If
End Function
Function Export EnumProcesses(
pidProcess As *DWord,
cb As DWord,
cbNeeded As *DWord
) As BOOL
If IsRunningOnNT() Then
PsapiInit()
EnumProcesses = pEnumProcesses(pidProcess, cb, cbNeeded)
Else
Dim hSnap As HANDLE
Dim pe As PROCESSENTRY32
Dim bResult As BOOL
Dim i As DWord
' スナップショットを作成
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
' プロセスの最初の情報を取得
pe.cntUsage = Len (pe)
bResult = Process32First(hSnap, pe)
While bResult
If cb >= (i + 1) * SizeOf (DWord) Then
pidProcess = pe.th32ProcessID
End If
i++
bResult = Process32Next(hSnap, pe)
WEnd
If cbNeeded <> 0 Then
SetDWord(cbNeeded, i * SizeOf (DWord))
End If
CloseHandle(hSnap)
End If
End Function
TypeDef PPROCESSENTRY32 = *PROCESSENTRY32
TypeDef LPPROCESSENTRY32 = PPROCESSENTRY32
予めapi_tlhelp32.sbpをAB5のIncludeフォルダからAB4のIncludeフォルダへコピーしておいてください。
出力ファイル名をPSAPI.DLLとしてリリースビルドし,それをAB5のabdev.exeと同じフォルダにおきます。
これによってWindows 98で起動するようになったのは確認しましたが,どこまで使えるかはわかりません。
また,NT系でこのファイルが存在する状態でAB5を起動した場合,本来のPSAPI.DLLを呼ぶようにしており,問題ないと当初考えていましたが,
ヘルプを表示するときにも,(本来のPSAPI.DLLではなく)この自作DLLが使われるらしく,
必要な関数が見つからないというエラーが表示され,ヘルプを表示させることができません。
将来的にNT系でしか使えない(9x系で代替が存在しない)APIを使ってきたら,もうお手上げです。
たとえばUnicodeのW版APIの使用もそうです。その際にはunicows.libをリンクしてくれれば救われるのですが……。
[url=http://www.activebasic.com/activebasic5.php?page=download]最新のAB5をダウンロード[/url]
動作環境に書かれているとおり,AB5はWindows NT系でしか動かないことになっています。
しかし,今のところ裏技的に9x系でも動かす方法があります。
現在AB5がNTを要求している理由は,PSAPI.DLLを使用しているからです。つまりPSAPI.DLLの代わりを用意すればよいわけです。
AB 4.24で新しくDLLプロジェクトを作成し,次のコードを書きます。
[hide][code]#include <api_tlhelp32.sbp>
Dim OSVersionInfo As OSVERSIONINFO
Dim hmodPsapi As HMODULE
Function Export DllMain(hinstDLL As HINSTANCE, fdwReason As DWord, lpvReserved As VoidPtr) As Long
'DLLエントリポイント
Select Case fdwReason
Case DLL_PROCESS_ATTACH
'DLLがプロセス空間にロードされた時に実行されます。
_System_StartupProgram()
' DisableThreadLibraryCalls(hinstDLL)
OSVersionInfo.dwOSVersionInfoSize = Len (OSVersionInfo)
GetVersionEx(OSVersionInfo)
DllMain=TRUE
End Select
End Function
Function IsRunningOnNT() As BOOL
If OSVersionInfo.dwPlatformId = VER_PLATFORM_WIN32_NT Then
IsRunningOnNT = TRUE
Else
IsRunningOnNT = FALSE
End If
End Function
TypeDef PGetModuleFileNameExA = *Function(
hProcess As HANDLE,
hModule As HMODULE,
pFilename As PSTR,
nSize As DWord
) As DWord
TypeDef PEnumProcessModules = *Function(
hProcess As HANDLE,
phModule As *HMODULE,
cb As DWord,
pcbNeeded As *DWord
) As BOOL
TypeDef PEnumProcesses = *Function(
pidProcess As *DWord,
cb As DWord,
cbNeeded As *DWord
) As BOOL
Dim pGetModuleFileNameExA As PGetModuleFileNameExA
Dim pEnumProcessModules As PEnumProcessModules
Dim pEnumProcesses As PEnumProcesses
Sub PsapiInit()
If IsRunningOnNT() <> FALSE And hmodPsapi = 0 Then
Dim systemPath[ELM(MAX_PATH)] As Byte
GetSystemDirectory(systemPath, MAX_PATH)
lstrcat(systemPath, "\psapi.dll")
hmodPsapi = LoadLibrary(systemPath)
pGetModuleFileNameExA = GetProcAddress(hmodPsapi, "GetModuleFileNameExA") As PGetModuleFileNameExA
pEnumProcessModules = GetProcAddress(hmodPsapi, "EnumProcessModules") As PEnumProcessModules
pEnumProcesses = GetProcAddress(hmodPsapi, "EnumProcesses") As PEnumProcesses
End If
End Sub
TypeDef HMODULE = HINSTANCE
TypeDef PSTR = BytePtr
Function Export GetModuleFileNameExA(
hProcess As HANDLE,
hModule As HMODULE,
pFilename As PSTR,
nSize As DWord
) As DWord
If IsRunningOnNT() Then
PsapiInit()
GetModuleFileNameExA = pGetModuleFileNameExA(hProcess, hModule, pFilename, nSize)
Else
GetModuleFileNameExA = GetModuleFileName(hModule, pFilename, nSize)
End If
End Function
Function Export EnumProcessModules(
hProcess As HANDLE,
phModule As *HMODULE,
cb As DWord,
pcbNeeded As *DWord
) As BOOL
If IsRunningOnNT() Then
PsapiInit()
EnumProcessModules = pEnumProcessModules(hProcess, phModule, cb, pcbNeeded)
Else
End If
End Function
Function Export EnumProcesses(
pidProcess As *DWord,
cb As DWord,
cbNeeded As *DWord
) As BOOL
If IsRunningOnNT() Then
PsapiInit()
EnumProcesses = pEnumProcesses(pidProcess, cb, cbNeeded)
Else
Dim hSnap As HANDLE
Dim pe As PROCESSENTRY32
Dim bResult As BOOL
Dim i As DWord
' スナップショットを作成
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
' プロセスの最初の情報を取得
pe.cntUsage = Len (pe)
bResult = Process32First(hSnap, pe)
While bResult
If cb >= (i + 1) * SizeOf (DWord) Then
pidProcess[i] = pe.th32ProcessID
End If
i++
bResult = Process32Next(hSnap, pe)
WEnd
If cbNeeded <> 0 Then
SetDWord(cbNeeded, i * SizeOf (DWord))
End If
CloseHandle(hSnap)
End If
End Function
TypeDef PPROCESSENTRY32 = *PROCESSENTRY32
TypeDef LPPROCESSENTRY32 = PPROCESSENTRY32
[/code][/hide]
予めapi_tlhelp32.sbpをAB5のIncludeフォルダからAB4のIncludeフォルダへコピーしておいてください。
出力ファイル名をPSAPI.DLLとしてリリースビルドし,それをAB5のabdev.exeと同じフォルダにおきます。
これによってWindows 98で起動するようになったのは確認しましたが,どこまで使えるかはわかりません。
また,NT系でこのファイルが存在する状態でAB5を起動した場合,本来のPSAPI.DLLを呼ぶようにしており,問題ないと当初考えていましたが,
ヘルプを表示するときにも,(本来のPSAPI.DLLではなく)この自作DLLが使われるらしく,
必要な関数が見つからないというエラーが表示され,ヘルプを表示させることができません。
将来的にNT系でしか使えない(9x系で代替が存在しない)APIを使ってきたら,もうお手上げです。
たとえばUnicodeのW版APIの使用もそうです。その際にはunicows.libをリンクしてくれれば救われるのですが……。