「上書き保存(UAC対応)」の版間の差分
→変更履歴: 箇条書きの修正 |
SyntaxHighlightにcopyの追加 |
||
| (同じ利用者による、間の6版が非表示) | |||
| 13行目: | 13行目: | ||
== 変更履歴 == | == 変更履歴 == | ||
* 2013-02-02 | * 1.0.1 (2013-02-02) | ||
** バグ修正&UAC判定の強化 | ** バグ修正&UAC判定の強化 | ||
* 2013-01-27 | * 1.0.0 (2013-01-27) | ||
** 初版 | ** 初版 | ||
| 36行目: | 36行目: | ||
* 「外部でファイルが変更されています」のメッセージが表示される | * 「外部でファイルが変更されています」のメッセージが表示される | ||
* UAC 制御画面でキャンセルしても編集マーク(*)が消える(実際には保存されていない) | * UAC 制御画面でキャンセルしても編集マーク(*)が消える(実際には保存されていない) | ||
<syntaxhighlight lang="javascript"> | <syntaxhighlight lang="javascript" copy> | ||
#title="上書き保存" | #title="上書き保存" | ||
| 51行目: | 51行目: | ||
// 『無題』は通常処理 | // 『無題』は通常処理 | ||
if (! | if (!document.Name) { | ||
document.Save(); | |||
Quit(); | |||
} | } | ||
// 変更がない場合は保存しない | // 変更がない場合は保存しない | ||
if ( | if (document.Saved) { | ||
Quit(); | |||
} | } | ||
// ファイルがない場合は通常処理(Mery準拠) | // ファイルがない場合は通常処理(Mery準拠) | ||
var fso = new ActiveXObject("Scripting.FileSystemObject"); | var fso = new ActiveXObject("Scripting.FileSystemObject"); | ||
if (!fso.FileExists( | if (!fso.FileExists(document.FullName)) { | ||
document.Save(); | |||
Quit(); | |||
} | } | ||
// 書き込み禁止か取得 | // 書き込み禁止か取得 | ||
var file = fso.GetFile( | var file = fso.GetFile(document.FullName); | ||
if (file.Attributes & 0x01) { | if (file.Attributes & 0x01) { | ||
Alert("このファイルは読み取り専用です"); | |||
Quit(); | |||
} | } | ||
// UAC の判定 | // UAC の判定 | ||
if (!IsNeedUAC( | if (!IsNeedUAC(document.FullName)) { | ||
document.Save(); | |||
Quit(); | |||
} | } | ||
| 84行目: | 84行目: | ||
var shell = new ActiveXObject("Wscript.Shell"); | var shell = new ActiveXObject("Wscript.Shell"); | ||
var folder = shell.ExpandEnvironmentStrings("%TEMP%"); | var folder = shell.ExpandEnvironmentStrings("%TEMP%"); | ||
var tempFilePath = fso.BuildPath(folder, | var tempFilePath = fso.BuildPath(folder, document.Name); | ||
SaveToFile(tempFilePath, Document); | SaveToFile(tempFilePath, Document); | ||
var appShell = new ActiveXObject("Shell.Application"); | var appShell = new ActiveXObject("Shell.Application"); | ||
appShell.ShellExecute("cmd.exe", '/c COPY /Y "' + tempFilePath +'" "' + | appShell.ShellExecute("cmd.exe", '/c COPY /Y "' + tempFilePath +'" "' + document.FullName + '" & DEL "' + tempFilePath + '"', "", "runas", 2); | ||
UpdateSavedMark(true); | UpdateSavedMark(true); | ||
| 97行目: | 97行目: | ||
// UAC が必要かを判定 | // UAC が必要かを判定 | ||
function IsNeedUAC(path) { | function IsNeedUAC(path) { | ||
if (!path) { | |||
return false; | |||
} | |||
// 書き込み可能か確認 | |||
var fso = new ActiveXObject("Scripting.FileSystemObject"); | |||
try { | |||
fso.OpenTextFile(path, 8).Close(); | |||
return false; | |||
} catch (e) { | |||
// 排他制御中でも同じ結果を返すが判別できない | |||
} | |||
// OS 判定 | |||
// XP 以前は不要 | |||
var oLocator = new ActiveXObject("WBemScripting.SWbemLocator"); | |||
var oService = oLocator.ConnectServer(); | |||
var os = new Enumerator(oService.ExecQuery("SELECT * FROM Win32_OperatingSystem")); | |||
if (Number(os.item().Version.substring(0, 3)) < 6.0) { | |||
return false; | |||
} | |||
// ファイルの権限を確認 | |||
var SE_DACL_AUTO_INHERITED = 0x0400; | |||
var permission = new Enumerator(oService.ExecQuery("SELECT * FROM Win32_LogicalFileSecuritySetting Where Path='" + path.replace(/\\/g, "\\\\") + "'")); | |||
if (!permission.atEnd() && permission.item().ControlFlags & SE_DACL_AUTO_INHERITED) { | |||
return true; | |||
} | |||
return false; | |||
} | } | ||
// ファイル保存 | // ファイル保存 | ||
function SaveToFile(path, doc) { | function SaveToFile(path, doc) { | ||
var charset = "utf-8"; | |||
switch (doc.Encoding) { | |||
case meEncodingUTF16LEBOM: | |||
case meEncodingUTF16LENoBOM: | |||
case meEncodingUTF16BEBOM: | |||
case meEncodingUTF16BENoBOM: charset = "unicode"; break; | |||
case meEncodingUTF8BOM: | |||
case meEncodingUTF8NoBOM: charset = "utf-8"; break; | |||
case meEncodingUTF7: charset = "utf-7"; break; | |||
case meEncodingEUC: charset = "euc-JP"; break; | |||
case meEncodingJIS: charset = "iso-2022-jp"; break; | |||
case meEncodingShiftJIS: charset = "shift-jis"; break; | |||
} | |||
var adodb = new ActiveXObject("ADODB.Stream"); | |||
adodb.Charset = charset; | |||
adodb.Type = 2; | |||
adodb.Open(); | |||
adodb.WriteText(doc.Text.replace(/\n/mg, NEWLINE_CODE)); | |||
// BOM 削除処理 | |||
if (doc.Encoding == meEncodingUTF8NoBOM) { | |||
adodb.Position = 0; | |||
adodb.Type = 1; | |||
adodb.Position = 3; | |||
var binary = adodb.Read(); | |||
adodb.Close(); | |||
// 新規ストリームに BOM を除いた文字列を書き込む | |||
adodb.Open(); | |||
adodb.Write(binary); | |||
} | |||
adodb.SaveToFile(path, 2); | |||
adodb.Close(); | |||
}; | }; | ||
| 167行目: | 170行目: | ||
// すぐに反映されないので対処 | // すぐに反映されないので対処 | ||
function UpdateSavedMark(isSaved) { | function UpdateSavedMark(isSaved) { | ||
if (document.Saved != isSaved) { | |||
document.Saved = isSaved; | |||
var sel = document.selection; | |||
if (sel.GetActivePointX(mePosLogical) == 1 && sel.GetActivePointY(mePosLogical) == 1) { | |||
sel.CharLeft(); | |||
} else { | |||
sel.CharLeft(); | |||
sel.CharRight(); | |||
} | |||
} | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| 183行目: | 186行目: | ||
副作用(制限) | 副作用(制限) | ||
* 元に戻す、やり直しの履歴が削除される | * 元に戻す、やり直しの履歴が削除される | ||
<syntaxhighlight lang="javascript"> | <syntaxhighlight lang="javascript" copy> | ||
#title="上書き保存" | #title="上書き保存" | ||
| 196行目: | 199行目: | ||
// 『無題』は通常処理 | // 『無題』は通常処理 | ||
if (! | if (!document.Name) { | ||
document.Save(); | |||
Quit(); | |||
} | } | ||
// 変更がない場合は保存しない | // 変更がない場合は保存しない | ||
if ( | if (document.Saved) { | ||
Quit(); | |||
} | } | ||
// ファイルがない場合は通常処理(Mery準拠) | // ファイルがない場合は通常処理(Mery準拠) | ||
var fso = new ActiveXObject("Scripting.FileSystemObject"); | var fso = new ActiveXObject("Scripting.FileSystemObject"); | ||
if (!fso.FileExists( | if (!fso.FileExists(document.FullName)) { | ||
document.Save(); | |||
Quit(); | |||
} | } | ||
// 書き込み禁止か取得 | // 書き込み禁止か取得 | ||
var file = fso.GetFile( | var file = fso.GetFile(document.FullName); | ||
if (file.Attributes & 0x01) { | if (file.Attributes & 0x01) { | ||
Alert("このファイルは読み取り専用です"); | |||
Quit(); | |||
} | } | ||
// UAC の判定 | // UAC の判定 | ||
if (!IsNeedUAC( | if (!IsNeedUAC(document.FullName)) { | ||
document.Save(); | |||
Quit(); | |||
} | } | ||
var shell = new ActiveXObject("Wscript.Shell"); | var shell = new ActiveXObject("Wscript.Shell"); | ||
var folder = shell.ExpandEnvironmentStrings("%TEMP%"); | var folder = shell.ExpandEnvironmentStrings("%TEMP%"); | ||
var tempFilePath = fso.BuildPath(folder, | var tempFilePath = fso.BuildPath(folder, document.Name); | ||
// 保存前の状態を保持 | // 保存前の状態を保持 | ||
var sel = | var sel = document.selection; | ||
var latestText = | var latestText = document.Text; | ||
var sx = ScrollX, sy = ScrollY; | var sx = ScrollX, sy = ScrollY; | ||
var tx = sel.GetTopPointX(mePosLogical), ty = sel.GetTopPointY(mePosLogical); | var tx = sel.GetTopPointX(mePosLogical), ty = sel.GetTopPointY(mePosLogical); | ||
var bx = sel.GetBottomPointX(mePosLogical), by = sel.GetBottomPointY(mePosLogical); | var bx = sel.GetBottomPointX(mePosLogical), by = sel.GetBottomPointY(mePosLogical); | ||
var filePath = | var filePath = document.FullName; | ||
// 一時ファイルに保存して UAC 対応ムーブ | // 一時ファイルに保存して UAC 対応ムーブ | ||
document.Saved = true; | |||
document.Save(tempFilePath); | |||
var appShell = new ActiveXObject("Shell.Application"); | var appShell = new ActiveXObject("Shell.Application"); | ||
appShell.ShellExecute("cmd.exe", '/c COPY /Y "' + tempFilePath +'" "' + filePath + '" & DEL "' + tempFilePath + '"', "", "runas", 2); | appShell.ShellExecute("cmd.exe", '/c COPY /Y "' + tempFilePath +'" "' + filePath + '" & DEL "' + tempFilePath + '"', "", "runas", 2); | ||
| 246行目: | 249行目: | ||
// ファイルムーブの完了待ち(最大 1 秒) | // ファイルムーブの完了待ち(最大 1 秒) | ||
for (var i=0; i<50; i++) { | for (var i=0; i<50; i++) { | ||
Sleep(20); | |||
if (!fso.FileExists(tempFilePath)) { | |||
break; | |||
} | |||
} | } | ||
// ファイルを開き直す | // ファイルを開き直す | ||
// UACの昇格を拒否されていた場合は、エディタ上の内容だけ書き換え | // UACの昇格を拒否されていた場合は、エディタ上の内容だけ書き換え | ||
editor.OpenFile(filePath); | |||
var doc = | var doc = editor.ActiveDocument | ||
if (doc.Text != latestText) { | if (doc.Text != latestText) { | ||
doc.Text = latestText; | |||
} | } | ||
doc.Selection.SetActivePoint(mePosLogical, tx, ty); | doc.Selection.SetActivePoint(mePosLogical, tx, ty); | ||
| 269行目: | 272行目: | ||
// UAC が必要かを判定 | // UAC が必要かを判定 | ||
function IsNeedUAC(path) { | function IsNeedUAC(path) { | ||
if (!path) { | |||
return false; | |||
} | |||
// 書き込み可能か確認 | |||
var fso = new ActiveXObject("Scripting.FileSystemObject"); | |||
try { | |||
fso.OpenTextFile(path, 8).Close(); | |||
return false; | |||
} catch (e) { | |||
// 排他制御中でも同じ結果を返すが判別できない | |||
} | |||
// OS 判定 | |||
// XP 以前は不要 | |||
var oLocator = new ActiveXObject("WBemScripting.SWbemLocator"); | |||
var oService = oLocator.ConnectServer(); | |||
var os = new Enumerator(oService.ExecQuery("SELECT * FROM Win32_OperatingSystem")); | |||
if (Number(os.item().Version.substring(0, 3)) < 6.0) { | |||
return false; | |||
} | |||
// ファイルの権限を確認 | |||
var SE_DACL_AUTO_INHERITED = 0x0400; | |||
var permission = new Enumerator(oService.ExecQuery("SELECT * FROM Win32_LogicalFileSecuritySetting Where Path='" + path.replace(/\\/g, "\\\\") + "'")); | |||
if (!permission.atEnd() && permission.item().ControlFlags & SE_DACL_AUTO_INHERITED) { | |||
return true; | |||
} | |||
return false; | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
スポンサーリンク