ファイルタイムスタンプ取得 +α について – 固定ページ 3 – プログラミング – Home

ファイルタイムスタンプ取得 +α につ...
 
通知
すべてクリア

[解決済] ファイルタイムスタンプ取得 +α について

固定ページ 3 / 3

aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

サービスってのを作ったことが無いので詳しくは知りませんが
サーバってのは必ずしもネットワークの向こうにあるコンピュータを指しません。

たとえば、COM インプロセスサーバなんてのは、実体はローカルコンピュータ内にある
EXE だったり DLL だったりしますが、他のプログラムに機能を提供するという意味で
広義の「サーバ」と呼ばれます。

ただ、前述の MSDN 抜粋のサーバってのは狭義の意味で、ネットワークサーバのこと
でしょうから、そのビルド時のメッセージに出たサーバ云々と
GetFileInformationByHandle の成功/失敗は無関係だと思われますが。


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

あぁ… ATL 使ってるからですね。
ATL ってのは COM コンポーネントを簡単に作るためのものですから。
まさに例に出した「COM サーバ」を作ってたわけですね。


返信引用
あいる
 あいる
(@あいる)
ゲスト
結合: 20年前
投稿: 55
 

> そこで 変わりに
> Uninstall();を記述するか
これって本当に問題ない?用途的におかしいような・・・
# 言葉通りの動作するはずですけど・・・(^^;

> PostThreadMessage(dwThreadID, WM_QUIT, 0, 0);
> このようにすると正常に終了するみたいです

これの意図がわかりませんが、Run 内にメッセージループがあるから
メッセージ飛ばさなくてもreturn しちゃえば済むのでは・・・(^^;
気になるのは、PostThreadMessage の後にメッセージループを書いてるんじゃないの?
と言うことだけなんですけど、これって問題ないのかな?
# 個人的にはあまりよろしくないような気がする・・・(^^;
# 動作自体には問題ないのでしょうけどね・・・

サーバー云々は・・・COM からみてのサーバーとかだったような?
どっかにその辺りの記述があったような気もする・・・
# その辺りの言葉の使い方は別にどうでもいいと思うけどね・・・動作がはっきりしてれば
(^^;
なんにせよ、OS 種別としてのServer = サーバーと言ってるとは限らないって事ですね。
サービスやCOM から見ると、実行時の親をサーバーと呼んでるみたいです。
# 私の認識なので、違ったらどなたか訂正よろしく(^^;


返信引用
wood
 wood
(@wood)
ゲスト
結合: 23年前
投稿: 895
Topic starter  

シャノン さんへ
私の参考書「VISUAL C++6.0 ATLによる COM プログラミング入門」の14ページ
にこんなことが書かれていて「サーバー」と言う機能に該当しないものを作っている
意識で降りました

書籍一部引用
「ビューを持つコントロールをACTIVEX COMコントロールと呼び
 ビューが無いものをACTIVEX COMサービスと呼びます
 また、
 ACTIVEX COMの呼び出しをサポートする実行モジュールを
 ACTIVEX COM実行モジュールと呼びます(EXEタイプ)
 これらは
 どれもクライアント/サーバーで分類するとサーバーに属します」

「これらは」の意味を「ビューを持つEXE」だけが「サーバー」と呼ばれるのだと
勘違いしていたようです
つまり、ビューを持つと言う意味と、サーバーと言う意味にはビューは関係なく
「ACTIVEX COM」を使用するすべては、呼び出され方または、実行の仕方で
「サーバー」になりえると言うことのようです

大変申し訳ございませんが、「サーバー解釈論議」ついては尽きる事がなさそうなので
まことに勝手ながら、ここらで打ち切らさせていただきます
ありがとうございました


返信引用
wood
 wood
(@wood)
ゲスト
結合: 23年前
投稿: 895
Topic starter  

あいる さんへ

「TLCSVC6」これが今作っている本当の名前です、書き直すの面倒になったので
デバックウィンドウはそのままコピペします

>#これの意図がわかりませんが、Run 内にメッセージループがあるから
>#メッセージ飛ばさなくてもreturn しちゃえば済むのでは・・・(^^;
「return しちゃえば済むのでは」こんなこと全然思っても見てませんでした
やってみたら「PostThreadMessage(dwThreadID, WM_QUIT, 0, 0);」は
必要なくなりました

そして

KillTimer(NULL, m_timer);
SetServiceStatus(SERVICE_STOP_PENDING);
return ;

この方法でデバック・ステップ実行(以降も同様)を行い終了まで実行すると
デバックウィンドにこのように表示されます
システムが表示する「アサーサッション」の表示等は表示されずに終了できるみたい
なのですが(タスクマネージャも確認しました)
「例外処理」がちょっと気になりました、意味はまだわかってません、今後調べます

ーーーーーーーーーーーーーーーーーーーーーーーーーー
例外処理 (初回) は TLCSVC6.exe (KERNEL32.DLL) にあります: 0x000006EF: (名前があ
りません)。
スレッド 0x358 終了、終了コード 0 (0x0)。
プログラム 'E:\DEVPROJECTV6\TLCSVC6\Debug\TLCSVC6.exe' はコード 0 (0x0) で終了しまし
た。
ーーーーーーーーーーーーーーーーーーーーーーーーーー

こう、記述を変更して再実行
KillTimer(NULL, m_timer);
Uninstall();
return ;
結果 こうなりました
ーーーーーーーーーーーーーーーーーーーーーーーーーー
スレッド 0xEF5 終了、終了コード 0 (0x0)。
プログラム 'E:\DEVPROJECTV6\TLCSVC6\Debug\TLCSVC6.exe' はコード 0 (0x0) で終了しまし
た。
ーーーーーーーーーーーーーーーーーーーーーーーーーー

「Uninstall」を使ってみた発想は単純にAppWizardが生成したコードを眺めなおしたら
ただの直感で「アンインストール」と言う言葉に引かれて使ってしまいました


返信引用
wood
 wood
(@wood)
ゲスト
結合: 23年前
投稿: 895
Topic starter  

現在の最終ソース(一部割愛)
ーーーーーーーーーーーーーーーーーーーーーーーーーーー
void CServiceModule::Run()
{
_Module.dwThreadID = GetCurrentThreadId();


AppWizardが生成したコード


MSG msg;

       ↓↓↓↓ここから私がコーディングしたところ
// ユーザーコーディング ST   
// Handlerも同様に設定すること ←先に参考リンクを見て自分に言い聞かせるための
                 メモです(SetTimerに対するもの)

m_timer = SetTimer(NULL, NULL, 1000, NULL); //1秒設定
GetCurrentDirectory(sizeof(dir_str),dir_str);
strcat(dir_str,\\SCRIDX\\TLCSVC.IDX);
              ↑↑↑
               ここの実際のファオルダ名称を変更し以下の関数が
               失敗する用にしてデバックしてます

m_chkfil = CreateFile(
dir_str ,
GENERIC_READ|GENERIC_WRITE ,
FILE_SHARE_READ ,
NULL ,
OPEN_EXISTING ,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH |
     FILE_FLAG_RANDOM_ACCESS ,
NULL);

if(m_chkfil == INVALID_HANDLE_VALUE ){
sprintf(m_error_str,%s,GetSystemMessage(GetLastError()));
MessageBox(NULL,m_error_str, err,MB_OK);
KillTimer(NULL, m_timer);
Uninstall();
//SetServiceStatus(SERVICE_STOP_PENDING);
//PostThreadMessage(dwThreadID, WM_QUIT, 0, 0);
return ;
}else{
GetFileInformationByHandle(m_chkfil,&m_fil_info);
GetFileTime(m_chkfil,
             &m_Create_Time,&m_LastAccess_Time,&m_LastWrite_Time);

}
// ユーザーコーディング ED
           ↑↑↑↑  ここまで

while (GetMessage(&msg, 0, 0, 0))
{
if(msg.message == WM_TIMER) TLC_FIL_CHK(); ←これは私が追加したところ
                           です
DispatchMessage(&msg);
}
_Module.RevokeClassObjects();
CoUninitialize();
}
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

CreateFileの部分は、今後さらに書き直しますので気にしないでください

ちょっとご紹介
(私にとっては、便利だったので、既に知っている人にはどうでもいい事ですが)
http://www.roy.hi-ho.ne.jp/pastel/home/VC/errormsg.html


返信引用
ぽち
 ぽち
(@ぽち)
ゲスト
結合: 22年前
投稿: 24
 

はじめまして
ぽち といいます

ご存知かも知れませんが「VC6++ ATL サービス」を作成したときに参考にしたHPです。
http://program.station.ez-net.jp/special/vc/atl/service_vc6.asp
# 初めてサービスを作る私にもかなり参考になりました。

# 紹介だけというのも寂しいので、チョコッと書かせていただきます。

ATLのサービスをビルドすると
・デバッグビルド:ローカルサーバー
・リリースビルド:サービス
として登録されます。
# ローカルサーバーとして登録する理由としては、デバッグできるようにとのことです
# 間違ってたらすいません。

デバッグされていると言うことはローカルサーバーとして登録されているので、ビルド
の結果に
---------------------------
リンク中...
登録を行っています
サーバー登録が完了しました!  ←← ここ
ブラウザ データベースを作成中...

HOGEHOGE.exe - エラー 0、警告 0
---------------------------
こう出るわけです。

サービスとして登録すると、コントロールパネルの「サービス」から操作が可能となり
ます。
# ローカルサーバーでは、「サービス」からの操作はできません。

ここで本題なのですが(長くなってすいません)、問題のSetServiceStatus()はサービス
として登録しないと(?)実行できなかったと思います。
# おそらくこれが↓↓↓にあたるのでは?
ーーーーーーーーーーーーーーーーーーーーーーーーーー
例外処理 (初回) は TLCSVC6.exe (KERNEL32.DLL) にあります: 0x000006EF: (名前があ
りません)。
スレッド 0x358 終了、終了コード 0 (0x0)。
プログラム 'E:\DEVPROJECTV6\TLCSVC6\Debug\TLCSVC6.exe' はコード 0 (0x0) で終了
しまし
た。
ーーーーーーーーーーーーーーーーーーーーーーーーーー

解決策としては
・ローカルサーバーとして登録したらSetServiceStatus()を使用しない
・サービスと登録したらSetServiceStatus()を実行する
ローカルサーバーとサービスの見分けは、確かmService(BOOL型)という変数をチェック
とするとわかります。
# mServiceをいじっている箇所は_tWinMain()にあります。

# 長々書いてしまいましたが、ここまで書いてはずしていたらすいませんm(_ _)m


返信引用
あいる
 あいる
(@あいる)
ゲスト
結合: 20年前
投稿: 55
 

えーとですね・・・Uninstall は、MSDN より・・・
「実行中のサービスを停止し、サービス コントロール マネージャ データベースから削除しま
す。」
と言う動作します。問題大有りではないかと・・・(^^;
# 起動毎にインストール/アンインストールは不思議な動作かと・・・

なんにせよ、atlbase.h をまずは見た方がいいかと・・・
# VC6 にあったかな?ないかも?(^^;

それと、サービスステータスの意味ももう一度確認した方がいいと思います。
# 後始末してからPENDING ってのはちょっとね・・・

もうひとつ・・・return する前に後始末はきちんと終わらせましょう。
_Module.RevokeClassObjects();
CoUninitialize();
が呼ばれてないですね・・・

蛇足ですが、CoInitialize とCoUninitialize はいらないような・・・
AppWizard ではWinMain もServiceMain も書き出してくれてないと思いますが、
ServiceMain で呼んでるはずです。
# 手元にATL7.0 のソースしかなくていまいち自信なし(^^;
# ATL7.0 では開発がかなり楽にできるようなってます(^^;


返信引用
wood
 wood
(@wood)
ゲスト
結合: 23年前
投稿: 895
Topic starter  

ぽち さん 情報ありがとうございます
>mService
探してみます


返信引用
wood
 wood
(@wood)
ゲスト
結合: 23年前
投稿: 895
Topic starter  

あいるさんへ
>AppWizard ではWinMain もServiceMain も書き出してくれてないと思いますが、
VC6では書き出されていました
たぶん「CServiceModule::ServiceMain」と
「extern C int WINAPI _tWinMain(HINSTANCE hInstance,・・・」
のことだと思います

ご指摘頂いたそれぞれ、確認してから次に進みたいと思います

ぽち さん の解説からこのようにしてみました
----------------
sprintf(m_error_str,%s,GetSystemMessage(GetLastError()));
MessageBox(NULL,m_error_str, err,MB_OK);
KillTimer(NULL, m_timer);
if(m_bService == TRUE)
 SetServiceStatus(SERVICE_STOP_PENDING);
return ;
----------------

一度ここで済みにさせていただきます
ご両名の方々、いろいろ親切に解説していただき真にありがとうございました


返信引用
固定ページ 3 / 3

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました