- - PR -
GUI登録されたタスクの編集
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2004-11-23 22:46
初めまして、内線110です。
WindowsXP上で、他のアプリケーションが登録したスケジュール(タスク)に対して横やりを入れたいと考えています。しかしいろいろと試してみましたが、なかなかうまくいく方法が見つからないので投稿させていただきました。 [開発環境] Windows XP SP1 VisualStudio .net 2003 [開発言語] VB.net [実行環境] WindowsXP SP1 こちらの過去の投稿にもあった方法ではありますが、今までに試した方法と状況は以下の通りです。 WMI経由でWin32_ScheduleJobを・・・ ---> GUIベースで登録したものには対応していないそうです。 http://www.microsoft.com/japan/technet/scriptcenter/schedule/default.mspx API経由でNetScheduleJob〜を・・・ ---> 後述 ファイルを解析して・・・ ---> 早々にリタイアしました というわけで、現在はAPI経由で以下のようなサンプルを作ってみましたが、エラーコード(戻り値:lngApiResult)が1702になり、頓挫しています。長々とで申し訳ありませんが添付しましたコード上の問題点、やり方の問題点などご教授いただけたらと思います。よろしくお願いします。 -------------[ code ]---------------- '************ 'タスクを取得 '************ Private Declare Auto Function NetScheduleJobEnum Lib "netapi32.dll" _ ( _ ByVal ServerName As String, _ ByRef PointerToBuffer As Long, _ ByVal PreferredMaximumLength As Long, _ ByRef EntriesRead As Long, _ ByRef TotalEntries As Long, _ ByRef ResumeHandle As Long _ ) As Long '************ 'メモリ解放 '************ Private Declare Auto Function NetApiBufferFree Lib "netapi32.dll" _ ( _ ByVal Buffer As Long _ ) As Long '************ 'メモリ移動 '************ Private Declare Auto Sub RtlMoveMemory Lib "Kernel32.dll" _ ( _ ByRef Destination As AT_ENUM, _ ByRef Source As Long, _ ByVal Length As Long _ ) '************ '定数、クラス '************ Private Const MAX_PREF_LEN = -1& Private Const NERR_Success = 0 Private Const ERROR_MORE_DATA = 234& Private Class AT_ENUM Public JobId As Long Public JobTime As Long Public DaysOfMonth As Long Public DaysOfWeek As Byte Public Flags As Byte Public dummy As Integer Public Command As Long End Class '************ 'タスク取得 '************ Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim lngApiResult As Long Dim strServerName As String Dim lngBufferPointer As Long Dim lngEntriesRead As Long Dim lngTotalEntries As Long Dim lngResumeHandle As Long = Nothing Dim lngEntry As Long Dim udtAtEnum As AT_ENUM Dim lngTemp As Long Dim varTemp strServerName = "" '取得 lngApiResult = _ NetScheduleJobEnum( _ strServerName, _ lngBufferPointer, _ MAX_PREF_LEN, _ lngEntriesRead, _ lngTotalEntries, _ lngResumeHandle _ ) If (lngApiResult = NERR_Success) Or (lngApiResult = ERROR_MORE_DATA) Then For lngEntry = 0 To lngEntriesRead - 1 lngTemp = lngBufferPointer + Len(udtAtEnum) * lngEntry RtlMoveMemory(udtAtEnum, lngTemp, Len(udtAtEnum)) Next End If 'メモリ解放 If lngBufferPointer <> 0 Then NetApiBufferFree(lngBufferPointer) End If End Sub [ メッセージ編集済み 編集者: 内線110 編集日時 2004-11-23 22:48 ] | ||||||||||||
|
投稿日時: 2005-08-09 15:19
はじめまして。Micaです。
投稿された件、解決しましたでしょうか??? 実は同じような現象が起きていまして、調査しているうちににここにたどり着きました。 6.0で試してみたところ、ServerNameを指定すると上手くいくことがわかりました。 ""だと1702が返ってきます。 そこでVB.Netで同じように試してみたところ、訳のわからない、桁数が随分多い値が返ってきました。 古い投稿に対して、しかも返信ではなくて申し訳ありませんが、もし解決済みであれば、ご教授いただけませんでしょうか??? | ||||||||||||
|
投稿日時: 2005-08-09 15:38
件名のことについては全く詳しくありませんが、Micaさんの現象はおそらく数値型に関する変更が原因だと思います。
VB6まではLongは32ビット値でしたが、VB.NETになってLongは64ビット値に変わり、Integerがその代わりに32ビット値になりました。 またVB6の16ビット値であるInteger型はVB.NETではShort型になっています。 | ||||||||||||
|
投稿日時: 2005-08-12 15:57
Hongliangさま、お返事ありがとうございます。
ご指摘のとおり数値の型を変えてみましたところ、エラーコードに正しい数値が返ってくるようになり、取得も上手くいっているようです。(lngEntriesReadの値が正しいので、上手くいっていると仮定)・・・が、 lngTemp = lngBufferPointer + Len(udtAtEnum) * lngEntry RtlMoveMemory(udtAtEnum, lngTemp, Len(udtAtEnum)) で構造体「udtAtEnum.JobId」にポインタがそのまま入ってきてしまい、中身の参照ができません。 お気づきの点があればご教授ください。 よろしくお願いいたします。 | ||||||||||||
|
投稿日時: 2005-08-12 16:42
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=21701&forum=7&2
多分こんな感じでしょう。 .NETでポインタから構造体にするには、System.Runtime.IntoperServices.Marshal.PtrToStrucureメソッドを使用します。 | ||||||||||||
|
投稿日時: 2005-08-12 18:04
Hongliangさま、早速のお返事ありがとうございます。
前投稿の直後後、調査を続けていましたらそのサンプルを見つけ、現在挑戦中ですが、上手くいきません。。。 Dim obj As Object = System.Runtime.InteropServices.Marshal.PtrToStructure(current, wts) で、値を生成できないとコンパイルエラーになります。 どのようにしたら戻り値を取得できるようになるのでしょうか??? | ||||||||||||
|
投稿日時: 2005-08-12 18:33
あはは、コードを見返して唯一気になった点がばっちりヒットしちゃったようです。
ここでwtsが型指定せずに宣言されていますよね。ですからコンパイラによってObject型であると認識されます。 で、Marshal.PtrToStructureを確認すると
と二つのオーバーロードが見つかります。 wtsはObject型と認識されますから、上の方のオーバーロードを使っていると認識され……Subだから返値無しなのに返値があるとコーディングしてる、これはエラーだ……という寸法です。 wtsの宣言を型指定してやって下さい。それで解決するはずです。 ところで、
エラーメッセージはできる限り正しく書くようにしましょう。 「できない」ではなく「しない」となっているはずです。こういうニュアンスも原因推定に重要ですから。 //VS2002のドキュメントエクスプローラでは何故かVB.NETのエラーコードがキーワードでも検索でも引っかからない……。 | ||||||||||||
|
投稿日時: 2005-08-12 20:44
コンパイルエラーとれました。ありがとうございます。
。。。とここで、本来やりたかった処理に戻って、まとめてみました。
これを実行すると、 Dim obj As Object = System.Runtime.InteropServices.Marshal.PtrToStructure(current, typAtInfo) にて、「'System.NullReferenceException' のハンドルされていない例外が mscorlib.dll で発生しました。追加情報 : オブジェクト参照がオブジェクト インスタンスに設定されていません。」・・・というエラーが発生します。 currentにはポインタが入ってきているようです。 typAtInfoの型に問題があるのでしょうか??? 度々で申し訳ございませんが、お気づきの点があればご教授願います。 |