”規定のスクリプトホストを変更できません。”と出た場合の対応


自宅のWindows8スクリプトホストの変更ができなかったので
対応を調べたときのメモ。

C:\root\004_開発\WSH>CScript //H:CScript
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.

CScript エラー: 既定のスクリプト ホストを変更できません。

上記メッセージは、該当レジストリに書き込めない為に出力される。


Google先生に聞くと、以下の情報が見つかった。
レジストの中身を直接変更する
regeditで見てみると、確かにスクリプトホストがWScript.exeとなっていたが、
直観的になんか違うような気がして、もう少し調べると、、
レジストリに書き込めないからエラーの情報を見て、単純に権限がないだけじゃないかと思い、
レジストリエディタから、VBFile*1の権限を見ると、
同じログインユーザで、admin権限版と、一般ユーザ版の権限が存在していた。


コマンドプロンプトを管理者で実行すると、

C:\WINDOWS\system32>cscript //H:CScript
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.

既定のスクリプト ホストが "cscript.exe" に設定されました。

難なく変更ができた。
変更できないDOSはタイトルがコマンドプロンプトだが、
管理者で起動すると、「管理者:コマンドプロンプト」と出ていた。

scpでパスワードなしでコピーするには

通常は、scp実行後にパスワードを求められるが、鍵をクライアントとサーバで共有することで、
パスワードを省くことができる。
こちらのサイトを参考に、というかここに書いてある通りにすればできた。

  1. クライアント側で鍵を生成する(ssh-keygenコマンド)
  2. 公開鍵をサーバ側にもっていく。ここは手動?scp*1でもっていく。
  3. scpをする際の相手側ユーザのホーム直下に.sshを作る*2
  4. .ssh配下に認証リストを作る*3
  5. 認証リストにクライアント側の公開鍵を追加する。cat 公開鍵 >> 認証リストで良い。

注意なのは、公開鍵はリネームしてもよいが、秘密鍵をリネームすると、意味がない*4

*1:パスワードを求められる

*2:なければ

*3:これもなければ

*4:結局パスワードを求められる

Windows8でtelnetを有効化するには

WindowsServerだと、サーバマネージャで、機能の追加を選べば、楽々入るが、
Windows8の場合は以下の手順で有効化させる。

  1. アプリの検索で、”コントロールパネル”を入れる。
  2. 表示させたら、まずピン止めする。
  3. プログラムを選ぶ。
  4. Windowsの機能の有効化〜を選ぶ。
  5. telnetクライアントを選んでOKを押す。


HyperVもリストにあって驚いた。
なんだ仮想化できるのか。

case1個で複数の条件を表現するには

Bシェルのcaseで複数の条件を一度に表現できる。

#!/bin/sh
#caseに複数を条件を持たせる例

case $1 in
	"X" | "Y" | "Z")
		echo "XかYかZが入力されました"
		;;
	*)
		echo "それ以外の入力です:$1"
		;;
esac

以下、実行結果。

sample$ ./test.sh X
XかYかZが入力されました
sample$ ./test.sh Y
XかYかZが入力されました
sample$ ./test.sh Z
XかYかZが入力されました
sample$ ./test.sh A
それ以外の入力です:A

開発サーバと本番サーバで条件分岐させたいけど、
本番サーバ#1と#2が同じ処理の場合は、
ifよりcaseで、|(or)表現にした方がわかりやすい。

変数を立て続けに宣言した場合と、1行ずつ宣言した時で、型が異なるらしい。

ysK_Tech2015-01-12

参照渡しを用いて、再帰的に処理を進める関数を作っていて、
型が違うエラーが出て、はまった対応のメモ。

' 関数funcを参照渡しから値渡しにすると動くが、なぜかこのコードは動かない。
Sub ボタン2_Click()

    Dim val1, val2 As Integer
    Dim str As String
    
    val1 = 10
    val2 = 20
    str = "こんにちは"
    
    Call func(val1, val2, str)
    
    MsgBox ("val1=" & val1 & "val2=" & val2 & "str=" & str)
End Sub


Sub func(ByRef val1 As Integer, ByRef val2 As Integer, ByRef str As String)

    val1 = 100
    val2 = 200
    str = "こんばんは"

End Sub

このコードを実行すると、以下のダイアログが出力されて実行できない。

                                                    • -
Microsoft Visual Basic for Applications
                                                    • -
コンパイル エラー: ByRef 引数の型が一致しません。
                                                    • -
OK ヘルプ
                                                    • -

エディタ上は、funcのval1が反転して止まってしまう。


不思議なことに参照渡しを値渡しに変えると普通に実行される。
なんで?何が違うんだ?とはまりました。


そして、次のように、変えたら動きました。

'参照渡しでもうごくコード。
Sub ボタン2_Click()

    Dim val1 As Integer
    Dim val2 As Integer
    Dim str As String
    
    val1 = 10
    val2 = 20
    str = "こんにちは"
    
    Call func(val1, val2, str)
    
    MsgBox ("val1=" & val1 & "val2=" & val2 & "str=" & str)
End Sub


Sub func(ByRef val1 As Integer, ByRef val2 As Integer, ByRef str As String)

    val1 = 100
    val2 = 200
    str = "こんばんは"

End Sub

ウィッチで確認できないから*1
推測だけど、

    Dim val1, val2 As Integer

と、

    Dim val1 As Integer
    Dim val2 As Integer

では型が違うのか?横並びのときは、左から読んだときに、変数の続きがあって、
まだ確定できないからobject型になるとか?
でもIntegerをObjectに変えたところで結果は同じだった。


解せないが、こういう仕様という事で理解しないとダメなのか。

*1:コンパイルできませんと出て、emptyになってしまう

Javaのインストールに失敗する対応メモ

お客のWindows7端末で、Javaを最新にアップデートしようとしたら、
エラーになってしまい、「なんとかして!」と言われて対応した時のメモ*1

  • ラクルのHPからインストールをするとエラーが出る。*2
  • 手元にexeをダウンロードして、管理者権限で起動したがやっぱり同じエラーになる。起動するがすぐエラーになる(動いていない?)
  • ダウンロードしたexeを右クリック>プロパティから互換モードで色々いじったが効果なし。
  • フォルダの権限をフル権限にしたが効果なし。
  • セキュリティソフトをオフにしたがやっぱり効果なし。


何か言い訳を考えながら、イベントログのアプリケーションを除くと、

ソース "MsiInstaller" からのイベント ID 10011 の説明が見つかりません。このイベントを発生させるコンポーネントがローカル コンピューターにインストールされていないか、インストールが壊れています。ローカル コンピューターにコンポーネントをインストールするか、コンポーネントを修復してください。

イベントが別のコンピューターから発生している場合、イベントと共に表示情報を保存する必要があります。

イベントには次の情報が含まれています:

Product: XXXXXXX -- 指定された状態で使用するには無効なキーです。

(NULL)
(NULL)
(NULL)
(NULL)
(NULL)

メッセージ リソースは存在しますが、メッセージが文字列テーブル/メッセージ テーブルに見つかりません。

と出力されていた。
この中で、「指定された状態で使用するには無効なキーです」とエラーが出ており、この文言でgoogle先生に聞いてみると、
インストーラーのパッチで権限強化されて一部のアプリがインストールできないページを発見!


パッチ「KB2918614」が悪さ?をしているようで、
コンパネからアプリケーションの削除で、上記のパッチを消したところ無事インストーラーが起動して、作業完了!*3


[教訓]:困ったらとりあえずイベントログのアプリケーションログを覗いてみよう。

*1:受託範囲外なんですけど!と言いたかった・・

*2:内容忘れた

*3:安堵

自分と同じ階層の、特定のエクセルのみシートを全コピーする

月例会でバラバラに提出された報告資料を、総括ファイルにワンタッチでまとめるvba
これで毎回ブックを開いて、シートのコピーをしなくてよいわけだ。

' 同じ階層の、特定のエクセルファイルのシートを結合する
' このvbaで発生するいかなる問題に対して、私は責任を持ちません。
' コピペは自己責任でお願いします。
Private Sub cmdSum_Click()

    ' カレントパスの取得
    Dim curPath As String
    curPath = ThisWorkbook.Path
    'MsgBox (curPath)
    
    ' 配下のファイルを取得
    Dim objFS As Object
    Set objFS = CreateObject("Scripting.FileSystemObject")

    Dim objDir As Object
    Set objDir = objFS.GetFolder(curPath)
    
    ' 目的のエクセルファイルならシートをコピーする
    ' もしマージ資料が増えたら、ここに追記していけばよい。
    Dim tgt(2) As String
    tgt(0) = "@001_資料1.xls"
    tgt(1) = "@002_性能2.xls"
    tgt(2) = "@003_性能3.xls"


    Dim i As Integer
    For i = 0 To UBound(tgt)
    
        ' 対象ファイルが存在しない場合は、読み飛ばすか確認
        If (objFS.FileExists(curPath + "\" + tgt(i)) = True) Then
                    
            ' エクセルファイルを開いてシートをコピーする
            Dim wb, wbBase As workBook
            Set wb = Workbooks.Open(Filename:=curPath + "\" + tgt(i), ReadOnly:=True)
            Set wbBase = Workbooks("総括.xls")
            
            ' 総括ブックの、シート末尾に順次追加する
            Dim j, wbBaseSheetsCnt
            wbBaseSheetsCnt = wbBase.Sheets.Count
            For j = wb.Sheets.Count To 1 Step -1
                wb.Sheets(j).Copy after:=wbBase.Sheets(wbBaseSheetsCnt)
            Next
            
            wb.Close

        Else
            If (MsgBox(tgt(i) + "が見つかりません。続行しますか?", vbYesNo) = vbNo) Then
                MsgBox ("処理を中断しました")
                Exit For
            End If

        End If
    Next
    
    ' 後始末
    Set objFS = Nothing

End Sub


肝は、総括ブックにシートを追加するときの順番。
末尾のシートから、総括ブックのシート末尾に追加しないと、、シートの順番がごちゃごちゃになる。