(.Net).Netアプリケーションから Windows タスクスケジューラを操作するの記事補足です。@ITの会議室に上がってたコードを VB.Net に変換したものです。
詳しくは上記記事を参考に。
ふと疑問に思ったのが、DLL を読んでるところです。
VB.Net から DLL の関数見るのって、Declare を使うんじゃなかったでしたっけ?
と思い見つけたのが【VB.NET】Windows APIの利用。
なるほど。Declare 使うのと、DLLImport属性使う方法があるっぽいです。
このサンプルでは、ole32.dll 内の CoCreateInstance メソッドを使って、クラスIDを渡し、ITaskScheduler オブジェクトを生成してるんですね。
(文字数制限のためハイライトは無しです)
Imports System.Runtime.InteropServices
Public Class Class2
' CLSID, IIDの定数定義
Private Shared CLSID_CTaskScheduler As New Guid("{148BD52A-A2AB-11CE-B11F-00AA00530503}")
Private Shared CLSID_CTask As New Guid("{148BD520-A2AB-11CE-B11F-00AA00530503}")
Private Shared IID_ITaskScheduler As New Guid("{148BD527-A2AB-11CE-B11F-00AA00530503}")
Private Shared IID_ITask As New Guid("{148BD524-A2AB-11CE-B11F-00AA00530503}")
'''
''' CLSCTX列挙子の定義
'''
'''
Public Enum CLSCTX
CLSCTX_INPROC_SERVER = &H1
CLSCTX_INPROC_HANDLER = &H2
CLSCTX_LOCAL_SERVER = &H4
CLSCTX_INPROC_SERVER16 = &H8
CLSCTX_REMOTE_SERVER = &H10
CLSCTX_INPROC_HANDLER16 = &H20
CLSCTX_RESERVED1 = &H40
CLSCTX_RESERVED2 = &H80
CLSCTX_RESERVED3 = &H100
CLSCTX_RESERVED4 = &H200
CLSCTX_NO_CODE_DOWNLOAD = &H400
CLSCTX_RESERVED5 = &H800
CLSCTX_NO_CUSTOM_MARSHAL = &H1000
CLSCTX_ENABLE_CODE_DOWNLOAD = &H2000
CLSCTX_NO_FAILURE_LOG = &H4000
CLSCTX_DISABLE_AAA = &H8000
CLSCTX_ENABLE_AAA = &H10000
CLSCTX_FROM_DEFAULT_CONTEXT = &H20000
CLSCTX_INPROC = CLSCTX_INPROC_SERVER Or CLSCTX_INPROC_HANDLER
CLSCTX_SERVER = CLSCTX_INPROC_SERVER Or CLSCTX_LOCAL_SERVER Or CLSCTX_REMOTE_SERVER
CLSCTX_ALL = CLSCTX_SERVER Or CLSCTX_INPROC_HANDLER
End Enum
'''
''' TASK_TRIGGER_TYPE列挙子の定義
'''
'''
Public Enum TASK_TRIGGER_TYPE
TASK_TIME_TRIGGER_ONCE = 0
TASK_TIME_TRIGGER_DAILY = 1
TASK_TIME_TRIGGER_WEEKLY = 2
TASK_TIME_TRIGGER_MONTHLYDATE = 3
TASK_TIME_TRIGGER_MONTHLYDOW = 4
TASK_EVENT_TRIGGER_ON_IDLE = 5
TASK_EVENT_TRIGGER_AT_SYSTEMSTART = 6
TASK_EVENT_TRIGGER_AT_LOGON = 7
End Enum
' ITaskSchedulerインターフェイスの定義
InterfaceType(ComInterfaceType.InterfaceIsIUnknown), _
Guid("148BD527-A2AB-11CE-B11F-00AA00530503")> _
Interface ITaskScheduler
Sub SetTargetComputer() ' dummy
Sub GetTargetComputer() ' dummy
Sub Enum_() ' dummy
Sub Activate() ' dummy
Sub Delete() ' dummy
Function NewWorkItem(<[In](), MarshalAs(UnmanagedType.LPWStr)> ByVal pwszTaskName As String, _
<[In](), MarshalAs(UnmanagedType.LPStruct)> ByVal rclsid As Guid, _
<[In](), MarshalAs(UnmanagedType.LPStruct)> ByVal riid As Guid _
) As
Object Sub AddWorkItem() ' dummy
Sub IsOfType() ' dummy
End Interface
' ITaskインターフェイスの定義
InterfaceType(ComInterfaceType.InterfaceIsIUnknown), _
Guid("148BD524-A2AB-11CE-B11F-00AA00530503")> _
Interface ITask
' IScheduledWorkItemインターフェイスメソッド
Function CreateTrigger(ByRef iNewTrigger As System.UInt16 _
) As
Object Sub DeleteTrigger() ' dummy
Sub GetTriggerCount() ' dummy
Sub GetTrigger() ' dummy
Sub GetTriggerString() ' dummy
Sub GetRunTimes() ' dummy
Sub GetNextRunTime() ' dummy
Sub SetIdleWait() ' dummy
Sub GetIdleWait() ' dummy
Sub Run() ' dummy
Sub Terminate() ' dummy
Sub EditWorkItem() ' dummy
Sub GetMostRecentRunTime() ' dummy
Sub GetStatus() ' dummy
Sub GetExitCode() ' dummy
Sub SetComment() ' dummy
Sub GetComment() ' dummy
Sub SetCreator() ' dummy
Sub GetCreator() ' dummy
Sub SetWorkItemData() ' dummy
Sub GetWorkItemData() ' dummy
Sub SetErrorRetryCount() ' dummy
Sub GetErrorRetryCount() ' dummy
Sub SetErrorRetryInterval() ' dummy
Sub GetErrorRetryInterval() ' dummy
Sub SetFlags() ' dummy
Sub GetFlags() ' dummy
Sub SetAccountInformation(<[In](), MarshalAs(UnmanagedType.LPWStr)> ByVal pwszAccountName As String, _
<[In](), MarshalAs(UnmanagedType.LPWStr)> ByVal pwszPassword As String)
Sub GetAccountInformation() ' dummy
' ITaskインターフェイスメソッド
Sub SetApplicationName(<[In](), MarshalAs(UnmanagedType.LPWStr)> ByVal pwszApplicationName As String)
Sub GetApplicationName() ' dummy
Sub SetParameters() ' dummy
Sub GetParameters() ' dummy
Sub SetWorkingDirectory() ' dummy
Sub GetWorkingDirectory() ' dummy
Sub SetPriority() ' dummy
Sub GetPriority() ' dummy
Sub SetTaskFlags() ' dummy
Sub GetTaskFlags() ' dummy
Sub SetMaxRunTime() ' dummy
Sub GetMaxRunTime() ' dummy
End Interface
' ITaskTriggerインターフェイスの定義
InterfaceType(ComInterfaceType.InterfaceIsIUnknown), _
Guid("148BD52B-A2AB-11CE-B11F-00AA00530503")> _
Interface ITaskTrigger
Sub SetTrigger(ByRef pTrigger As TASK_TRIGGER)
Sub GetTrigger() ' dummy
Sub GetTriggerString() ' dummy
End Interface 'ITaskTrigger
' CoCreateInstanceのインポート
_ Public Shared Function CoCreateInstance( _
<[In](), MarshalAs(UnmanagedType.LPStruct)> ByVal rclsid As Guid, _
ByVal pUnkOuter As Object, _ ByVal dwClsContext As CLSCTX, _
<[In](), MarshalAs(UnmanagedType.LPStruct)> ByVal riid As Guid _
) As
Object End Function
' TASK_TRIGGER構造体の定義
_ Public Structure TASK_TRIGGER
Public cbTriggerSize As System.UInt16
Public Reserved1 As System.UInt16
Public wBeginYear As System.UInt16
Public wBeginMonth As System.UInt16
Public wBeginDay As System.UInt16
Public wEndYear As System.UInt16
Public wEndMonth As System.UInt16
Public wEndDay As System.UInt16
Public wStartHour As System.UInt16
Public wStartMinute As System.UInt16
Public MinutesDuration As System.UInt32
Public MinutesInterval As System.UInt32
Public rgFlags As System.UInt32
Public TriggerType As TASK_TRIGGER_TYPE
'TRIGGER_TYPE_UNION Type;
Public Type1 As System.UInt16
Public Type2 As System.UInt16
Public Type3 As System.UInt16
Public TypePadding As System.UInt16
Public Reserved2 As System.UInt16
Public wRandomMinutesInterval As System.UInt16
End Structure
Public Sub Main()
Try
' タスクスケジューラ オブジェクトを取得する
Dim iTaskScheduler As ITaskScheduler = CType(CoCreateInstance(CLSID_CTaskScheduler, Nothing, CLSCTX.CLSCTX_INPROC_SERVER, IID_ITaskScheduler), ITaskScheduler)
' 新しいタスクを作成する
Dim iTask As ITask = CType(iTaskScheduler.NewWorkItem("TestTask", CLSID_CTask, IID_ITask), ITask)
' ITaskSchedulerインターフェイスを解放する
Marshal.ReleaseComObject(iTaskScheduler)
' 起動するアプリケーション名を設定する
iTask.SetApplicationName("notepad.exe")
' アカウント名、パスワードを設定する
iTask.SetAccountInformation("testuser", "passwd")
' トリガーを作成する
Dim iNewTrigger As System.UInt16
Dim iTaskTrigger As ITaskTrigger = CType(iTask.CreateTrigger(iNewTrigger), ITaskTrigger)
' スケジュールを設定する
Dim pTrigger As New TASK_TRIGGER()
pTrigger.cbTriggerSize = CType(Marshal.SizeOf(pTrigger), System.UInt16)
pTrigger.wBeginYear = 2009
pTrigger.wBeginMonth = 5
pTrigger.wBeginDay = 1
pTrigger.wStartHour = 0
pTrigger.wStartMinute = 0
pTrigger.TriggerType = TASK_TRIGGER_TYPE.TASK_TIME_TRIGGER_ONCE
iTaskTrigger.SetTrigger(pTrigger)
' ITaskTriggerインターフェイスを解放する
Marshal.ReleaseComObject(iTaskTrigger)
' IPersistFileインターフェイスを取得する
Dim pPersistFile As IntPtr = IntPtr.Zero
Dim IID_IPersistFile As Guid = Marshal.GenerateGuidForType(GetType(UCOMIPersistFile))
Marshal.QueryInterface(Marshal.GetIUnknownForObject(iTask), IID_IPersistFile, pPersistFile)
' ITaskインターフェイスを解放する
Marshal.ReleaseComObject(iTask)
' タスクをディスクへ保存する
Dim iPersistFile As UCOMIPersistFile = CType(Marshal.GetObjectForIUnknown(pPersistFile), UCOMIPersistFile)
iPersistFile.Save(Nothing, True)
' IPersistFileインターフェイスを解放する
Marshal.ReleaseComObject(iPersistFile)
Catch e As Exception
' 例外発生時にメッセージとスタックとレースを出力する
Console.WriteLine(e.Message)
Console.WriteLine(e.StackTrace)
System.Windows.Forms.MessageBox.Show(e.Message)
End Try
End Sub
End Class