sudo.cmd / su.cmd2015年10月18日 21時57分13秒

コマンドラインから管理者に昇格したい

たとえば、mklinkでシンボリックリンクを作りたい場合、いちいちcmd.exeを右クリックから「管理者として実行」するのは非常に面倒くさく、いま開いてるプロンプトから権限昇格できると便利だよね、と思って調べると、まぁいろいろな方々がすでにやってたりするわけです。

要は、WSHでShell.Application(エクスプローラを外部から操作するためのActiveXインターフェイス)で実行ファイルに対して「管理者として実行」で起動させる、という仕組みを使う、と。

んで、久々になんちゃってコマンド

んで、まぁ、suとかsudoとかを作ってみようかと。いや、先ほどのGoogle検索の結果に出てくるあちこちの記事でもすでに実現されてるんだけど、なんとなく自分でもやってみるか、という程度で。

suとsudoを別々に実装してもいいんだけど、cmd.exeを「管理者として実行」できればsu、任意のコマンドならsudoになるので、同じスクリプトを別のバッチファイルから呼び出す方式で実装することに。

ダウンロード

こちらからダウンロードをどうぞ。

sudo / suコマンド一式

zipには

  • scripts/sudo.js
  • su.cmd
  • sudo.cmd
の3つのファイルが格納されてるので、この構造を維持したままパスが通ったところに設置するとコマンドラインからいつでも使えるようになります。

ソース - scripts/sudo.js

スクリプトのソースはこんな感じ。

キモは最後のほうにある「new ActiveXObject("Shell.Application").ShellExecute()」のところで、ここで第4引数に"runas"を与えると、エクスプローラのコンテキストメニューから「管理者として実行」を行ったことになる、という感じです。詳しくは以下のリンク先を参照。

Shell.ShellExecute method (Windows)

ソース - sudo.cmd

sudoのバッチはこんな内容です。

バッチに渡された引数をそのままsudo.jsに丸投げしてるだけの簡単なつくりです。

ソース - su.cmd

suのバッチはこんな感じ。

sudo.cmdでは引数をそのまま丸投げしてたところを、明示的に「cmd.exe /k」しています。

あと、スクリプトを実行すると新しいプロンプトが開くので、なにも考えずに使ってるとコマンドプロンプトのウィンドウだらけになってウザいので最後にexitしてますが、これはお好みで削除してもよいでしょう。

あ、それからsudo.js側で小技を入れているので、suした場合は元のディレクトリを引き継ぎます。

使い道とか

suしてmklinkしてシンボリックリンクをバンバン作成するとか、hostsいじるのにsudo notepadするとか、まぁそんな感じでしょうか。

即吊ブックマークレット改善版2015年05月26日 20時48分50秒

iOSでうまくいかなかったので…

前のエントリに載せたブックマークレットはソースが長すぎてiCloudで同期できなくてiOSでの動作確認もままならなかったので、意地になって改善しました。なんとか使い物になるかなぁ、と。

改善版ブックマークレット

即吊ダイアログ[改]

デスクトップブラウザなら↑のリンクをブックマークツールバーにドラッグドロップしてください。リンクをクリックするとpromptでjavascript:なURLを表示するので、スマートフォンやらタブレットの場合はこれをコピーした上で適当なページをブックマーク、編集で貼り付けてください。

ソース

こんな感じです。ブックマークレットにするにあたってはこのソースをpackerで圧縮して<をエスケープしています。

即吊ブックマークレット2015年05月21日 01時35分49秒

またの名を「ソク吊嵐」

即吊☆キャプチャー|WEBキャプチャーをTwitterに投稿しちゃうアプリケーション ってなサイトがあってですな。サイトの画面をキャプチャしてさくっとTwitterに投げ込むわけですよ。いたく便利で。

投稿するキャプチャー画像にコメント、ハッシュタグを入れる。特定のツイートにリプライするなど出来ます。

勢いです。勢い。

オプションもいろいろあって、ブックマークレットも用意されてるんだけども、prompt()連発のウィザード形式で、少々戸惑っちゃうんですわ。すぐに慣れるんだけども。

そこでなんとなく勢いでダイアログベースのブックマークレットを作ってみたわけなんですわ。ええ。

即吊ダイアログ

※:2015.5.25 ダイアログにスタイル適用したり、実験中パラメータ「callback」に対応したりで更新しました。

※:2015.5.26 ブックマークレットのURIが長すぎるせいか、iCloudでの同期がうまくいきません&iOSだとうまく動かないかも。

iCloudで同期できるサイズまで小さくしてiOS 8で動作するバージョンを作成しました。

吊りたいページでブックマークレットを起動するとこんなダイアログが出ます。

Firefox 38とChrome 42(どちらもWindows)でしか試してないし、オプションも追加コメントとお仕事場モードくらいしか試してないんだけども、まぁ一応使えるのではないかと。サイトによってはレイアウト崩れたりいろいろ問題ありそうだけども。

中身はこんな感じ(雑です)。

(function(act){
  var w=window,
    d=w.document,
    u=w.location.href,
    ex=function(){
      var args=Array.prototype.slice.call(arguments),ds=(args.shift()||{}),sr=(args.shift()||{});
      for(var p in sr){
        ds[p]=sr[p]
      }
      return args.length?ex.apply(null,[ds].concat(args)):ds;
    },
    dc=function(n){
      return d.createElement(n);
    },
    esc=function(s) {
      return s
        .replace(/&/g,'&amp;')
        .replace(/</g,'&lt;')
        .replace(/>/g,'&gt;')
        .replace(/'/g,'&apos;')
        .replace(/"/g,'&quot;');
    },
    term=function(e){
      setTimeout(function(){
        e.parentNode.removeChild(e);
      },100)
    },
    st={
      d:{
        fontSize:'14px',
        lineHeight:1.4
      },
      fm:{
        textAlign:'left',
        backgroundColor:'#fff',
        color:'#000',
        position:'absolute',
        width:'600px',
        padding:'10px',
        top:0,
        right:0,
        zIndex:9999,
        border:'solid 1px #999'
      },
      ttl:{
        textAlign:'center',
        fontWeight:'bold',
        fontSize:'20px',
        margin:'-5px -5px 5px -5px',
        backgroundColor:'#f9c',
        color:'#c71585'
      },
      txt:{
        width:'360px',
        border:'solid 1px #999'
      },
      lbl:{
        width:'195px',
        marginRight:'5px',
        display:'inline-block',
        textAlign:'right'
      },
      btn:{
        width:'150px',
        margin:'5px 5px 0 5px',
        padding:'4px 10px',
        border:'solid 1px #666',
        backgroundColor:'#eee'
      }
    },
    trimFields=function(fm){
      for(var ls=fm.getElementsByTagName('input'),i=0,l=ls.length;i<l;i++){
        if((ls[i].type=='text'&&!ls[i].value.length)||(ls[i].type=='checkbox'&&!ls[i].checked)){
          ls[i].disabled=true;
        }
      }
      setTimeout(function(){fm.submit();term(fm)},0)
    };
  d.body.appendChild((function(){
    var fm=ex(dc('form'), {
        method:'get',
        action:act,
        target:'_blank',
        onsubmit:function(){trimFields(fm)}
      }),
      title=ex(dc('div'),{innerHTML:esc('ソク吊嵐ダイアログ')}),
      btn=null;
    ex(fm.style,st.d,st.fm);
      ex(title.style,st.d,st.ttl);
    fm.appendChild(title);
    var items=[
      {lbl:'吊るURL',ttl:'即吊したいURLを入れてください(必須です。)',ele:ex(dc('input'),{type:'text',name:'url',value:u,readonly:'readonly'})},
      {lbl:'ハッシュタグ',ttl:'ハッシュタグを付けます。全角半角空白、カンマで多重に付けることができます。',ele:ex(dc('input'),{type:'text',name:'hashtag'})},
      {lbl:'サイト全体キャプチャを試行',ttl:'allとリクエストすると出来る限りWEBサイト全体をキャプチャーしようと頑張ります。',ele:ex(dc('input'),{type:'checkbox',name:'images',value:'all'})},
      {lbl:'追加コメント',ttl:'コメントを付けることが出来ます。',ele:ex(dc('input'),{type:'text',name:'text'})},
      (function(){
        if(!/^https:\/\/twitter\.com/.test(u))return {};
        return {lbl:'このツイートにリプライ',ttl:'1とリクエストすると吊るサイトがツイートならば、そのツイートに.@でリプライを付けて投稿します。',ele:ex(dc('input'),{type:'checkbox',name:'reply',value:'1'})};
      })(),
      {lbl:'返信元ツイートURL',ttl:'吊るサイトを狙ったツイートに.@でリプライを付けて投稿します。(ツイートのURL入れてね。)',ele:ex(dc('input'),{type:'text',name:'status'})},
      {lbl:'職場モード',ttl:'1とリクエストするとターミナル風CSSモードで投稿します。お仕事場でも恥ずかしくありません。かも',ele:ex(dc('input'),{type:'checkbox',name:'terminal',value:'1'})},
      {lbl:'自分にナルト',ttl:'1とリクエストするとピリオド無しの@でこっそり魚拓したのを自分に向けてメンションします。',ele:ex(dc('input'),{type:'checkbox',name:'mention',value:'1'})},
      {lbl:'戻り先',ttl:'吊り終わったら飛びたいURIにを入れてください。ページ出力前にページ遷移しちゃうのでちょっと動作が早いですが><',ele:ex(dc('input'),{type:'text',name:'callback'})}
    ];
    for(var i=0,l=items.length,item=items[i],lbl;i<l;i++,item=items[i]){
      var ln=dc('div');ex(ln.style,{margin:'3px 0'});
      if('lbl' in item){
        lbl=ex(dc('span'),{innerHTML:esc(item.lbl)});
        ex(lbl.style,st.d,st.lbl);
        ln.appendChild(lbl);
      }
      if(('ttl' in item)&&lbl){
        ex(lbl,{'title':item.ttl});
      }
      if('ele' in item){
        if(item.ele.type=='text'){
          ex(item.ele.style,st.d,st.txt);
        }
        ln.appendChild(item.ele);
      }
      fm.appendChild(ln);
    }
    ln=dc('div');ex(ln.style,{marginTop:'10px',borderTop:'solid 1px #ccc'});
    ex(ln.style,{marginTop:'10px',textAlign:'center'});
    fm.appendChild(ln);
    btn=ex(dc('button'),{type:'submit',innerHTML:esc('吊る!')});ex(btn.style,st.d,st.btn);
    ln.appendChild(btn);
    btn=ex(dc('button'),{type:'button',innerHTML:esc('やめる'),onclick:function(){term(fm)}});ex(btn.style,st.d,st.btn);
    ln.appendChild(btn);
    return fm;
  })())
})('http://drinker.slfeed.net/archive/')


ローカルストレージを確認したり消したりするブックマークレット2012年03月19日 12時31分51秒

TLでローカルストレージ絡みの話がちょろちょろ流れてたので、興味があったのと多少は需要がありそうな気がしたのでざっくり作ってみた。

用途は、スマートフォンやタブレットなどのモバイルOSで、例えばiOSなんかはorigin指定で削除することもできないし、消す場合はCookieやらなにやら一絡げで削除しちゃうので、「このoriginのlocalStorageだけ消したい!」というような用途で使ってください。

なお、削除すると元ページの機能が意図通りに動かなくなる可能性があるので慎重に。

ブックマークレット

ローカルストレージの内容確認

こんな感じ。

ローカルストレージの内容確認

ローカルストレージを削除

こんな感じ。

ローカルストレージを削除

インストール方法

どちらのブックマークレットも、リンクをクリックくするとソースがpromptで表示されるので、スマートフォンやらタブレットデバイスの場合はこれをコピーして使ってください。デスクトップブラウザの場合はそのままドラッグドロップでよいかと。

注意点とか

Web Storageは同一生成元ポリシーなので、確認/削除のスコープは当然これに縛られます。

また、処理対象にしているのはwindow.localStorageのみなので、ラッパーかませてCookie使ってるページとか、globalStorage使ってるページとかでは効力ないかと。

無限箱の箱が全部ピンクになるまでがんばるブックマークレット2012年02月24日 11時21分36秒

なんとなく無限なめこ無限箱ですべてが黄金なめこピンク箱になるまで自動的に抜きまくるブックマークレットを作ってみた。

※:いろいろ事情があってキノコから箱になったようです。あと、なんか様子がおかしくなって逃げ回るようになってたり。

無限用ブックマークレット

いまのとこWinのFirefox10とChrome17でしか動作確認取れてません。IEはちょっと無理っぽいので無視の方向で。

追記

ちぇ、iPadだとすんなり動かないか…

追記2

Androidもダメだな。なんかが根本的にダメなのか。

一応ソースも載せておこう。

javascript:(function(){
    var
        _f=arguments.callee,
        ns=$.makeArray($('#main>img')),
        i=0,g=0,
        fl=Math.floor,
        fnd=function(i){
            return arObj[fl(i/COL)]?arObj[fl(i/COL)][i%ROW]:null
        };
    setTimeout(function(){
        var t=(fnd(i)||{isAnimation:false}).isAnimation?null:ns[i++],TM=50;
        if(t){
            if(!/((golden)|(box2))/.test(t.src)){
                var p=$(t).position();
                p.left++;
                p.top++;
                onMouseDown({
                    preventDefault:$.noop,
                    pageX:p.left,pageY:p.top,
                    touches:[{pageX:p.left+1,pageY:p.top+1}]
                })
            }else{
                TM=0;
                if(++g>=ns.length){
                    alert('completed!!');return
                }
            }
        }
        setTimeout(t?arguments.callee:_f,TM);
    },0);
})();

追記3

iOS/Android対応で修正。たぶん動くはず…

追記4:ブックマークレットの登録方法

デスクトップブラウザなら「無限箱用ブックマークレット」のリンクをブックマークバーにそのままドラッグドロップするだけでOKです。

スマートフォンやタブレットデバイスの場合は以下の要領で登録・編集してください。

  1. このページでもどこでも適当に新規ブックマークを追加する
  2. 「無限箱用ブックマークレット」をタップしてプロンプト表示されるブックマークレットURLをクリップボードにコピー
  3. 最初に新規登録したブックマークのURLをコピーしたもので置き換え、適当にタイトルを入れる

現在動作が確認できているのはFirefox10(Win) / Chrome 17(Win) / Safari 5.1(Mac, iOS5.0.1) / Android 2.3.3 くらいです。

追記5

タイミングによっては黄金なめこピンク箱も抜いてしまうバグの修正

ってか、なにやってんだ、俺…

追記6(2012-02-28 02:24)

箱対応