2009-05-12 11 views
4

ファイルからの書き込み/読み取りがあり、アプリケーションの他のインスタンスのファイルをロックしたいとします。どのように私はそれを行うことができます(C + +ビジュアルスタジオ2003)? 私は_locking()を使ってみましたが、同じインスタンスで読み書きしようとすると自分自身がファイルにアクセスできませんでした。 LockFile()のオプションはありますが、正しく設定する方法はわかりません。 私を助けてください。Windows上でC++を使用してファイルをロックする

+0

この事実にも縛られていますか? –

+0

ハンドルをcreatefileからfstreamに変換する方法はありますか? –

+0

@Sofsr:この質問を見てください:http://stackoverflow.com/questions/839856/using-stdfstream-how-to-deny-access-read-and-write-to-the-file – Casebash

答えて

11

Win32 API CreateFileを使用し、共有権を指定しないでください。これにより、他のプロセスがそのファイルにアクセスすることができなくなります。

dwShareMode DWORDは、共有の種類を指定します(例:GENERIC_READ)。 0を指定すると、共有権を付与する必要がないことを意味します。

例:

HANDLE hFile = CreateFile(_T("c:\\file.txt"), GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); 

あなただけがLockFileLockFileExを使用することができ、ファイルの特定の部分をロックします。

例:

//Lock the first 1024 bytes 
BOOL bLocked = LockFile(hFile, 0, 0, 1024, 0); 

For locking on other platforms please see my post here

1

LockFileEx()(排他ロック)が必要です。 CおよびC++用のSecure Programming Cookbookのthis discussionをご覧ください。

1

オンラインでしばらく検索したところ、良い例は見つかりませんでした。

ここでは、プロセスの存続期間中にファイルをロックする目的でCreateFileを呼び出す方法を2つ紹介します。これは、グローバル名前付きミューテックスにCreateMutexを使用するCLimitSingleInstanceの面に沿って使用します。

CreateFileへの最初の呼び出しでは開こうとしますが、2番目の呼び出しでは必要に応じて作成されます。 私はもう少し徹底した実装をしています。 Qtで実装したので、std :: coutの代わりにqCritical()を使用し、代わりにQDir :: tempPath()を実装しました。ここで

class SingleInstance 
{ 
protected: 
    DWORD m_dwLastError; 
    HANDLE m_hFile; 
public: 
    SingleInstance(const char *strMutexName) { } 

    bool attemptToLockTempFile() 
    { 
     QString lockFile = QDir::tempPath() + "/My.exe.lock"; 
     m_hFile = CreateFileA(lockFile.toLocal8Bit().data(), GENERIC_READ, 0, 
           NULL, OPEN_EXISTING, 0, NULL); 
     DWORD dwLastError = GetLastError(); 
     if(m_hFile != NULL && m_hFile != INVALID_HANDLE_VALUE) 
     { 
      return true; 
     } 
     else 
     { 
      if(dwLastError == ERROR_FILE_NOT_FOUND) 
      { 
       m_hFile = CreateFileA(lockFile.toLocal8Bit().data(), GENERIC_READ, 
             0, NULL, CREATE_NEW, 0, NULL); 
       dwLastError = GetLastError(); 

       if(m_hFile != NULL && m_hFile != INVALID_HANDLE_VALUE) 
       { 
        return true; 
       } 
       else if(dwLastError == ERROR_SHARING_VIOLATION) 
       { 
        qCritical() << "Sharing Violation on My.exe.lock"; 
       } 
       else 
       { 
        qCritical() << "Error reading" << "My.exe.lock" << "-" << dwLastError; 
       } 
      } 
      else if(dwLastError == ERROR_SHARING_VIOLATION) 
      { 
       qCritical() << "Sharing Violation on My.exe.lock"; 
      } 
      else 
      { 
       qCritical() << "Unable to obtain file lock -" << dwLastError; 
      } 
      return false; 
     } 
    } 

    ~SingleInstance() 
    { 
     if (m_hFile != NULL && m_hFile != INVALID_HANDLE_VALUE) 
     { 
      ::CloseHandle(m_hFile); //Do as late as possible. 
      m_hFile = NULL; 
     } 
    } 
} 

はあなたの主な機能のトップに持っているだろうかです:私はのCreateFile()が、まだそれを試してみましたfstreamの/ファイルを使用しているとき、私は*ファイルへのハンドルを取得するにはどうすればよい

SingleInstance g_SingleInstanceObj(globalId_QA); 

// Makes sure that the program doesn't run if there is another 
// instance already running 
if (g_SingleInstanceObj.IsAnotherInstanceRunning()) 
{ 
    return 0; 
} 
関連する問題