3流プログラマのメモ書き

元開発職→社内SE→派遣で営業支援→開発戻り浦島太郎状態の三流プログラマのIT技術メモ書き。 このメモが忘れっぽい自分とググってきた技術者の役に立ってくれれば幸いです。

(.Net).Netアプリケーションから Windows タスクスケジューラを操作する(@IT参考コード編)

(.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