by NoWest » 2009年6月16日(火) 03:00
一応、動くものになっていると思いますので、ご確認を
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: 全て選択
Sub MainWnd_SetCommand_Click()
Dim Path[MAX_PATH] As Byte
Dim FileName[MAX_PATH] As Byte
'リソースに埋め込みたいファイルパスのエディットボックスから取得
If GetDlgItemText(hMainWnd,FilePathBox,Path,MAX_PATH)=0 Then
MessageBox(hMainWnd,"追加するファイルが選択されていません!","Error 01",MB_OK or MB_ICONHAND)
Exit Sub
End If
Dim IsUpdate As Long
IsUpdate=BeginUpdateResource(Dir+"ProgramB.exe",FALSE)'FileName はターゲットファイルのフルパス。Ex:"C:\test.exe" にリソースを埋め込む場合、FileName="C:\test.exe"
If IsUpdate=0 Then'エラー
MessageBox(hMainWnd,"リソースの埋め込み先に異常あり:"+Dir+"ProgramB.exe","Error 02",MB_OK or MB_ICONHAND)
Exit Sub
End If
'ファイルをオープン
Dim hFile As HANDLE
Dim fSize As DWord
Dim buffer As BytePtr
Dim dummy As DWord
hFile=CreateFile(Path,GENERIC_READ,0,ByVal NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL)
If hFile=INVALID_HANDLE_VALUE Then
MessageBox(hMainWnd,"ファイルのオープンに失敗","Error 03",MB_OK or MB_ICONHAND)
Exit Sub
End If
fSize=GetFileSize(hFile,0)
If fSize=&HFFFFFFFF Then
CloseHandle(hFile)
MessageBox(hMainWnd,"ファイルのサイズ取得に失敗","Error 04",MB_OK or MB_ICONHAND)
Exit Sub
End If
buffer=malloc(fSize)
ReadFile(hFile,buffer,fSize,VarPtr(dummy),ByVal 0)
GetFileTitle(Path,FileName,MAX_PATH)
'リソースに追加
Dim Update As Long
Update=UpdateResource(IsUpdate,RT_MANIFEST,RT_MANIFESTID,MAKELANGID(LANG_JAPANESE,SUBLANG_SYS_DEFAULT),buffer,fSize)
If Update=0 Then'エラー
EndUpdateResource(IsUpdate,TRUE)
MessageBox(hMainWnd,"リソースの埋め込み時に異常事態発生","Error 05",MB_OK or MB_ICONHAND)
Exit Sub
End If
UpdateResource(IsUpdate,RT_MANIFESTSIZE,RT_MANIFESTSIZEID,MAKELANGID(LANG_JAPANESE,SUBLANG_SYS_DEFAULT),VarPtr(fSize),Len(fSize))
UpdateResource(IsUpdate,RT_MANIFESTFILE,RT_MANIFESTFILEID,MAKELANGID(LANG_JAPANESE,SUBLANG_SYS_DEFAULT),FileName,Len(MakeStr(FileName)))
EndUpdateResource(IsUpdate,FALSE)
CloseHandle(hFile)
MessageBox(hMainWnd,"たぶんエラーなく書き込みを完了しました。","Success!!",MB_OK or MB_ICONINFORMATION)
End Sub
いくつか気になったことがあるので確認を、
1.カレントディレクトリを格納した変数Dirは
コード: 全て選択
Dir=MakeStr(path)+"\"
と、すべきです。
以前のコードをコピーしたので現在は直されているかもしれませんが。
基本的にAB4.Xでは文字列と文字配列の足し算はできません。
Dir=path+"\"は計算できないわけです。
2.ファイルのバッファはファイルサイズ+1する必要はないです。
コード: 全て選択
buffer=malloc(fSize)
文字列の場合は終端NULLと呼ばれる方式になっていますので、
確保したい文字列+終端NULL文字用に+1する必要がありますが、
ファイルはそのようなことを考える必要はないです。
3.ファイルの中身をリソースに書き込む際は文字列に変換する必要はありません。
コード: 全て選択
Update=UpdateResource(IsUpdate,RT_MANIFEST,RT_MANIFESTID,MAKELANGID(LANG_JAPANESE,SUBLANG_SYS_DEFAULT),buffer,fSize)
バッファへのアドレスうをそのまま渡せばよいです。
4.数値型変数をLenすると変数の大きさが返ります。
コード: 全て選択
UpdateResource(IsUpdate,RT_MANIFESTSIZE,RT_MANIFESTSIZEID,MAKELANGID(LANG_JAPANESE,SUBLANG_SYS_DEFAULT),VarPtr(fSize),Len(fSize))
この場合、fSizeはLONG型なのでLen(fSize)は4[Byte]という結果が返ります。
なので,ファイルサイズが格納されている変数へのポインタを渡します。
こすれば4バイトの変数の中身をリソースへそのまま書き出すことができます。
5.ポインタをLenしても文字の長さを得ることはできません。
コード: 全て選択
UpdateResource(IsUpdate,RT_MANIFESTFILE,RT_MANIFESTFILEID,MAKELANGID(LANG_JAPANESE,SUBLANG_SYS_DEFAULT),FileName,Len(MakeStr(FileName)))
FileNameは文字配列なので[]を省略すると
先頭文字へのアドレスを指し示すポインタとして機能します。
ですので,Len(FileName)の結果は4Byteになるおそれがあります。
※もしかしたらちゃんと動いてしまうかもしれませんが避けるべきです。
FileNameをMakeStrをかまして文字列にしてからLenで文字の長さを取得します。
一応、動くものになっていると思いますので、ご確認を
[hide][code]Sub MainWnd_SetCommand_Click()
Dim Path[MAX_PATH] As Byte
Dim FileName[MAX_PATH] As Byte
'リソースに埋め込みたいファイルパスのエディットボックスから取得
If GetDlgItemText(hMainWnd,FilePathBox,Path,MAX_PATH)=0 Then
MessageBox(hMainWnd,"追加するファイルが選択されていません!","Error 01",MB_OK or MB_ICONHAND)
Exit Sub
End If
Dim IsUpdate As Long
IsUpdate=BeginUpdateResource(Dir+"ProgramB.exe",FALSE)'FileName はターゲットファイルのフルパス。Ex:"C:\test.exe" にリソースを埋め込む場合、FileName="C:\test.exe"
If IsUpdate=0 Then'エラー
MessageBox(hMainWnd,"リソースの埋め込み先に異常あり:"+Dir+"ProgramB.exe","Error 02",MB_OK or MB_ICONHAND)
Exit Sub
End If
'ファイルをオープン
Dim hFile As HANDLE
Dim fSize As DWord
Dim buffer As BytePtr
Dim dummy As DWord
hFile=CreateFile(Path,GENERIC_READ,0,ByVal NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL)
If hFile=INVALID_HANDLE_VALUE Then
MessageBox(hMainWnd,"ファイルのオープンに失敗","Error 03",MB_OK or MB_ICONHAND)
Exit Sub
End If
fSize=GetFileSize(hFile,0)
If fSize=&HFFFFFFFF Then
CloseHandle(hFile)
MessageBox(hMainWnd,"ファイルのサイズ取得に失敗","Error 04",MB_OK or MB_ICONHAND)
Exit Sub
End If
buffer=malloc(fSize)
ReadFile(hFile,buffer,fSize,VarPtr(dummy),ByVal 0)
GetFileTitle(Path,FileName,MAX_PATH)
'リソースに追加
Dim Update As Long
Update=UpdateResource(IsUpdate,RT_MANIFEST,RT_MANIFESTID,MAKELANGID(LANG_JAPANESE,SUBLANG_SYS_DEFAULT),buffer,fSize)
If Update=0 Then'エラー
EndUpdateResource(IsUpdate,TRUE)
MessageBox(hMainWnd,"リソースの埋め込み時に異常事態発生","Error 05",MB_OK or MB_ICONHAND)
Exit Sub
End If
UpdateResource(IsUpdate,RT_MANIFESTSIZE,RT_MANIFESTSIZEID,MAKELANGID(LANG_JAPANESE,SUBLANG_SYS_DEFAULT),VarPtr(fSize),Len(fSize))
UpdateResource(IsUpdate,RT_MANIFESTFILE,RT_MANIFESTFILEID,MAKELANGID(LANG_JAPANESE,SUBLANG_SYS_DEFAULT),FileName,Len(MakeStr(FileName)))
EndUpdateResource(IsUpdate,FALSE)
CloseHandle(hFile)
MessageBox(hMainWnd,"たぶんエラーなく書き込みを完了しました。","Success!!",MB_OK or MB_ICONINFORMATION)
End Sub[/code][/hide]
いくつか気になったことがあるので確認を、
1.カレントディレクトリを格納した変数Dirは
[code] Dir=MakeStr(path)+"\"[/code]
と、すべきです。
以前のコードをコピーしたので現在は直されているかもしれませんが。
基本的にAB4.Xでは文字列と文字配列の足し算はできません。
Dir=path+"\"は計算できないわけです。
2.ファイルのバッファはファイルサイズ+1する必要はないです。
[code] buffer=malloc(fSize)[/code]
文字列の場合は終端NULLと呼ばれる方式になっていますので、
確保したい文字列+終端NULL文字用に+1する必要がありますが、
ファイルはそのようなことを考える必要はないです。
3.ファイルの中身をリソースに書き込む際は文字列に変換する必要はありません。
[code] Update=UpdateResource(IsUpdate,RT_MANIFEST,RT_MANIFESTID,MAKELANGID(LANG_JAPANESE,SUBLANG_SYS_DEFAULT),buffer,fSize)[/code]
バッファへのアドレスうをそのまま渡せばよいです。
4.数値型変数をLenすると変数の大きさが返ります。
[code] UpdateResource(IsUpdate,RT_MANIFESTSIZE,RT_MANIFESTSIZEID,MAKELANGID(LANG_JAPANESE,SUBLANG_SYS_DEFAULT),VarPtr(fSize),Len(fSize))[/code]
この場合、fSizeはLONG型なのでLen(fSize)は4[Byte]という結果が返ります。
なので,ファイルサイズが格納されている変数へのポインタを渡します。
こすれば4バイトの変数の中身をリソースへそのまま書き出すことができます。
5.ポインタをLenしても文字の長さを得ることはできません。
[code] UpdateResource(IsUpdate,RT_MANIFESTFILE,RT_MANIFESTFILEID,MAKELANGID(LANG_JAPANESE,SUBLANG_SYS_DEFAULT),FileName,Len(MakeStr(FileName)))[/code]
FileNameは文字配列なので[]を省略すると
先頭文字へのアドレスを指し示すポインタとして機能します。
ですので,Len(FileName)の結果は4Byteになるおそれがあります。
※もしかしたらちゃんと動いてしまうかもしれませんが避けるべきです。
FileNameをMakeStrをかまして文字列にしてからLenで文字の長さを取得します。