exeファイルがサーバーからアクセスされたかどうかを確認する方法
-
21-09-2019 - |
質問
これは、クライアント・サーバ・アプリケーションです。私はexeファイルのファイル、実行するスクリプトのリストを交換し、ニーズが更新されることを何か他のものになる更新プログラムを作成しています。これは、サーバー上にインストールされます。
実行可能ファイルがネットワーク共有経由で開かれているかどうかを確認するために最初に私の必要性。私は、コンピュータの管理に、共有ファイル、開くファイルを行くことによって、この手動操作を行うことができます。これは、ファイルが開いているかどうかを確認するための唯一の方法であると思われます。私は、ファイルが開かれているかどうかを確認するためにR / Wを使用してみましたが、これは動作しませんでした。 Win32_ServerConnectionに見えたが、名前がない開いていたファイルのこのちょうど記載された番号。
私はそれは、Delphiで行うことができない場合のDelphi 7やC#でこれをコーディングしたいと思います。私はこれを行う方法上のサーバーが、何も上の開いているファイルを表示することができますいくつかのプログラムを発見しました。
解決
私は、ファイルシステム上のファイルを変更できるかどうかを確認するには、次のように関数を使用します。基本的に私はまだ開いて、fNameを呼ばれる新しいファイル「を作成」してみてください(それが存在しなければならない)、既存およびそれに有効なファイルハンドルを取得します。それが失敗した場合、そのファイルは使用中です。 この関数は、実際にファイルを作成しません。また、(私がハンドルに何かを決して)既存のfilessytemを変えるん。それは単に、私はそれで何かをしたいはずです、私はファイルへのファイルハンドルを取得できるかどうかを確認します。
このは、リモートコンピュータ上の共有から開かれたファイルのために働くます。
function IsFileInUse(fName: string): boolean;
var
HFileRes: HFILE;
begin
Result := false;
if not FileExists(fName) then
exit;
HFileRes := CreateFile(pchar(fName),
GENERIC_READ or GENERIC_WRITE,
0, nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
Result := (HFileRes = INVALID_HANDLE_VALUE);
if not Result then
CloseHandle(HFileRes);
end;
他のヒント
なぜあなたはそれを削除しようとしないのですか?ファイルが現在開いている場合は、エラーになります。そして、それが動作する削除する場合は、更新された実行ファイルを単にコピーすることができます。
Windows 2000では以降、あなたが使用することができます NetFileEnum のAPIます:
program test;
{$APPTYPE CONSOLE}
uses
Windows,
Classes,
SysUtils;
type
PFileInfo3 = ^TFileInfo3;
TFileInfo3 = record
fi3_id: DWORD;
fi3_permissions: DWORD;
fi3_num_locks: DWORD;
fi3_pathname: PWideChar;
fi3_username: PWideChar;
end;
TNetFileEnumCallback = function(const FileInfo: TFileInfo3; Data: Pointer): Boolean;
const
netapi = 'netapi32.dll';
function NetApiBufferFree(Buffer: Pointer): DWORD; stdcall; external netapi;
function NetFileEnum(servername: PWideChar; basepath: PWideChar; username: PWideChar; level: DWORD; var bufptr: Pointer;
prefmaxlen: DWORD; var entriesread: DWORD; var totalentries: DWORD; resume_handle: PDWORD): DWORD; stdcall;
external netapi;
procedure EnumNetFileUsers(const LocalPath: WideString; Callback: TNetFileEnumCallback; Data: Pointer = nil);
const
EntryCount = 32;
var
NetResult, EntriesRead, TotalEntries, ResumeHandle: Cardinal;
Buf: Pointer;
P: PFileInfo3;
I: Integer;
begin
EntriesRead := 0;
TotalEntries := 0;
ResumeHandle := 0;
repeat
NetResult := NetFileEnum(nil, PWideChar(LocalPath), nil, 3, Buf, EntryCount * SizeOf(TFileInfo3), EntriesRead,
TotalEntries, @ResumeHandle);
if not (NetResult in [ERROR_SUCCESS, ERROR_MORE_DATA]) then
RaiseLastOSError(NetResult);
try
P := Buf;
for I := 0 to EntriesRead - 1 do
begin
if Callback(P^, Data) then
Break;
Inc(P);
end;
finally
NetApiBufferFree(Buf);
end;
until NetResult = ERROR_SUCCESS;
end;
function ShowFileInfo(const FileInfo: TFileInfo3; Data: Pointer): Boolean;
begin
Result := False;
Writeln(Format('id: %d, permissions: $%.8x, num_locks: %d, pathname: ''%s'', username: ''%s''',
[FileInfo.fi3_id, FileInfo.fi3_permissions, FileInfo.fi3_num_locks, FileInfo.fi3_pathname, FileInfo.fi3_username]));
end;
begin
try
if ParamCount = 1 then
EnumNetFileUsers(ParamStr(1), ShowFileInfo);
except
on E: Exception do
begin
Writeln(Format('[%s] %s', [E.ClassName, E.Message]));
ExitCode := 1;
end;
end;
end.
。 LocalPath
パラメータに渡されたパスは、二重のバックスラッシュ、例えばそもそも持っているようです
test.exe C:\\Dev\Test\test.exe
(ファイル共有を介して開いている場合)は、以下の出力を生成
id: -469761405, permissions: $00000001, num_locks: 0, pathname: 'C:\\Dev\Test\test.exe', username: 'Ondrej'
また、MSDNが言うことに注意してください
「管理者のメンバーだけか サーバーオペレータローカルグループ缶 成功しNetFileEnumを実行 機能。 "
あなたは、これは上で実行されます、あなたが一致するためのプロセスのマシン名、ホスト名、またはコンピュータ名を検索することができますことを、「サーバ」の静的リストを保つことができます。そのリストには、あなたは、その開放地元を想定することができます。
string name = Environment.MachineName;
string name = System.Net.Dns.GetHostName();
string name = System.Windows.Forms.SystemInformation.ComputerName;
Process[] myProcesses = Process.GetProcessesByName("myExeProcName",MachineName);
foreach(Process myProcess in myProcesses)
{
Console.Write("MachineName : " + myProcess.MachineName + "\n");
}
あなたはSystem.IOでFileSystemWatcherを見たことがありますか?
http://msdn.microsoft.com/en -us /ライブラリ/ system.io.filesystemwatcher.aspxする