end0tknr's kipple - web写経開発

太宰府天満宮の狛犬って、妙にカワイイ

appium + pyautogui + win32gui for python で、excelの保護ビューを解除 - RPAもどき

f:id:end0tknr:20190502034149p:plain

appium + windows app driver で、ダウンロードされたexcelファイルに対する 自動操作を行おうとしましたが、「保護ビュー」がある為、操作できない。

WinAppDriver UI Recorderで「編集を有効にする」ボタンのXPATHを調べ、 これをクリックしようとしても、できない。

appium + windows app driver では不可能と判断し、pyautogui + win32gui の力も借りることにしました。

で、以下が、そのpython script。

# -*- coding: utf-8 -*-
from appium import webdriver
from selenium.webdriver.common.keys import Keys
import pyautogui
import win32gui
import time

def main():
    ## appiumで、アプリ起動
    desired_caps = {}
    desired_caps["app"] = r"c:\Users\end0t\Downloads\ないしょ_DEV_MACRO_ORG.xlsm"

    driver = webdriver.Remote(
        command_executor='http://127.0.0.1:4723',
        desired_capabilities= desired_caps)

    ## win32guiで、対象のアプリを探索
    time.sleep(2)
    app_handle = win32gui.FindWindow(None, "ないしょ_DEV_MACRO_ORG.xlsm  [保護ビュー] - Excel")
    print("APP HANDLE:",app_handle)
    
    ## pyautoguiで、ショートカット(ALT→F→I→E)を送信し、保護ビューを解除
    if app_handle > 0 :
        pyautogui.press('alt')
        time.sleep(1)
        pyautogui.press('F')
        time.sleep(1)
        pyautogui.press('I')
        time.sleep(1)
        pyautogui.press('E')
        
    
    ## 終了
    driver.quit()


if __name__ == '__main__':
    main()

jQueryで右クリックによるコンテキスト メニュー表示 - jQuery-chromeContext ( javascript )

イベントは jQuery.on() で設定することで、後から追加されたelementにも対応できますし、 本体である jquery.chromeContext.js は、数10行の小規模で、後から改造するにしても楽ですので。

jQuery-chromeContext で十分かと思います。

http://travishorn.github.io/jquery-chromeContext/

以下、jquery-chromeContext のデモにあるsrc

html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    
    <title>chromeContext Menu</title>
    
    <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/normalize/2.1.0/normalize.css">
    <link rel="stylesheet" href="css/demo.css">
    <link rel="stylesheet" href="../lib/css/chromeContext.css">
  </head>
  <body>
    <div id="one" class="box">one</div>
    <div id="two" class="box">two</div>
    
    <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script src="../lib/js/jquery.chromeContext.js"></script>
    <script src="js/demo.js"></script>
  </body>
</html>

jquery.chromeContext.js (本体)

(function ($) {
  var cctxId = 0;
  
  $.fn.chromeContext = function (options) {
    var trigger = this;
    var menu = $('<div class="cctx"/>');
    var l = options.items.length;
    var i;
    
    for (i = 0; i < l; i++) {
      var item = options.items[i];
      var el = $('<div/>');
      
      if (item.separator) {
        el.addClass('cctx-separator');
      } else {
        el.addClass('cctx-item');
        el.text(item.title);
        el.on('click', item.onclick);
      }
      
      menu.append(el);
    }
    
    menu.attr('data-cctxId', cctxId);
    
    $('body').append(menu);
    
    this
      .attr('data-cctxId', cctxId)
      .on('contextmenu', function (e) {
        var menu = $('.cctx[data-cctxId="'+ $(this).attr('data-cctxId') +'"]');
        
        e.preventDefault();
                
        menu
          .css('top', e.clientY)
          .css('left', e.clientX)
          .show();
      })
      .parents()
        .on('mouseup', function () {
          $('.cctx:visible').hide();
        });
    
    cctxId++;
    return this;
  };
}( jQuery ));

demo.js

$(function(){
  $('#one').chromeContext({
    items: [
      { title: 'Hello',
        onclick: function () { console.log('hello.'); } },
      { separator: true },
      { title: 'World',
        onclick: function () { console.log('world.'); } }
    ]
  });
  
  $('#two').chromeContext({
    items: [
      { title: 'Item 1',
        onclick: function () { console.log('one.'); } },
      { title: 'Item 2',
        onclick: function () { console.log('two.'); } },
      { title: 'Item 3',
        onclick: function () { console.log('three.'); } },
      { title: 'Item 4',
        onclick: function () { console.log('four.'); } },
      { title: 'Item 5',
        onclick: function () { console.log('five.'); } },
      { title: 'Item 6',
        onclick: function () { console.log('six.'); }
      }
    ]
  });
});

css

body {
  padding: 50px;
}

.box {
  width: 200px;
  height: 200px;
  float: left;
  margin: 20px;
  padding: 5px 10px;
  font-size: 30px;
  font-weight: bold;
  color: #FFF;
  text-shadow: 1px 1px 2px #555;
}

#one { background-color: #FF8080; }
#two { background-color: #84FF84; }

pgRouting を使用した 幾何学図形に対する経路探索

install postgres 11.2 & postgis 2.5 & mapserver 7.2 (2019年版) - end0tknr's kipple - 新web写経開発

先日のentryの続きとして、

  1. pgRouting を install
  2. 任意の図形をメッシュ化
  3. メッシュを経路とみなして、経路探索

を行います。

FEMの自動メッシュにあるドロネー三角形分割(デローニ、Delaunay diagram)も考えましたが、 手間なので、PostGIS + pgRouting + MapServerに頼りました。

今後の発展に向けたTODO

TODO 1 - 今回は二次元問題を対象にしていますが、三次元問題に拡張したい

ダイクストラ法とA*(A-star)探索を3Dメッシュ上で行いThree.jsで可視化をしてみた - Qiita

例えば、↑こんな感じ。

また、今回使用しているPostGISのAddGeometryColumn()は、 最後に引数に次元数(今回の場合、2)を取るので、3次元への拡張は、 それ程、難しくない気がします。(勝手な期待)

SELECT AddGeometryColumn('','geom_multi_line','geom','0','MULTILINESTRING',2);

TODO 2 - コスト設定

今回は、幾何学形状を保存するDBテーブルで一律、コスト=1としていますが、 コストを変更することにより、探索結果の変化を見てみたい。

pgRouting 本体 の install

次のurlに記載のとおりです。

http://docs.pgrouting.org/2.6/en/pgRouting-installation.html

$ wget https://github.com/pgRouting/pgrouting/releases/download/v2.6.2/pgrouting-2.6.2.tar.gz
$ tar -xvf pgrouting-2.6.2.tar.gz
$ cd pgrouting-2.6.2
$ mkdir build
$ cd build
$ /usr/local/bin/cmake \
    -DPOSTGRESQL_PG_CONFIG=/usr/local/pgsql/bin/pg_config \
    ..
$ make
$ sudo make install

幾何学計算用のデータベース作成(createdb)と、pgRoutingの拡張

$ /usr/local/pgsql/bin/createdb -U postgres -E utf8 geom_test
$ /usr/local/pgsql/bin/psql -U postgres geom_test
psql> CREATE EXTENSION pgrouting CASCADE;

通常は、↑これでOK。

ERROR:  could not load library "/usr/local/pgsql/lib/libpgrouting-2.6.so": \
  libCGAL.so.13: cannot open shared object file: No such file or directory

★私の環境では、「CREATE EXTENSION pgrouting CASCADE」の際、 上記のエラーが出力された為、/etc/ld.so.conf に 「/usr/local/lib64」を追加しました。

$ sudo vi /etc/ld.so.conf
include ld.so.conf.d/*.conf
/usr/local/lib
/usr/local/lib64  #### <---ADD

幾何学図形用テーブル作成(CREATE TABLE)

ポイントの1つは、AddGeometryColumn() による幾何学図形格納用カラム追加。 AddGeometryColumn() の仕様は、次のurlが分かりやすいです。

https://www.finds.jp/docs/pgisman/2.0.0/AddGeometryColumn.html

もう1つのポイントは、source, target, cost の3つのカラムで、 これらは、pgRoutingによる経路探索で参照されます。

SET CLIENT_ENCODING TO UTF8;
SET STANDARD_CONFORMING_STRINGS TO ON;

-- #### ポリゴン 格納用 ####
CREATE TABLE "geom_polygon" (
  gid serial,
  "memo" varchar(200)
);
ALTER TABLE "geom_polygon" ADD PRIMARY KEY (gid);
SELECT AddGeometryColumn('','geom_polygon','geom','0','POLYGON',2);

-- #### メッシュ 格納用 (★ MULTI LINE )####
CREATE TABLE "geom_multi_line" (
  gid serial,
  "memo" varchar(200)
);
ALTER TABLE "geom_multi_line" ADD PRIMARY KEY (gid);
SELECT AddGeometryColumn('','geom_multi_line','geom','0','MULTILINESTRING',2);


-- #### 経路候補 格納用 ####
CREATE TABLE "route_line" (
  gid serial,
  source integer,         -- 始点
  target integer,         -- 終点
  cost double precision,  -- コスト
  "memo" varchar(200)
);
ALTER TABLE "route_line" ADD PRIMARY KEY (gid);
SELECT AddGeometryColumn('','route_line','geom','0','LINESTRING',2);

-- #### 経路結果 格納用 ####
CREATE TABLE "route_line_ans" (
  gid serial,
  "memo" varchar(200)
);
ALTER TABLE "route_line_ans" ADD PRIMARY KEY (gid);
SELECT AddGeometryColumn('','route_line_ans','geom','0','LINESTRING',2);

幾何学図形データの登録 (INSERT INTO)

ポリゴン

psql> insert into geom_polygon (geom)
      values('POLYGON((10 10,10 40,70 40,70 10,60 10,60 30,50 30,50 10,10 10),
                      (20 20,40 20,40 30,20 30,20 20))'::GEOMETRY );

上記のSQLにより、以下のような切り欠きのあるポリゴンが生成されます

f:id:end0tknr:20190429210856p:plain

メッシュ (MULTILINESTRING)

psql> insert into geom_multi_line (geom)
      values('MULTILINESTRING(( 5 15, 75 15),(5  25, 75 25),( 5 35, 75 35),
                              (15  5, 15 45),(25  5, 25 45),(35  5, 35 45),
                              (45  5, 45 45),(55  5, 55 45),(65  5, 65 45))'::GEOMETRY);

上記のSQLにより、以下のようなメッシュが生成されます

f:id:end0tknr:20190429210909p:plain

経路候補データの算出と登録

前述のポリゴンとメッシュのAND領域を算出し、経路候補データとして登録します。

psql> select ST_AsText(
        ST_Intersection(
            'POLYGON((10 10,10 40,70 40,70 10,60 10,60 30,50 30,50 10,10 10),
                     (20 20,40 20,40 30,20 30,20 20))'::GEOMETRY,
            'MULTILINESTRING(( 5 15, 75 15),(5  25, 75 25),( 5 35, 75 35),
                             (15  5, 15 45),(25  5, 25 45),(35  5, 35 45),
                             (45  5, 45 45),(55  5, 55 45),(65  5, 65 45))'::GEOMETRY
        )
      );
-------------------------------------------------------------------------------------
MULTILINESTRING((10 15,15 15),(15 15,25 15),(25 15,35 15),(35 15,45 15),(45 15,50 15),
                (60 15,65 15),(65 15,70 15),(10 25,15 25),(15 25,20 25),(40 25,45 25),
        (45 25,50 25),(60 25,65 25),(65 25,70 25),(10 35,15 35),(15 35,25 35),
        (25 35,35 35),(35 35,45 35),(45 35,55 35),(55 35,65 35),(65 35,70 35),
                (15 10,15 15),(15 15,15 25),(15 25,15 35),(15 35,15 40),(25 10,25 15),
        (25 15,25 20),(25 30,25 35),(25 35,25 40),(35 10,35 15),(35 15,35 20),
        (35 30,35 35),(35 35,35 40),(45 10,45 15),(45 15,45 25),(45 25,45 35),
        (45 35,45 40),(55 30,55 35),(55 35,55 40),(65 10,65 15),(65 15,65 25),
        (65 25,65 35),(65 35,65 40))

上記で出力された (10 15,15 15),(15 15,25 15)... をLINE として route_line テーブルへ登録(INSERT)します。

psql> insert into route_line (geom)
  values
  ('LINESTRING(10 15,15 15)'::GEOMETRY),('LINESTRING(15 15,25 15)'::GEOMETRY),
  ('LINESTRING(25 15,35 15)'::GEOMETRY),('LINESTRING(35 15,45 15)'::GEOMETRY),
  ('LINESTRING(45 15,50 15)'::GEOMETRY),('LINESTRING(60 15,65 15)'::GEOMETRY),
  ('LINESTRING(65 15,70 15)'::GEOMETRY),('LINESTRING(10 25,15 25)'::GEOMETRY),
  ('LINESTRING(15 25,20 25)'::GEOMETRY),('LINESTRING(40 25,45 25)'::GEOMETRY),
  ('LINESTRING(45 25,50 25)'::GEOMETRY),('LINESTRING(60 25,65 25)'::GEOMETRY),
  ('LINESTRING(65 25,70 25)'::GEOMETRY),('LINESTRING(10 35,15 35)'::GEOMETRY),
  ('LINESTRING(15 35,25 35)'::GEOMETRY),('LINESTRING(25 35,35 35)'::GEOMETRY),
  ('LINESTRING(35 35,45 35)'::GEOMETRY),('LINESTRING(45 35,55 35)'::GEOMETRY),
  ('LINESTRING(55 35,65 35)'::GEOMETRY),('LINESTRING(65 35,70 35)'::GEOMETRY),
  ('LINESTRING(15 10,15 15)'::GEOMETRY),('LINESTRING(15 15,15 25)'::GEOMETRY),
  ('LINESTRING(15 25,15 35)'::GEOMETRY),('LINESTRING(15 35,15 40)'::GEOMETRY),
  ('LINESTRING(25 10,25 15)'::GEOMETRY),('LINESTRING(25 15,25 20)'::GEOMETRY),
  ('LINESTRING(25 30,25 35)'::GEOMETRY),('LINESTRING(25 35,25 40)'::GEOMETRY),
  ('LINESTRING(35 10,35 15)'::GEOMETRY),('LINESTRING(35 15,35 20)'::GEOMETRY),
  ('LINESTRING(35 30,35 35)'::GEOMETRY),('LINESTRING(35 35,35 40)'::GEOMETRY),
  ('LINESTRING(45 10,45 15)'::GEOMETRY),('LINESTRING(45 15,45 25)'::GEOMETRY),
  ('LINESTRING(45 25,45 35)'::GEOMETRY),('LINESTRING(45 35,45 40)'::GEOMETRY),
  ('LINESTRING(55 30,55 35)'::GEOMETRY),('LINESTRING(55 35,55 40)'::GEOMETRY),
  ('LINESTRING(65 10,65 15)'::GEOMETRY),('LINESTRING(65 15,65 25)'::GEOMETRY),
  ('LINESTRING(65 25,65 35)'::GEOMETRY),('LINESTRING(65 35,65 40)'::GEOMETRY);

※ MULTILINESTRING <-> LINESTRING の相互変換には、ST_LineMerge()やST_Dump()が使えるようですが postgisやpgRoutingを使いこなせていないので、今回の場合、エディタで変換しています。

psql> select ST_LineMerge(ST_Multi(ST_Union(the_geom))) as new_geom from lines 何か条件;
psql> select (ST_Dump(the_geom)).geom as new_geom from multilines;

route_lineテーブル内容の描画結果が以下で、メッシュがポリゴンにより、 切り取られていることが分かります。

f:id:end0tknr:20190429210937p:plain

★次のpgr_createTopology()は、pgRoutingによる経路探索で必要な情報を 自動生成してくれますので、必ず実行して下さい。(テーブルが追加されます)

psql> SELECT pgr_createTopology('route_line', 0, 'geom', 'gid');

以下は、pgr_createTopology()により作成された経路(LINE)の端点情報です f:id:end0tknr:20190429211203p:plain

pgr_dijkstra() による経路探索 (ダイクストラ法)

以下が、点:2→8の経路探索結果です。

  • ※ 「Deprecated function」と表示されましたが、今回は無視
  • ※ id1:端点のID、id2:LINEのID
psql> SELECT *
   FROM pgr_dijkstra(
     'SELECT gid as id, source, target, cost FROM route_line',
     2,
     8,
     false,
     false
   );
NOTICE:  Deprecated function
 seq | id1 | id2 | cost
-----+-----+-----+------
   0 |   2 |  22 |    1
   1 |  11 |  23 |    1
   2 |  20 |  15 |    1
   3 |  21 |  16 |    1
   4 |  22 |  17 |    1
   5 |  23 |  18 |    1
   6 |  24 |  19 |    1
   7 |  25 |  41 |    1
   8 |  17 |  40 |    1
   9 |   8 |  -1 |    0
(10 rows)

算出された経路を、画像に描画する為、route_line_ansテーブルへINSERTします。

psql> select gid, geom from route_line
      where gid in (22,23,15,16,17,18,19,41,40);
 gid |                                        geom                                        
-----+------------------------------------------------------------------------------------
  15 | 0102000000020000000000000000002E40000000000080414000000000000039400000000000804140
  16 | 0102000000020000000000000000003940000000000080414000000000008041400000000000804140
  17 | 0102000000020000000000000000804140000000000080414000000000008046400000000000804140
  18 | 010200000002000000000000000080464000000000008041400000000000804B400000000000804140
  19 | 0102000000020000000000000000804B40000000000080414000000000004050400000000000804140
  22 | 0102000000020000000000000000002E400000000000002E400000000000002E400000000000003940
  23 | 0102000000020000000000000000002E4000000000000039400000000000002E400000000000804140
  40 | 01020000000200000000000000004050400000000000002E4000000000004050400000000000003940
  41 | 0102000000020000000000000000405040000000000000394000000000004050400000000000804140

psql> insert into route_line_ans(gid,geom)
values
(15,'0102000000020000000000000000002E40000000000080414000000000000039400000000000804140'),
(16,'0102000000020000000000000000003940000000000080414000000000008041400000000000804140'),
(17,'0102000000020000000000000000804140000000000080414000000000008046400000000000804140'),
(18,'010200000002000000000000000080464000000000008041400000000000804B400000000000804140'),
(19,'0102000000020000000000000000804B40000000000080414000000000004050400000000000804140'),
(22,'0102000000020000000000000000002E400000000000002E400000000000002E400000000000003940'),
(23,'0102000000020000000000000000002E4000000000000039400000000000002E400000000000804140'),
(40,'01020000000200000000000000004050400000000000002E4000000000004050400000000000003940'),
(41,'0102000000020000000000000000405040000000000000394000000000004050400000000000804140');

経路の描画

以下は、描画出力に使用したmapserverのmapファイルです

MAP
    SIZE   700 500           
    EXTENT 0 0 100 50       # minx miny maxx maxy
    STATUS ON              #地図を表示するか
    UNITS meters           #地図の単位(DD は緯度経度)
    IMAGECOLOR 255 255 255 #背景色R G B
    IMAGETYPE PNG          #地図画像を保存する形式
    LAYER
         NAME "polygon"
         CONNECTIONTYPE POSTGIS
         CONNECTION "user=postgres password='' dbname=geom_test host=localhost"
         DATA "geom FROM geom_polygon" #select文
         TYPE POLYGON
         STATUS ON
         CLASS
             COLOR 230 230 230
         END
    END
    # LAYER
    #      NAME "mesh"
    #      CONNECTIONTYPE POSTGIS
    #      CONNECTION "user=postgres password='' dbname=geom_test host=localhost"
    #      DATA "geom FROM geom_multi_line" #select文
    #      TYPE LINE
    #      STATUS ON
    #      CLASS
    #          COLOR 94 124 180
    #      END
    # END
    LAYER
         NAME "line"
         CONNECTION "user=postgres password='' dbname=geom_test host=localhost"
         CONNECTIONTYPE POSTGIS
         DATA "geom FROM route_line" #select文
         TYPE LINE
         STATUS ON
         LABELITEM 'gid'
         CLASS
           COLOR 94 124 180
           LABEL
             TYPE TRUETYPE
             COLOR 94 124 180
             SIZE 10
             POSITION AUTO
             PARTIALS TRUE
           END
         END
    END

    SYMBOL
      NAME "circle"
      TYPE ellipse
      FILLED true
      POINTS
        8 8
      END # End of POINTS
    END # End of SYMBOL
  
    LAYER
         NAME "point_end"
         CONNECTION "user=postgres password='' dbname=geom_test host=localhost"
         CONNECTIONTYPE POSTGIS
         DATA "the_geom FROM route_line_vertices_pgr" #select文
         TYPE POINT
         STATUS ON
         LABELITEM 'id'
         CLASS
           STYLE     
             SYMBOL "circle"
             COLOR 0 185 0
           END
           LABEL
             TYPE TRUETYPE
             COLOR 0 185 0
             SIZE 10
             POSITION AUTO
             PARTIALS TRUE
           END
         END
    END

    LAYER
         NAME "line_route"
         CONNECTION "user=postgres password='' dbname=geom_test host=localhost"
         CONNECTIONTYPE POSTGIS
         DATA "geom FROM route_line_ans" #select文
         TYPE LINE
         STATUS ON
         LABELITEM 'gid'
         CLASS
           COLOR 200 0 0
           LABEL
             TYPE TRUETYPE
             COLOR 200 0 0
             SIZE 10
             POSITION AUTO
             PARTIALS TRUE
           END
         END
    END
END

↑こう書いて、実行すると、以下の様に出力されます。

$ /usr/local/bin/shp2img -all_debug -m gis_test_5.map -o gis_test_5_5.png

f:id:end0tknr:20190429211007p:plain

その他

参考url

pgRoutingをはじめて使ってみた - Qiita

pgRoutingでスタート地点とゴール地点が多対多の検索を1発で実行する - Qiita

ジオメトリタイプ一覧をながめる - Qiita

ポリゴンデータ作成は難しいので、ST_IsValid()を活用しましょう。

幾何学図形的なtrue / false を判定してくれます

SELECT ST_IsValid(
 'POLYGON((10 10,10 40,70 40,70 10,60 10,60 30,50 30,50 10,10 10),
          (20 20,40 20,40 30,20 30,20 20))'::GEOMETRY
);

 st_isvalid 
------------
 t

install postgres 11.2 & postgis 2.5 & mapserver 7.2 (2019年版)

install postgres 9.6 & postgis 2.3 & mapserver & mapserver 7.0 - end0tknr's kipple - 新web写経開発

国土交通省にあるGISデータをPostGISへインポート(2017年版) - end0tknr's kipple - 新web写経開発

上記2エントリの2019年版。

面倒なので、前回との差異のみを以下に記載します。

PostGIS 2.5 は、PostgreSQL 11.2 にもinstall OK

https://postgis.net/docs/manual-2.5/postgis_installation.html の「Required」に「PostgreSQL 9.4 or higher.」と記載されています。

「ver.11.2って上げ過ぎかな?」とも思いましたが、 結果的に問題なく、PostGIS 2.5をinstallできました。

postgresのcreatelangコマンドが削除されていました

前回のエントリににて

$ /usr/local/pgsql/bin/createlang -U postgres plpgsql gis_test

を実行していますが、postgres 11.2ではcreatelangがありませんでした。

$ /usr/local/pgsql/bin/psql -U postgres gis_test
psql> CREATE LANGUAGE plpgsql;
ERROR:  language "plpgsql" already exists

の手順で操作すればよいようです。 ただし、この「CREATE LANGUAGE plpgsql」はそもそもPostGISのinstallでは 不要な操作だったようです。

libgeos_c.so.1: cannot open shared object file: No such file or directory

$ /usr/local/pgsql/bin/psql -U postgres -d gis_test \
   -f /usr/local/pgsql/share/contrib/postgis-2.5/postgis.sql
BEGIN
SET
DO
CREATE FUNCTION
psql:/usr/local/pgsql/share/contrib/postgis-2.5/postgis.sql:94: ERROR:  could not load library "/usr/local/pgsql/lib/postgis-2.5.so": libgeos_c.so.1: cannot open shared object file: No such file or directory
   :

のようなエラーが発生。

$ sudo vi /etc/ld.so.conf
include ld.so.conf.d/*.conf
/usr/local/lib

$ sudo ldconfig

のように「/usr/local/lib」を追加し、一旦?は回避しました。

mapserverno cmakeコマンド

以下のように実行しました。 この後の 国土交通省にあるGISデータをPostGISへインポートやPNGファイル作成も問題なく動作しています。

$ cmake -DCMAKE_PREFIX_PATH=/usr/local/pgsql \
>       -DWITH_PROTOBUFC=0 \
>       -DWITH_GIF=0 \
>       ..
-- * Summary of configured options for this build
--  * Mandatory components
--   * png: /usr/local/lib/libpng.so
--   * jpeg: /usr/local/lib/libjpeg.so
--   * freetype: /usr/local/lib/libfreetype.so
--  * Optional components
--   * GDAL: /usr/local/lib/libgdal.so
--   * OGR: /usr/local/lib/libgdal.so
--   * GIF: disabled
--   * MYSQL: disabled
--   * FRIBIDI: /usr/local/lib/libfribidi.so
--   * HARFBUZZ: /usr/lib64/libharfbuzz.so
--   * GIF: disabled
--   * CAIRO: /usr/lib64/libcairo.so
--   * SVGCAIRO: disabled
--   * RSVG: disabled
--   * CURL: disabled
--   * PROJ: /usr/local/lib/libproj.so
--   * PIXMAN: disabled
--   * LIBXML2: /usr/lib64/libxml2.so
--   * POSTGIS: /usr/local/pgsql/lib/libpq.so
--   * GEOS: /usr/local/lib/libgeos_c.so
--   * FastCGI: /usr/local/lib/libfcgi.so
--   * PROTOBUFC: disabled
--   * Oracle Spatial: disabled
--   * Exempi XMP: disabled
--  * Optional features
--   * WMS SERVER: ENABLED
--   * WFS SERVER: ENABLED
--   * WCS SERVER: ENABLED
--   * SOS SERVER: disabled
--   * WMS CLIENT: disabled
--   * WFS CLIENT: disabled
--   * ICONV: ENABLED
--   * Thread-safety support: disabled
--   * KML output: disabled
--   * Z+M point coordinate support: disabled
--   * XML Mapfile support: disabled
--  * Mapscripts
--   * Python: disabled
--   * PHP: disabled
--   * PERL: disabled
--   * RUBY: disabled
--   * JAVA: disabled
--   * C#: disabled
--   * V8 Javascript: disabled
--   * Apache Module (Experimental): disabled
-- 
-- Will install files to /usr/local
-- Will install libraries to /usr/local/lib
-- Configuring done
-- Generating done
-- Build files have been written to: /home/end0tknr/tmp/mapserver-7.2.2/build

centos 7 ( systemd )で postgresql-11 を自動起動

$ tar -xvf postgresql-11.2.tar.gz
$ cd postgresql-11.2
$ less INSTALL
        --with-systemd
                Build with support for systemd service notifications. This
                improves integration if the server binary is started under
                systemd but has no impact otherwise. libsystemd and the
                associated header files need to be installed to be able to
                use this option.

と記載されいたので、「--with-systemd」 付きでconfigureしたら

$ ./configure --with-systemd
  :
checking systemd/sd-daemon.h usability... no
checking systemd/sd-daemon.h presence... no
checking for systemd/sd-daemon.h... no
configure: error: header file <systemd/sd-daemon.h> is required for systemd support

と、エラー

$ sudo yum install systemd-devel 

のように systemd-devel が必要らしい。

後は、 https://www.postgresql.org/docs/11/server-start.html に記載の通り postgresql.service を作成し、登録すればOK

$ sudo vi /etc/systemd/system/postgresql.service

[Unit]
Description=PostgreSQL database server
Documentation=man:postgres(1)

[Service]
Type=notify
User=postgres
ExecStart=/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
KillSignal=SIGINT
TimeoutSec=0

[Install]
WantedBy=multi-user.target

その他、make 手順はINSTALLファイルにコマンドラインレベルで記載されています

python v2.7 + selenium + firefox (geckodriver.exe) でfileの自動upload & download

多分、↓こう

#!/usr/local/bin/python
# -*- coding: utf-8 -*-
import getopt
import os
import sys
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import traceback
from time import sleep

CONF = {'mile_id':'ないしょ','mile_pw':'ないしょ'}

def main():
    # browser起動
    browser = init_browser()
    # login処理
    if login_group_ware(browser) == False:
        return False
    # file upload
    file_name = "browser_screen_shot.png"
    if upload_file(browser,file_name) == False:
        return False
    # file download
    download_file(browser,file_name)
    # 終了処理
    browser.quit()

    
def download_file(browser,file_name):

    print file_name
    
    browser.get("https://bunsho.mile.sexy.com/lite/folder/204939")

    tr_lists = browser.find_elements_by_class_name("listItemName")
    for tr_list in tr_lists:
        if tr_list.text == file_name:
            a_href = tr_list.find_element_by_tag_name("a")
            a_href.click()
            sleep(5)

            download_link = browser.find_element_by_id("BunshoVS_dlLink")
            download_link.click()
            browser.implicitly_wait(10) # seconds
            return True
    return False

        
def upload_file(browser, file_name):

    browser.get("https://bunsho.mile.sexy.com/lite/folder/204939")


    browser.get("https://bunsho.mile.sexy.com/folder/204939/file/create")
    browser.execute_script('javascript:switch_to_normal_mode()')

    elm_file = browser.find_element_by_id("fp0file")
    elm_file.send_keys("c:\\home\\end0tknr\\tmp\\SELENIUM\\" + file_name)
    
    browser.execute_script('javascript:Creator.create_commit(file_select_mode)')
    
    # seleniumにおけるwaitは以下を参照
    # refer to https://kurozumi.github.io/selenium-python/waits.html
    try:
        WebDriverWait(browser, 10).until(
            EC.title_contains(u"ほげほげ")
        )
    except Exception as e:
#        print(dir(e))
        print e.args
        return False

    return True

    
def init_browser():
    profile = webdriver.FirefoxProfile()

    # 0:desktop, 1:sys規定のfolder, 2:user def folder
    profile.set_preference("browser.download.folderList",2)
    profile.set_preference("browser.download.dir", os.getcwd())
    profile.set_preference("browser.download.manager.showWhenStarting",False)

    # chrome driverでは、download.directory_upgrade=Trueで上書き保存できましたが
    # firefox では、上書き方法不明
    # profile.set_preference("browser.download.directory_upgrade",True)

    # image/png の場合、強制的にdownload (=画面表示しない)
    profile.set_preference("browser.helperApps.neverAsk.saveToDisk","image/png")
    browser = webdriver.Firefox(firefox_profile=profile)

    return browser

    
def login_group_ware(browser):

    browser.get("https://login.mile.sexy.com/login.pl")
    login_id_form = browser.find_element_by_name('credential_0')
    login_id_form.send_keys(CONF['mile_id'])
    login_pw_form = browser.find_element_by_name('credential_1')
    login_pw_form.send_keys(CONF['mile_pw'])

    login_btn = browser.find_element_by_name('Submit')
    login_btn.click()

    if( browser.current_url == "https://top.mile.sexy.com/"):
        return True
    return False


if __name__ == '__main__':
    main()

linux netstat or lsof でポートを使用するプロセス(プログラム)を確認

sonarqube-7.7 を install後、起動を試みるも、できなかったので、調査。

$ ./sonar.sh console
Running SonarQube...
wrapper  | --> Wrapper Started as Console
wrapper  | Launching a JVM...
jvm 1    | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
jvm 1    |   Copyright 1999-2006 Tanuki Software, Inc.  All Rights Reserved.
jvm 1    | 
jvm 1    | 2019.04.02 20:24:47 INFO  app[][o.s.a.AppFileSystem] Cleaning or creating temp directory /home/end0tknr/local/sonarqube-7.7/temp
jvm 1    | 2019.04.02 20:24:47 INFO  app[][o.s.a.es.EsSettings] Elasticsearch listening on /127.0.0.1:9001
jvm 1    | 2019.04.02 20:24:48 INFO  app[][o.s.a.p.ProcessLauncherImpl] Launch process[[key='es', ipcIndex=1, logFilenamePrefix=es]] from [/home/end0tknr/local/sonarqube-7.7/elasticsearch]: /home/end0tknr/local/sonarqube-7.7/elasticsearch/bin/elasticsearch
jvm 1    | 2019.04.02 20:24:48 INFO  app[][o.s.a.SchedulerImpl] Waiting for Elasticsearch to be up and running
jvm 1    | 2019.04.02 20:24:49 INFO  app[][o.e.p.PluginsService] no modules loaded
jvm 1    | 2019.04.02 20:24:49 INFO  app[][o.e.p.PluginsService] loaded plugin [org.elasticsearch.transport.Netty4Plugin]
jvm 1    | OpenJDK 64-Bit Server VM warning: If the number of processors is expected to increase from one, then you should configure the number of parallel GC threads appropriately using -XX:ParallelGCThreads=N
jvm 1    | 2019.04.02 20:25:38 WARN  app[][o.s.a.p.AbstractProcessMonitor] Process exited with exit value [es]: 1
jvm 1    | 2019.04.02 20:25:38 INFO  app[][o.s.a.SchedulerImpl] Process [es] is stopped
jvm 1    | 2019.04.02 20:25:38 INFO  app[][o.s.a.SchedulerImpl] SonarQube is stopped
wrapper  | <-- Wrapper Stopped

で、以下の通り

$ sudo netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:5000            0.0.0.0:*               LISTEN      3570/perl           
tcp        0      0 127.0.0.1:9001          0.0.0.0:*               LISTEN      3037/python         
tcp        0      0 0.0.0.0:139             0.0.0.0:*               LISTEN      3117/smbd           
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      3041/sshd           
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      3568/master         
tcp        0      0 0.0.0.0:445             0.0.0.0:*               LISTEN      3117/smbd           
tcp6       0      0 :::3306                 :::*                    LISTEN      3328/mysqld         
tcp6       0      0 :::139                  :::*                    LISTEN      3117/smbd           
tcp6       0      0 :::80                   :::*                    LISTEN      3035/httpd          
tcp6       0      0 :::22                   :::*                    LISTEN      3041/sshd           
tcp6       0      0 ::1:25                  :::*                    LISTEN      3568/master         
tcp6       0      0 :::445                  :::*                    LISTEN      3117/smbd           
$

更に lsof コマンドで詳細確認

$ sudo lsof -i :9001
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
superviso 3037 root    4u  IPv4  24613      0t0  TCP localhost:etlservicemgr (LISTEN)
$

最終的に、supervisord が9001ポートを既に使用していることが分かります

lizard (python製) で、C# (csharp) の 循環的複雑度 (cyclomatic_complexity)計測

https://github.com/terryyin/lizard

c# の code metricsは、visual studio で計測できますが、 全srcの循環的複雑度をコマンドラインから一覧で生成したかった為、lizard を利用。

install & usage

$ sudo /usr/local/bin/pip install lizard

$ /usr/local/bin/lizard --version
1.16.3
$ /usr/local/bin/lizard --help
usage: lizard [options] [PATH or FILE] [PATH] ...

lizard is an extensible Cyclomatic Complexity Analyzer for many programming
languages including C/C++ (doesn't require all the header files). For more
information visit http://www.lizard.ws

positional arguments:
  paths                 list of the filename/paths.

optional arguments:
  -h, --help            show this help message and exit
  --version             show program's version number and exit
  -l LANGUAGES, --languages LANGUAGES
                        List the programming languages you want to analyze. if
                        left empty, it'll search for all languages it knows.
                        `lizard -l cpp -l java`searches for C++ and Java code.
                        The available languages are: cpp, java, csharp,
                        javascript, python, objectivec, ttcn, ruby, php,
                        swift, scala, GDScript, go, lua
  -V, --verbose         Output in verbose mode (long function name)
  -C CCN, --CCN CCN     Threshold for cyclomatic complexity number warning.
                        The default value is 15. Functions with CCN bigger
                        than it will generate warning
  -f INPUT_FILE, --input_file INPUT_FILE
                        get a list of filenames from the given file
  -L LENGTH, --length LENGTH
                        Threshold for maximum function length warning. The
                        default value is 1000. Functions length bigger than it
                        will generate warning
  -a ARGUMENTS, --arguments ARGUMENTS
                        Limit for number of parameters
  -w, --warnings_only   Show warnings only, using clang/gcc's warning format
                        for printing warnings.
                        http://clang.llvm.org/docs/UsersManual.html#cmdoption-
                        fdiagnostics-format
  --warning-msvs        Show warnings only, using Visual Studio's warning
                        format for printing warnings.
                        https://msdn.microsoft.com/en-us/library/yxkt8b26.aspx
  -i NUMBER, --ignore_warnings NUMBER
                        If the number of warnings is equal or less than the
                        number, the tool will exit normally; otherwise, it
                        will generate error. If the number is negative, the
                        tool exits normally regardless of the number of
                        warnings. Useful in makefile for legacy code.
  -x EXCLUDE, --exclude EXCLUDE
                        Exclude files that match the pattern. * matches
                        everything, ? matches any single character,
                        "./folder/*" exclude everything in the folder
                        recursively. Multiple patterns can be specified. Don't
                        forget to add "" around the pattern.
  -t WORKING_THREADS, --working_threads WORKING_THREADS
                        number of working threads. The default value is 1.
                        Using a bigger number can fully utilize the CPU and
                        often faster.
  -X, --xml             Generate XML in cppncss style instead of the tabular
                        output. Useful to generate report in Jenkins server
  --csv                 Generate CSV output as a transform of the default
                        output
  -H, --html            Output HTML report
  -m, --modified        Calculate modified cyclomatic complexity number ,
                        which count a switch/case with multiple cases as one
                        CCN.
  -E EXTENSIONS, --extension EXTENSIONS
                        User the extensions. The available extensions are:
                        -Ecpre: it will ignore code in the #else branch.
                        -Ewordcount: count word frequencies and generate tag
                        cloud. -Eoutside: include the global code as one
                        function. -EIgnoreAssert: to ignore all code in
                        assert. -ENS: count nested control structures.
  -s SORTING, --sort SORTING
                        Sort the warning with field. The field can be nloc,
                        cyclomatic_complexity, token_count, p#arameter_count,
                        etc. Or an customized field.
  -T THRESHOLDS, --Threshold THRESHOLDS
                        Set the limit for a field. The field can be nloc,
                        cyclomatic_complexity, token_count, parameter_count,
                        etc. Or an customized file. Lizard will report warning
                        if a function exceed the limit
  -W WHITELIST, --whitelist WHITELIST
                        The path and file name to the whitelist file. It's
                        './whitelizard.txt' by default. Find more information
                        in README.
$

sample

$ /usr/local/bin/lizard --exclude "./GRA_batch_report/Backup/*" \
                                  --sort cyclomatic_complexity \
                  --languages csharp . > foo.txt
$ cat foo.txt
================================================
  NLOC    CCN   token  PARAM  length  location
------------------------------------------------
       4      1      9      0       4 CM.rpt::CM_A?_0?_R?2::CM_A?_0?_R02@34-37@./GRA_batch_report/ba_??_a??_0??_r02/rpt/CM_A??_0??_R0??.cs
      11      1     91      2      13 CM.rpt::CM_A?_0?_R?2::CM_A?_0?_R02_Re???Start@63-75@./GRA_batch_report/ba_cm_??_03_r02/rpt/CM_??_03_R02.cs
    <略>
      37      3    227      2      44 CM::BL_CM_M?_1?_???4::Get??ti??Grp@430-473@./GRA_web/bl_??_ms_11/??_CM_??_11_S04.cs
1074 file analyzed.

==============================================================
NLOC    Avg.NLOC  AvgCCN  Avg.token  function_cnt    file
--------------------------------------------------------------
   1475     228.2     1.7     2709.0         6     ./GRA_batch_report/ba_??_??_03_r02/rpt/??_AJ_??_R02.cs
     14       0.0     0.0        0.0         0     ./GRA_batch_report/ba_??_??_03_r02/Asse??yInfo.cs
    <略>
      0       0.0     0.0        0.0         0     ./GRA_web/bl_??_??_11/BL_??_??_11_S05.cs

=========================================================================================
!!!! Warnings (cyclomatic_complexity > 15 or length > 1000 or parameter_count > 100) !!!!

================================================
  NLOC    CCN   token  PARAM  length  location  
------------------------------------------------
    1369    313   8701      2    1807 FI::FI_??_03_??2::Da????id1_Item??ta??und@2503-4309@./GRA_web/allegroweb/FI_GL_03_S02.aspx.cs
     981    222   6540      2    1252 FI::FI_??_03_??9::Da????id1_Item??ta??und@950-2201@./GRA_web/allegroweb/FI_GL_03_S09.aspx.cs
    <略>
    1313      1  16162      0    1521 FI.rpt::??_??_05_R12::Initi??zeCo??nent@307-1827@./GRA_web/allegroweb/rpt/XF_GL_05_R12.cs
==========================================================================================
Total nloc   Avg.NLOC  AvgCCN  Avg.token   Fun Cnt  Warning cnt   Fun Rt   nloc Rt
------------------------------------------------------------------------------------------
    871324      49.8     4.5      446.4    15996          885      0.06    0.56

linux の cat やgrepは、PowerShellでは、Get-Content や Select-String

cat ≒ Get-Content

以下の通り、defaultでは、sjis以外文字化けするようです

PS C:\home\end0tknr\tmp\PS1> Get-Content .\foo_sjis.txt
これは、SJISのファイルです
PS C:\home\end0tknr\tmp\PS1> Get-Content -Encoding UTF8 .\foo_utf8.txt
これは、UTF-8のファイルです

grep ≒ Select-String

以下の通り、defaultでは、大文字小文字を区別しないようです

PS C:\home\end0tknr\tmp\PS1> Get-Content -Encoding UTF8 .\foo_utf8.txt | Select-String -Pattern "UTF" -CaseSensitive

これは、UTF-8のファイルです

(再) サーバにinstallされているOSやMWの一覧を自動収集したい (windows版)

サーバにinstallされているOSやMWの一覧を自動収集したい (windows版) - end0tknr's kipple - 新web写経開発

先日、記載したエントリではワンライナーで、読みづらいので power shell script らしく?修正しました。(以下)

function do_main {

    $i = 0

    #### win os 情報の収集
    $os_info = collect_win_os_ver
    $disp_cols = @([string] $i++,
           $os_info.SystemDirectory,
           $os_info.Version,
           $os_info.RegisteredUser )

    # タブ区切りで出力
    $disp_str = [string]::Join("`t", $disp_cols)
    # Write-Host と Write-Output の違いは要注意
    Write-Output $disp_str

    
    #### strawberry perl のver
    $disp_str = collect_perl_ver
    $disp_cols = @([string] $i++,
           "perl"
           $disp_str)
    $disp_str = [string]::Join("`t", $disp_cols)
    Write-Output $disp_str

    #### java spring のver
    $disp_str = collect_java_spring_ver
    $disp_cols = @([string] $i++,
           "java spring"
           $disp_str)
    $disp_str = [string]::Join("`t", $disp_cols)
    Write-Output $disp_str

    #### installerでinstallされたアプリ情報の収集
    $pkg_infos = collect_normal_package
    ## [string] $i は、数値の文字列化
    $i = 0
    foreach ($pkg_info in $pkg_infos) {

    if($pkg_info.DisplayName.Length -eq 0 -and
       $pkg_info.DisplayVersion.Length -eq 0 -and
       $pkg_info.Publisher.Length -eq 0 ){
           continue
       }

    $disp_cols = @([string] $i++,
               $pkg_info.DisplayName,
               $pkg_info.DisplayVersion,
               $pkg_info.Publisher)
    $disp_str = [string]::Join("`t", $disp_cols)
    Write-Output $disp_str
    }


}


function collect_java_spring_ver {

    $gradle_file =
    "c:\home\end0tknr\eclipse-workspace-oxygen\SpringBootMyBatis\build.gradle"
    $item_prop =
    Get-Content -Encoding UTF8 $gradle_file | Select-String "springBootVersion ="

    return $item_prop.toString().trim()
}


function collect_perl_ver {
    $item_prop = perl -v | Select-String -Pattern "version"
    return $item_prop.toString().trim()
}

function collect_win_os_ver {
    $item_prop =
    @(Get-WmiObject Win32_OperatingSystem |
      Select-Object SystemDirectory, Version, RegisteredUser )

    return $item_prop
}


function collect_normal_package {
    $pkg_infos =
    @( Get-ChildItem -Path(
           'HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
           'HKCU:SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'))
    
    $ret_pkg_infos = @()
    foreach ($pkg_info in $pkg_infos) {
    $item_prop =
    @(Get-ItemProperty $pkg_info.PsPath |
      Select-Object DisplayName, DisplayVersion, Publisher )

    $ret_pkg_infos += $item_prop
    }
    return $ret_pkg_infos
}

# function collect_normal_package {
#     $pkg_infos =
#     @( Get-ChildItem -Path(
#      'HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
#      'HKCU:SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall') |
#        % { Get-ItemProperty $_.PsPath |
#        Select-Object DisplayName, DisplayVersion, Publisher } )
#     return $pkg_infos
# }


do_main

(再) install WindowsApplicationDriver

https://end0tknr.hateblo.jp/entry/20190323/1553338368

先日、上記entryにて、Windows Application Driver をinstallしていますが、 あまりに中途半端なので、再度、hands-on。

find_element(s)by_accessibility_id() , find_element(s)by_class_name() , find_element(s)by_id() , find_element(s)by_name() , find_element(s)by_tag_name() , find_element(s)by_xpath() 等、要素探索のmethodが用意されていますが、 「WinAppDriver UI Recorder」でXPATHを調べ find_element_by_xpath()による要素探索が最も良かった。

ただし、アプリによっては「WinAppDriver UI Recorder」や「inspect.exe」による 調査中にアプリが強制終了する点が、なかなか難しい。

事前準備

Windows Application Driver

以下の WinAppDriver.exe を起動すると、port:4723 経由でwindowsアプリを操作できます。

WinAppDriver UI Recorder

https://github.com/Microsoft/WinAppDriver/releases/download/UiR_v1.0-RC/WinAppDriverUIRecorder.zip

上記zipを解凍し、 WinAppDriverUiRecorder.exe を起動すると、 アプリの各要素のXPATHを調べることができます。

inspect.exe

「WinAppDriver UI Recorder」と同様ですが、 アプリの各要素のクラス名や要素名等の様々な項目を調べることができます。

https://developer.microsoft.com/ja-jp/windows/downloads/sdk-archive からダウンロードし、インストールすると、以下に配備されます。

C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x64\inspect.exe

https://developer.microsoft.com/ja-jp/windows/downloads/sdk-archive

sample script

# -*- coding: utf-8 -*-
from appium import webdriver
import time

def main():
    ## アプリ起動
    desired_caps = {}
    desired_caps["app"] = r"C:\SCOOP\SCOOP22\Program\PLANMAN.exe"
    driver = webdriver.Remote(
        command_executor='http://127.0.0.1:4723',
        desired_capabilities= desired_caps)

    win_planman = init_planman(driver)
    print win_planman

    ## ↑ここまではうまく動作しました。
    ## ↓この先で、ListViewやTreeViewを探索したかったのですが
    ##   アプリが強制終了するなど、うまく動作しませんでした。
    pane_tree = win_planman.find_elements_by_class_name("ListLiew")
    print pane_tree

    
    ## 終了
    driver.quit()

def init_planman(driver):
    ## logon画面から遷移
    xpath_str = \
        "/".join(['/Pane[@Name="デスクトップ 1"][@ClassName="#32769"]',
                  'Window[@Name="ログオン"][@ClassName="ThunderRT6FormDC"]'])
    diagram_logon = driver.find_element_by_xpath(xpath_str)

    xpath_str = \
        "//Button[@Name=\"OK\"][@ClassName=\"ThunderRT6CommandButton\"]"
    diagram_logon.find_element_by_xpath(xpath_str).click()

    
    ## version check画面から遷移
    xpath_str = \
        "/".join(['/Pane[@Name="デスクトップ 1"][@ClassName="#32769"]',
                  'Window[@Name="SCOOP22 マネージャ"][@ClassName="#32770"]'])
    try:
        diagram_ver_chk = driver.find_element_by_xpath(xpath_str)
    except Exception as e:
        pass  ## version check画面が単に見つからない場合、無視して進みます
    else:
        xpath_str = "//Button[@Name=\"OK\"][@ClassName=\"Button\"]"
        diagram_ver_chk.find_element_by_xpath(xpath_str).click()
    
    ## plan manager探索
    xpath_str = \
        "/".join(['/Pane[@Name="デスクトップ 1"][@ClassName="#32769"]',
                  'Window[@Name="SCOOP22 マネージャ - soop22"]'+
                  '[@ClassName="ThunderRT6FormDC"]'])
    try:
        win_planman = driver.find_element_by_xpath(xpath_str)
    except Exception as e:
        print e , " " , xpath_str
        return

    return win_planman


if __name__ == '__main__':
    main()

サーバにinstallされているOSやMWの一覧を自動収集したい (windows版)

サーバにinstallされているOSやMWの一覧を自動収集したい (centos版) - end0tknr's kipple - 新web写経開発

先日の上記エントリのwindows版。

windowsの場合、コマンドライン(power shell Get-ChildItem)から以下のようにインストール済の一覧を取得できます

PS C:\Users\end0t> Get-ChildItem -Path(
>> 'HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
>> 'HKCU:SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall') |
>> % { Get-ItemProperty $_.PsPath | Select-Object DisplayName, DisplayVersion, Publisher }

DisplayName                                                           DisplayVersion  Publisher
-----------                                                           --------------  ---------
7-Zip 18.05 (x64)                                                     18.05           Igor Pavlov
Android Studio                                                        3.3             Google LLC
EPSON PX-049A Series プリンター アンインストール                                      Seiko Epson Corporation
Appium 1.11.0                                                         1.11.0          Appium Developers
GIMP 2.10.6                                                           2.10.6          The GIMP Team
Git version 2.19.1                                                    2.19.1          The Git Development Community
Mozilla Firefox 64.0.2 (x64 ja)                                       64.0.2          Mozilla
Mozilla Maintenance Service                                           61.0            Mozilla
Microsoft Project Professional 2016                                   16.0.4266.1001  Microsoft Corporation
Microsoft Office Professional Plus 2016                               16.0.4266.1001  Microsoft Corporation
Microsoft Visio Professional 2016                                     16.0.4266.1001  Microsoft Corporation
OWASP Zed Attack Proxy 2.7.0                                          2.7.0           OWASP ZAP
Vulkan Run Time Libraries 1.1.70.0                                    1.1.70.0        LunarG, Inc.
Canon MP470 series
Windows SDK for Windows Store Apps DirectX x64 Remote                 10.1.16299.91   Microsoft Corporation
Intel(R) Management Engine Components                                 11.7.0.1035     Intel Corporation
Application Verifier x64 External Package                             10.1.16299.91   Microsoft
Intel(R) PRO/Wireless Driver                                          20.50.0001.8400 Intel Corporation
Intel(R) Management Engine Components                                 1.0.0.0         Intel Corporation
Microsoft Visual C++ 2017 X64 Debug Runtime - 14.16.27024             14.16.27024     Microsoft Corporation
Windows App Certification Kit Native Components                       10.1.17763.132  Microsoft Corporation
Java(TM) SE Development Kit 10.0.1 (64-bit)                           10.0.1.0        Oracle Corporation
Universal CRT Tools x64                                               10.1.17763.132  Microsoft Corporation
Windows SDK for Windows Store Apps DirectX x64 Remote                 10.1.17134.12   Microsoft Corporation
Lenovo Active Protection System                                       1.82.00.17      Lenovo
CMake                                                                 3.14.0          Kitware
TortoiseSVN 1.10.1.28295 (64 bit)                                     1.10.28295      TortoiseSVN
   :