관리 메뉴

kisoo

[레지스트리]PendingFileRenameOperations & RunOnce 본문

01.About Programming /9..VC++

[레지스트리]PendingFileRenameOperations & RunOnce

JamesK78 2009. 7. 28. 09:28
Setup] PendingFileRenameOperations & RunOnce

Application을 설치하는 중에 재부팅을 하는 경우가 있습니다.
Application 설치 중 다른 File(DLL 과 같은 File) 을 사용해야 하는 경우가 생기는데, 이때 해당 File 이 다른 Process 가 사용하고 있는 경우, 재부팅을 요청하게 됩니다.
재부팅 후 남은 Procedure 는 해당 Process를 다시 실행해야 하는 것입니다. 이것을 저장하는 곳이 다음의 Registry 입니다.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\PendingFileRenameOperations

해당 Registry 는 MSI 에 의해서 보통 사용합니다만, 다음과 같은 Method 호출 시에도 사용됩니다.
일전에 진행하던 Case 입니다만… :-)

MoveFileEx() 의 DWORD dwFlags 를 MOVEFILE_DELAY_UNTIL_REBOOT 을 사용 하였을 경우 다음과 같은 조건을 만족해야 합니다.

  1. File 은 Remote Share 에 존재할 수 없습니다.
    이는 MOVEFILE_DELAY_UNTIL_REBOOT 의 Mechanism 이 Reboot 된 후 Network Resource 를 사용하기 전에 수행 되기 때문입니다.
  2. Windows 2000 인 경우,  MAX_PATH 0x00000104 즉 260 characters 이상의 FileName 을 사용할 수 없습니다. (첫 번째 Parameter 인 lpExistingFileName 에는 Unicode version 을 사용하기 위한 Prefix 로 “\\?\” 를 사용할 수 없습니다.
  3. 사용자 계정(Windows에 로그온 한 계정) 은 LocalSystem account 이거나 또는 administrator group 에 속해 있어야 합니다.
  4. 이동하려는 File 이 이미 존재할 경우, MOVEFILE_REPLACE_EXISTING Flag 가 MOVEFILE_DELAY_UNTIL_REBOOT 함께 사용되어야 합니다.
  5. System File 은 사용할 수 없습니다.
    (System File 을 사용할 경우 OS 의 환경에 따라서 (개인적인 환경에 따라서) 동작을 하지 않는 경우가 대부분 발생합니다.

MoveFileEx() 가 동작 하지 않을 경우
우선, HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\PendingFileRenameOperations 의 Registry Value 가 정상적으로 입력되어 있는지 확인 하여야 합니다.
만일 Registry 에 해당 Value 가 존재하더라도 동작 하지 않는 경우는 다음과 같을 때 발생합니다.

  1. 이동하려는 Folder 에 Administrator Group 권한 또는 Local System 권한이 없는 경우 문제가 발생합니다.
  2. Registry 에 PendingFileRenameOperation2 가 생성되어 있다면, 이는 수행되지 않습니다. 이는 Windows Bug 입니다.

추가 사항
1.     Rebooting 후 해당 작업의 성공여부를 알 수 있는 방법을 API 로 제공하고 있지 않습니다.
2.     Hard Link 인 경우 작업 수행이 불가능 할 수 있습니다.

샘플


HKEY hKey;
DWORD dwStringValueSize
= 1024;
char szTemp[1024] = "";
char szBiosInfo[1024] = "";
DWORD ret
;

RegOpenKeyEx(
                         HKEY_LOCAL_MACHINE
,
                         
"SYSTEM\\CurrentControlSet\\Control\\Session Manager" ,
                         
0,
                         KEY_READ
,
                         
&hKey);
ret
= RegQueryValueEx(
                                          hKey
,
                                         
"PendingFileRenameOperations" ,
                                          NULL
, NULL, (LPBYTE)szTemp, &dwStringValueSize);

if( ret == ERROR_SUCCESS )
{
       
for( int i = 0; i < dwStringValueSize; i++ )
       
{
               
if(i == 0)
                        szBiosInfo
[i] = szTemp[i];
               
else
               
{
                       
if(szTemp[i] == '\0')
                                szBiosInfo
[i] = '\n';
                       
else
                                szBiosInfo
[i] = szTemp[i];
               
}
       
}
}

::MessageBox( NULL, szBiosInfo, TEXT( "" ), MB_OK );

char T[1024] = {"A\0B\0C\0D\0E\0\0"};
DWORD kSize
= 30;
RegOpenKeyEx(
                         HKEY_LOCAL_MACHINE
,
                         _T
("SYSTEM\\CurrentControlSet\\Control\\Session Manager" ),
                         
0,
                         KEY_ALL_ACCESS
,
                         
&hKey );

RegSetValueEx(
                          hKey
,
                          _T
("PendingFileRenameOperations" ),
                         
0,
                          REG_MULTI_SZ
,
                         
(LPBYTE)T,
                          kSize
);

RegCloseKey( hKey );
Comments