powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Экспорт/импорт ветки реестра целиком (HKEY_CURRENT_USER), проблемы однако
7 сообщений из 7, страница 1 из 1
Экспорт/импорт ветки реестра целиком (HKEY_CURRENT_USER), проблемы однако
    #39649647
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть большая прога (не моя).
Настройки юзера хранит в HKEY_CURRENT_USER\Software\Microsoft\Proga
Настроек до фига. Всех ветвлений и параметров не знаю и знать не хочу, причем подветка или параметр не обязательно присутствуют (набор не известен).
Задачи: 1) сохранить ветку целиком в backup-файл 2) восстановить ее оттуда
Существенным условием является что действия выполняются от имени HKEY_CURRENT_USER со своей веткой, а он по дефолту ноль без палочки (т.е. НЕ администратор).

1. Вариант очевидный и простой (regedit аля cmd-утилита reg.exe)
Код: vbnet
1.
2.
  reg export "HKEY_CURRENT_USER\Software\Microsoft\Proga" "C:\...путь...\file.reg"
  reg import "C:\...путь...\file.reg"


Увы, НЕ катит из-за так сказать несовершенства формата "Windows Registry Editor Version 5.00".
А не катит потому, что прога допускает для некоторых REG_SZ перенос строки, в текстовухе .reg это чудо при экспорте перенесется на 2 строки, при импорте параметр назад не запишется, будет глюк и при определенных действиях Proga сделает crash.

2. Второй вариант - тупо сохранять все ветви/параметры по одному. Т.к. "до фига. Всех ветвлений и параметров не знаю и знать не хочу, причем подветка или параметр не обязательно присутствуют (набор не известен)", то НЕ катит и НЕ вариант, проще повеситься.

3. Третий вариант - он у меня давно на вооружении, все ф-ции написаны и отточены, работает как часы.
Использует RegSaveKey , RegSaveKeyEx , RegRestoreKey
Ветка сохраняется в бинарник, а не в .reg, в общем-то импорт-экспорт работает идеально ( под админом!!! )
Приведу кусок ".Net"-кода под спойлером (чтоб не голословно), потом о проблеме .
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
  Public Function RegistrySaveKey(ByVal hKey As IntPtr, ByVal lpszSubKey As String, _
   ByVal lpFile As String, Optional ByVal SaveFlag As Integer = 0, _
   Optional ByVal reg64 As Boolean = False, Optional ByVal reg32 As Boolean = False) As Boolean
    'SaveFlag = 0 -используем RegSaveKey
    'SaveFlag = 1-3 -используем RegSaveKeyEx с указанием формата

    Dim dwRes As Integer
    Dim phkResult As IntPtr
    Dim hToken As IntPtr
    Dim bRtnBool As Boolean

    RegistrySaveKey = False 'default

    If IO.File.Exists(lpFile) Then
      Try
        IO.File.Delete(lpFile)
      Catch
        'Debug.Print("DeleteFile Error. Error code: " & Err.Number.ToString & " (" & Err.Description & ")")
        Exit Function
      End Try
    End If

    If reg64 Then
      dwRes = RegOpenKeyEx(hKey, lpszSubKey, 0, KEY_READ Or KEY_WOW64_64KEY, phkResult)
    ElseIf reg32 Then
      dwRes = RegOpenKeyEx(hKey, lpszSubKey, 0, KEY_READ Or KEY_WOW64_32KEY, phkResult)
    Else
      dwRes = RegOpenKeyEx(hKey, lpszSubKey, 0, KEY_READ, phkResult)
    End If
    If dwRes <> ERROR_SUCCESS Then
      'Debug.Print("RegOpenKeyEx Error " & RaiseAPIErrorByNumber(dwRes))
      Exit Function
    End If

    ' Open a handle to the access token for the calling process.
    bRtnBool = OpenProcessToken(Process.GetCurrentProcess().Handle, _
                            TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY, _
                            hToken)
    If bRtnBool = False Then
      'Debug.Print("OpenProcessToken Error " & RaiseAPIErrorByNumber(Err.LastDllError))
      dwRes = Err.LastDllError
      GoTo cleanup
    End If

    'Enable the SE_BACKUP_NAME privilege.
    dwRes = SetPrivilege(hToken, SE_BACKUP_NAME, True)
    If dwRes <> 0 Then
      Debug.Print("SetPrivilege (1) Error " & RaiseAPIErrorByNumber(dwRes))
      GoTo cleanup
    End If

    If SaveFlag = 0 Then
      dwRes = RegSaveKey(phkResult, lpFile, IntPtr.Zero)
      If dwRes <> ERROR_SUCCESS Then
        Debug.Print("RegSaveKey Error " & RaiseAPIErrorByNumber(dwRes))
      Else
        RegistrySaveKey = True
      End If
    Else
      dwRes = RegSaveKeyEx(phkResult, lpFile, 0, SaveFlag)
      If dwRes <> ERROR_SUCCESS Then
        Debug.Print("RegSaveKeyEx Error " & RaiseAPIErrorByNumber(dwRes))
      Else
        RegistrySaveKey = True
      End If
    End If

    'Disable the SE_BACKUP_NAME privilege.
    dwRes = SetPrivilege(hToken, SE_BACKUP_NAME, False)
    If dwRes <> 0 Then
      Debug.Print("SetPrivilege (2) Error " & RaiseAPIErrorByNumber(dwRes))
    End If

cleanup:
    If hToken <> IntPtr.Zero Then CloseHandle(hToken)
    If phkResult <> IntPtr.Zero Then RegCloseKey(phkResult)

  End Function

  'Enabling and Disabling Privileges in C++
  'http://msdn.microsoft.com/en-us/library/windows/desktop/aa446619(v=vs.85).aspx
  Public Function SetPrivilege( _
   ByVal hToken As IntPtr, _
   ByVal lpszPrivilege As String, _
   ByVal bEnablePrivilege As Boolean) As Integer
    ' hToken - access token handle
    ' lpszPrivilege - name of privilege to enable/disable
    ' bEnablePrivilege - to enable or disable privilege

    Dim tP As New TOKEN_PRIVILEGES
    Dim New_tp As New TOKEN_PRIVILEGES
    Dim mLUID As New LUID
    If LookupPrivilegeValue("", lpszPrivilege, mLUID) = False Then
      Debug.Print("LookupPrivilegeValue Error " & Err.LastDllError)
      SetPrivilege = Err.LastDllError
      Exit Function
    End If

    tP.PrivilegeCount = 1
    tP.pLuid = mLUID
    If bEnablePrivilege Then
      tP.Attributes = SE_PRIVILEGE_ENABLED
    Else
      tP.Attributes = 0
    End If
    If AdjustTokenPrivileges(hToken, False, tP, 4 + (12 * tP.PrivilegeCount), _
     New_tp, 4 + (12 * New_tp.PrivilegeCount)) = False Then
      Debug.Print("AdjustTokenPrivileges Error " & Err.LastDllError)
      SetPrivilege = Err.LastDllError
      Exit Function
    End If

    If Err.LastDllError = ERROR_NOT_ALL_ASSIGNED Then
      Debug.Print("AdjustTokenPrivileges Error " & Err.LastDllError)
      SetPrivilege = Err.LastDllError
      Exit Function
    End If

    'при успехе эта ф-ция вернет 0
    Return 0
  End Function



А проблема в том что RegSaveKey/RegSaveKey требуют The calling process must have the SE_BACKUP_NAME privilege enabled. и аналогично RegRestoreKey The calling process must have the SE_RESTORE_NAME and SE_BACKUP_NAME privileges Код мой естественно это учитывает и вызывает
Код: vbnet
1.
2.
    'Enable the SE_BACKUP_NAME privilege.
    dwRes = SetPrivilege(hToken, SE_BACKUP_NAME, True)

,
но AdjustTokenPrivileges
без прав админа не работает:
Код: vbnet
1.
SetPrivilege Error 1300 (Вызывающая сторона не обладает всеми необходимыми правами доступа)


Юзер сам себе, своему процессу, привелегий SE_BACKUP_NAME, SE_RESTORE_NAME and SE_BACKUP_NAME присвоить не может.
Итого, код требует админа, под просто юзер работать не будет .
Несмотря на то что ветка HKEY_CURRENT_USER и юзеру надо сохранить свою ветку, казалось бы.

Вопросы.
1. М.б. кто знает еще разумные варианты импорта/экспорта ветки реестра HKEY_CURRENT_USER(не .reg, не вариант 2 и не вариант 3)? Чтоб работал от имени этого CURRENT_USER (без админов)?

2. "Третий вариант" в общем случае бесправного юзера вылечить можно? Предположительный ответ - НЕТ.

3. Допустим я говорю. "Ладно, вызываем админа в помощь". Запустить другое приложение "из-под бесправного юзера" с запросом прав админа при запуске этого другого я умею.
Но я должен как-то передать в это другое параметр: CURRENT_USER,
потому как "админ" не обязательно совпадает с CURRENT_USER.
Поясню, моя ветка реестра:
HKEY_CURRENT_USER\
Она соответствует в моем случае вот такой:
HKEY_USERS\S-1-5-21-2878779045-650142709-39536251-1001\
И лезть "админу" очевидно надо будет именно туда, а не в CURRENT_USER
Как мне вычислить свою строку S-1-5-21-2878779045-650142709-39536251-1001 (для себя бесправного)?
...
Рейтинг: 0 / 0
Экспорт/импорт ветки реестра целиком (HKEY_CURRENT_USER), проблемы однако
    #39649648
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как мне вычислить свою строку S-1-5-21-2878779045-650142709-39536251-1001 (для себя бесправного)?
Код: vbnet
1.
strSID = WindowsIdentity.GetCurrent().User.Value


И соответственно, перезапустившись под админом и передав strSID в качестве параметра, импортировать/экспортировать
HKEY_USERS\strSID\Software\…
вместо
HKEY_CURRENT_USER\Software\…

Но вот все-таки не нравится, и ветка "моя", и сохраняю для себя, "As Admin" как то не в кассу здесь.
...
Рейтинг: 0 / 0
Экспорт/импорт ветки реестра целиком (HKEY_CURRENT_USER), проблемы однако
    #39649652
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2. "Третий вариант" в общем случае бесправного юзера вылечить можно? Предположительный ответ - НЕТ.
Третий мой вариант эквивалентен
Код: vbnet
1.
2.
  reg save "HKEY_CURRENT_USER\Software\Microsoft\Proga" "C:\...путь...\file.dat" /y
  reg restore "HKEY_CURRENT_USER\Software\Microsoft\Proga" "C:\...путь...\file.dat"



При запуске из НЕадминской cmd точно также требует админа:
Код: vbnet
1.
Ошибка: Клиент не обладает требуемыми правами.
...
Рейтинг: 0 / 0
Экспорт/импорт ветки реестра целиком (HKEY_CURRENT_USER), проблемы однако
    #39649743
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Дмитрий77,

Вы хотите прав админа без админа?

Можно. Напишите сервис, который будет стартовать под админскими правами и пусть он возвращает нужные вам данные
...
Рейтинг: 0 / 0
Экспорт/импорт ветки реестра целиком (HKEY_CURRENT_USER), проблемы однако
    #39650096
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cat2Вы хотите прав админа без админа?
Cat2, Вы невнимательны.
Я хочу ветку реестра (пользовательскую), этим пользователем корректно экспортировать/импортировать (без прав админа, что вполне таки логично, т.к. пользователь хозяин своего HKEY_CURRENT_USER).
Но к сожалению процедуры Backup/Restore (которые только корректны в моем случае, почему написал сверху) работают только под админом. В отличии от процедур Export/Import (в .reg файл) которые админа не требуют, но мне к сожалению не подходят.

Посему "админа" таки запускать придется. А как это реализовать у меня вопросов нет.
...
Рейтинг: 0 / 0
Экспорт/импорт ветки реестра целиком (HKEY_CURRENT_USER), проблемы однако
    #39650104
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cat2,

Хотя я кажется понял что Вы хотели сказать.
Некий сервис запущен с админскими правами.
Юзер передает сервису "задание", требующее админских прав, сервис это задание выполняет (для юзера).
...
Рейтинг: 0 / 0
Экспорт/импорт ветки реестра целиком (HKEY_CURRENT_USER), проблемы однако
    #39650155
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Дмитрий77Cat2,

Хотя я кажется понял что Вы хотели сказать.
Некий сервис запущен с админскими правами.
Юзер передает сервису "задание", требующее админских прав, сервис это задание выполняет (для юзера).
Именно так.
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Экспорт/импорт ветки реестра целиком (HKEY_CURRENT_USER), проблемы однако
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]