SASからWindowsのAPIをコールするサンプルコードです。バージョンアップによるデータの引越しで、今回はWinAPIを使ったツールを作る予定です。動作確認したのは、Windows7+SAS9.2です。ネットにはいくつか見本が転がっていますが、PDFでうまく転記できなかったり、APIがまったく変わってしまったようなものもありました。
/*
*++
* WinAPI(SetFileTime)を呼び出して、ファイルのタイプスタンプを更新
*--
*/
filename winapi catalog 'WORK.Windows.WINAPI.SOURCE';
data _null_;
file winapi;
input;
put _infile_;
cards4;
routine CreateFileA
module=Kernel32
minarg=7
maxarg=7
stackpop=called
returns=long
;
arg 1 char input format=$cstr260.; * LPCTSTR lpFileName;
arg 2 num input format=pib4. byvalue; * DWORD dwDesiredAccess;
arg 3 num input format=pib4. byvalue; * DWORD dwShareMode;
arg 4 num input format=pib4. byvalue; * LPSECURITY_ATTRIBUTES lpSecurityAttributes (set to null,pass 0 byvalue);
arg 5 num input format=pib4. byvalue; * DWORD dwCreationDispostion;
arg 6 num input format=pib4. byvalue; * DWORD dwFlagsAndAttributes (set to zero);
arg 7 num input format=pib4. byvalue; * HANDLE hTemplateFile (ignored);
*-------------------------------------------------------------;
routine CloseHandle
module=Kernel32
minarg=1
maxarg=1
stackpop=called
returns=long
;
arg 1 num input format=pib4. byvalue; * HANDLE hObject;
*-------------------------------------------------------------;
routine SystemTimeToFileTime
minarg=9
maxarg=9
stackpop=called
module=Kernel32
returns=long
;
arg 1 num input fdstart format=pib2.; * WORD wYear ;
arg 2 num input format=pib2.; * WORD wMonth ;
arg 3 num input format=pib2.; * WORD wDayOfWeek ;
arg 4 num input format=pib2.; * WORD wDay ;
arg 5 num input format=pib2.; * WORD wHour ;
arg 6 num input format=pib2.; * WORD wMinute ;
arg 7 num input format=pib2.; * WORD wSecond ;
arg 8 num input format=pib2.; * WORD wMilliseconds ;
arg 9 num output fdstart format=pib8.;
*-------------------------------------------------------------;
routine LocalFileTimeToFileTime
minarg=2
maxarg=2
stackpop=called
module=kernel32
returns=long
;
arg 1 input fdstart num format=pib8.; * lpLocalFileTime // converted file time;
arg 2 output fdstart num format=pib8.; * lpFileTime, // UTC file time to convert;
*-------------------------------------------------------------;
routine SetFileTime
minarg=4
maxarg=4
stackpop=called
module=Kernel32
returns=long
;
arg 1 num input byvalue format=pib4.; * HANDLE hFindFile // file search handle ;
arg 2 num input fdstart format=pib8.; * CONST FILETIME * lpCreationTime, // pointer to creation file time ;
arg 3 num input fdstart format=pib8.; * CONST FILETIME * lpModifiedTime, // pointer to creation file time ;
arg 4 num input fdstart format=pib8.; * CONST FILETIME * lpAccessedTime, // pointer to creation file time ;
;;;;
run;
filename winapi;
filename sascbtbl catalog 'WORK.Windows.WINAPI.SOURCE';
%macro touch(path=, year=);
data _null_ ;
GENERIC_READ = 080000100x; /* GENRIC_READ + FILE_WRITE_ATTRIBUTES(0x0100) */
FILE_SHARE_READ = 1;
OPEN_EXISTING = 3;
length path $260;
path = "&path";
HANDLE = modulen('CreateFileA', path, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0,0);
If HANDLE >= 1 Then Do;
cdt_n = datetime();
MINUTE = Minute( cdt_n);
HOUR = Hour( cdt_n);
DAY = DAY( DatePart( cdt_n) );
DAYOFWK = WeekDay( DatePart( cdt_n) );
MONTH = MONTH( DatePart( cdt_n) );
YEAR = &year;
SECONDS = 0;
MSECONDS = 0;
CREATED = .;
CREATED1 = .;
rc = ModuleN('SystemTimeToFileTime', YEAR, MONTH, DAYOFWK, DAY, HOUR, MINUTE, SECONDS, MSECONDS, CREATED);
rc = ModuleN('LocalFileTimeToFileTime', CREATED, CREATED1);
put rc= created= created1=;
ACCESSE1 = CREATED1;
WRITTEN1 = CREATED1;
rc = ModuleN('SetFileTime', HANDLE, CREATED1, ACCESSE1, WRITTEN1);
put rc=;
rc = Modulen('CloseHandle', HANDLE);
put rc=;
end;
run;
%mend;
%touch(path=c:\temp\foo.txt, year=2009);
filename sascbtbl clear;
ん、これ環境変えたら動かないので直します。
返信削除