Я нахожусь в процессе отладки приложения и обнаружил, что оно использует строку подключения к базе данных, зашифрованную в поле «Db» в файле .ACF. Пока я работал над тем, как написать процедуру дешифрования / шифрования, я не могу записать свое новое значение.
Пример фрагмента кода PowerShell:
Add-Type -Path C:\app\adodb.dll
Add-Type -TypeDefinition $decryptCode
$recordSet = New-Object ADODB.RecordsetClass
$recordSet.Open("c:\app\connectionstring.acf",[Type]::Missing,[ADODB.CursorTypeEnum]::adOpenKeySet,[ADODB.LockTypeEnum]::adLockBatchOptimistic)
$dbEncrypted = $recordSet.Fields["Db"].Value
"Current Connection String: $([Decryptor.NativeMethods]::Decrypt($dbEncrypted))"
# update connection string
$newConnectionString = "<blah blah blah>"
$recordSet.Fields["Db"].Value = [Decryptor.NativeMethods]::Encrypt($newConnectionString)
$recordSet.Save()
Этот код читает строку подключения и расшифровывает ее ОК. Он также прекрасно шифрует новую строку подключения. Однако при попытке обновить поле «Db» выдает ошибку:
Настройка исключения «Значение»: «Многошаговая операция вызвала ошибки.
Проверьте каждое значение состояния. "В C: \ debugging \ Decryptor.ps1: 329 char: 1
+ $ recordSet.Fields ["Db"]. Value = [Decryptor.NativeMethods] :: Encrypt ($ n ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo: NotSpecified: (:) [], SetValueInvocationException
+ FullyQualifiedErrorId: ExceptionWhenSetting
[Decryptor.NativeMethods] :: Encrypt возвращает строку, хотя не все символы пригодны для печати, и строка длиннее исходной строки.
Я могу установить значение БД для обычных строк или строку, которую я только что прочитал из базы данных:
$recordSet.Fields["Db"].Value = $dbEncrypted
Я подумал, что это может быть размер, поскольку исходная зашифрованная строка содержала 147 символов, а новая - 179 символов. Поэтому я сократил новую строку до 147 символов, и даже меньше, но она все равно не будет установлена. Поэтому я подозреваю, что это связано с содержимым строки.
Строка, которую я пытаюсь установить, выглядит следующим образом:
Ì Ì Ì Ì Ì ù ù Ò Ò J · D R R R L L L L L ((! $ ($ $ \ \ \ \ \ \ \ \ \ H h h h þ þ þ Z Z Z Z Z Z Z Z Z)
ÕeæB¦ëvpâNÉ oSÆ! FZÆÿ²ÔFôó Ûvºä2øg
¹¼ àU¸ÏAß0g§ÿ¨brÁƾ('îÙ2ÿééµHãhû
= ¿6Å = # ´ú½¬ö
$ recordSet показывает следующие значения:
Properties : {IAccessor, IChapteredRowset, IColumnsInfo, IColumnsRowset...}
AbsolutePosition : 1
ActiveConnection :
BOF : False
Bookmark : 1
CacheSize : 1
CursorType : adOpenStatic
EOF : False
Fields : {DB}
LockType : adLockBatchOptimistic
MaxRecords : 0
RecordCount : 5
Source : c:\app\connectionstring.acf
AbsolutePage : 1
EditMode : adEditNone
Filter : 0
PageCount : 1
PageSize : 10
Sort :
Status : 8
State : 1
CursorLocation : adUseClient
MarshalOptions : adMarshalAll
DataSource : ADODB.RecordsetClass
ActiveCommand :
StayInSync : True
DataMember :
Index :
Текущие настройки для набора записей. Поля ["db"] показывают:
$ recordSet.Fields [ "Db"]
Status : 0
ActualSize : 147
Attributes : 4
DataFormat :
DefinedSize : 255
Name : DB
NumericScale : 0
OriginalValue :
Precision : 0
Properties : {BASECOLUMNNAME, BASETABLENAME, BASECATALOGNAME, BASESCHEMANAME...}
Type : adVarChar
UnderlyingValue :
Value : £àöÌóÓà™ù:Ò¡J·DµÕ1R|SÀgÐqíÀZ(Lá2 !¯'B$Rä\!kýȘg\ISX ê‰mh®¾ oÔçþOZißlß%¼ù€@Š˜ ÕeæB¦ëvpâNÉ
oSÆ!fZ–Æÿ²ÔFôó Ûvºä2øÀü"ëöÑ@Õ k§«üdÊ'Ó‹Û§1j©
$ recordSet.Fields ["Db"]. Свойства содержат
Attributes Name Type Value
---------- ---- ---- -----
1 BASECOLUMNNAME adVarWChar
1 BASETABLENAME adVarWChar
1 BASECATALOGNAME adVarWChar
1 BASESCHEMANAME adVarWChar
1 KEYCOLUMN adBoolean False
1 ISAUTOINCREMENT adBoolean False
1 RELATIONCONDITIONS adVarBinary
1 CALCULATIONINFO adVarBinary
1 OPTIMIZE adBoolean False
При дальнейшем тестировании с различными строками найдена эта строка:
$recordSet.Fields["Db"].Value = "£àöÌóÓà"
Но эта строка не работает:
$recordSet.Fields["Db"].Value = "£àöÌóÓà"
Exception setting "Value": "Multiple-step operation generated errors. Check each status value."
At line:1 char:1
+ $recordSet.Fields["Db"].Value = "£àöÌóÓà"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], SetValueInvocationException
+ FullyQualifiedErrorId : ExceptionWhenSetting
Дальнейшее тестирование выявляет следующее:
$broken = "£àöÌóÓà"
$working = "£àöÌóÓà"
# $broken.Length = 9
# $working.Length = 7
[System.Text.UTF8Encoding]::UTF8.GetBytes($working)
194
163
195
160
195
182
195
140
195
179
195
147
195
160
[System.Text.UTF8Encoding]::UTF8.GetBytes($broken)
194
163
195
160
195
182
195
140
195
179
195
147
195
160
194
129
194
153