How to check if a specific driver is installed using AutoLISP - lisp

(My ultimate goal is to verify if a specific database OCDB driver is installed before I run an Autolisp coded connection to a database)
I would like to know : How can i check if a driver is installed on a Windows 10 x64 computer, using AutoLISP on BricsCAD (or else AutoCAD)?
Also, may i have your commentaraies on the possibility of programatically installing the driver using autolisp? I guess, there are some wrappers available or in the worst case, i can simply launch the manual installation using (startapp "Explorer" "...installer-winx64.msi").
Thanks,

To ascertain whether the driver is installed, you could interrogate the Win32_SystemDriver WMI class - consider the following example:
;; Win32 System Driver-p - Lee Mac
;; Returns T if a driver exists with the supplied name
(defun LM:win32systemdriver-p ( drv )
(LM:wmiqueryhasmembers-p (strcat "select * from win32_systemdriver where name = '" drv "'"))
)
;; WMI Query has Members-p - Lee Mac
;; Returns T if the supplied WMI query has members
(defun LM:wmiqueryhasmembers-p ( qry / rtn srv wmi )
(if (setq wmi (vlax-create-object "wbemscripting.swbemlocator"))
(progn
(setq rtn
(vl-catch-all-apply
'(lambda ( )
(setq srv (vlax-invoke wmi 'connectserver)
qry (vlax-invoke srv 'execquery qry)
)
(< 0 (vla-get-count qry))
)
)
)
(foreach obj (list qry srv wmi)
(if (= 'vla-object (type obj)) (vlax-release-object obj))
)
(and (not (vl-catch-all-error-p rtn)) rtn)
)
)
)

The adopted test is simply :
(member "MySQL ODBC 3.51 Driver" ; Driver name in the Windows Registry (vl-registry-descendents "HKEY_LOCAL_MACHINE\\SOFTWARE\\ODBC\\ODBCINST.INI\\"))
Which will reliably give the right answer for the driver if ran either on a x86 process (32 bit app) or a x64 process using a x64 system.

Related

Run `create-react-app` from within Common Lisp

Assuming that a local system has create-react-app installed (npm i -g create-react-app), I want to run it with parameters from within a Common Lisp file. What's the best way to do this?
as far as i know, the potrable solution is uiop:run-program, since your cl distribution probably has the asdf included.
CL-USER> (uiop:run-program "create-react-app" :output t :error-output t)
;;Please specify the project directory:
;; create-react-app <project-directory>
;;For example:
;; create-react-app my-react-app
;;Run create-react-app --help to see all options.
;;; Debugger entered on #<UIOP/RUN-PROGRAM:SUBPROCESS-ERROR {10018B83A3}>
this one reports error, as the create-react-app itself does for no args.
(uiop:run-program "create-react-app my-new-shiny-app" :output t :error-output t)
succeeds, and creates app in your cwd.
you can wrap it into a function like this, for example:
(defun create-react-app (app-path &key verbose info scripts-version template use-npm use-pnp typescript)
(let ((cmd (format nil "create-react-app ~a ~
~#[--verbose~*~] ~
~#[--info~*~] ~
~#[--scripts-version ~a~] ~
~#[--template ~a~] ~
~#[--use-npm~*~] ~
~#[--use-pnp~*~] ~
~#[--typescript~*~]"
app-path verbose info scripts-version template use-npm use-pnp typescript)))
(format t "executing shell command: ~a~%" cmd)
(uiop:run-program cmd :output t :error-output t)))
(create-react-app "my-new-shiny-app" :template "cra-template-quickstart-redux" :use-npm t)
havent thoroughly tested it, but it should work.

How to use usocket to create a connection? (common lisp)

I'm trying to use socket in lisp to create a connection. Using sbcl, i found "usocket" available. But I failed to sending strings between the server and client. Here's the code:
Server:
(ql:quickload "usocket")
(use-package 'usocket)
(defun default-tcp-handler (stream) ; null
(declare (type stream stream))
(terpri stream))
(defparameter *us* (socket-server "127.0.0.1" 4547 #'default-tcp-handler))
(defparameter *s* (socket-accept *us*))
(defparameter *ss* (usocket:socket-stream *s*))
Client:
(ql:quickload "usocket")
(use-package 'usocket)
(defparameter *us* (socket-connect "127.0.0.1" 4547))
(defparameter *st* (usocket:socket-stream *us*))
I ran the server code first, it freezes. Then I ran the client code. But the server seemed to be no response.
I tried to format a string into the st stream:
(format *st* "hello, server")
But it returns nil.
How can i solve the problem??
Thanks a lot.
I tried your code and there were no errors, so everything seemed to be all right with the connection. However, if you only write to streams without reading (not to mention flushing the output), the connection has no way to manifest itself. Here is a modified version where the server reads a single line from the socket:
;;; server
(ql:quickload "usocket")
(use-package :usocket)
(defun default-tcp-handler (stream)
(declare (type stream stream))
(format t "~A~%" (read-line stream))
(finish-output))
(defparameter *us* (socket-server "127.0.0.1" 4547 #'default-tcp-handler))
;;; client
(ql:quickload "usocket")
(use-package :usocket)
(defparameter *us* (socket-connect "127.0.0.1" 4547))
(defparameter *st* (socket-stream *us*))
(write-line "hello server" *st*)
(finish-output *st*)
In your case format returned nil, because it always returns nil except format nil. The server hangs because it starts listening. If you don't want that, you'll have to work with multiple threads.

How do I choose/switch Leiningen profiles with Emacs nREPL?

I have a :dev profile set up in my leiningen project file. This defines an :init and :init-ns setting for my repl session. If I launch nrepl in emacs (M-x nrepl-jack-in) with the cursor over the :dev keyword in my project.clj, the repl launches and the :init and :init-ns settings are used. If I have my cursor elsewhere, the initial namespace is different (a test ns, not user), and :init hasn't been evaluated.
I'm guessing it's a feature of some sort, (I'm more inclined to think it's random buggy behaviour now) but can anyone explain it or point me at the docs that do so? Also, is there any way to change the profile once the repl's been launched?
Thanks
Contrary to what commenter #user7610 said, there is no cider-jack-in-with-profile function in cider. Cider pull-request #544 was a bit misleading in that regard.
If you want cider to load your own special-snowflake profile do this in emacs:
M-x set-variable cider-lein-parameters to e.g. with-profile +my-special-snowflake repl :headless
or to set the variable interactively (so you can see it's current value before changing it):
C-h, v cider-lein-parameters and then click or hit enter on "customize" and set it there to e.g. with-profile +my-special-snowflake repl :headless and apply it
That'll cause your next cider-jack-in to load the my-special-snowflake profile in addition to the base profile (which is needed in order to run the nrepl and hence cider).
Try this:
(defun start-cider-repl-with-profile ()
(interactive)
(letrec ((profile (read-string "Enter profile name: "))
(lein-params (concat "with-profile +" profile " repl :headless")))
(message "lein-params set to: %s" lein-params)
(set-variable 'cider-lein-parameters lein-params)
(cider-jack-in)))
Test on CIDER 0.16.0 (Riga)
I'm just searching the same feature and found this open issue in clojure-emacs/nrepl.el "Add argument to nrepl-jack-in to allow specification of profiles" https://github.com/clojure-emacs/nrepl.el/issues/327
it is still open
I try the function author by Jiacai Liu in my computer(GNU Emacs 26.2 (build 1, x86_64-apple-darwin18.2.0, NS appkit-1671.20 Version 10.14.3 (Build 18D109)) of 2019-04-13) . I get a error is:
eval-region: Wrong number of arguments: (1 . 1), 0
And then, I try to elisp function as:
(defun start-cider-repl-with-profile ()
(interactive)
(letrec ((profile (read-string "Enter profile name: "))
(lein-params (concat "with-profile +" profile " repl :headless")))
(message "lein-params set to: %s" lein-params)
(set-variable 'cider-lein-parameters lein-params)
(cider-jack-in '())))
Now it work. Thanks for Jiacai Liu!

Connect emacs to a remote ensime server

How can I connect to an ensime server on a remote host? My netbook is a bit slow for that kind of stuff. I copied the data over and use tramp to edit the files remotely. I ran bin/server to create the server and an ssh forwarding to be able to connect to it. I use ensime-connect to connect to the port on localhost. The ensime server on the remote server answers with Got connection, creating handler..., but that's about it. Ensime is in [ENSIME: wtf] mode in the emacs status line. How do I fix this?
The problem is the ensime can not find "config" of the connection (made through ensime-connect).
and then following line will throws error:
(if (and loose (ensime-file-in-directory-p file project-root))
because project-root is nil.
By setting the connection to ensime-buffer-connection, the problem can be fixed.
try adding following function to your ensime.el
and using the ensime-stackoverflow-connect to connect.
(defun ensime-stackoverflow-connect (host port)
(interactive (list
(read-from-minibuffer "Host: " ensime-default-server-host)
(read-from-minibuffer "Port: " (format "%d" ensime-default-port)
nil t)))
(let ((c (ensime-connect host port))
(config (ensime-config-load "/Users/whunmr/lab/scala/.ensime")))
(ensime-set-config c config)
(setq ensime-buffer-connection c))
)
remember to change the config path in the code: "/Users/whunmr/lab/scala/.ensime"
EDIT1:
the ".ensime" file was created by M-x ensime command, in your scala project folder.
actually, by just hardcode the config, you can ignore the file.
(defun ensime-my-connection (host port)
(interactive (list
(read-from-minibuffer "Host: " ensime-default-server-host)
(read-from-minibuffer "Port: " (format "%d" ensime-default-port)
nil t)))
(let ((c (ensime-connect host port))
(config '(:project-name "test" :project-package "com.whunmr" :sources ("./src") :compile-jars ("./" "../../apps/scala/lib/") :target "./bin" :root-dir "/Users/twer/lab/scala/")))
(ensime-set-config c config)
(setq ensime-buffer-connection c))
)

cl-pdf output error

I'm trying to use cl-pdf for some fairly basic PDF generation, but I'm getting tripped up at the examples (which is embarassing to say the least).
When I run the first example included in the package
(defun example1 (&optional (file #P"/tmp/ex1.pdf"))
(pdf:with-document ()
(pdf:with-page ()
(pdf:with-outline-level ("Example" (pdf:register-page-reference))
(let ((helvetica (pdf:get-font "Helvetica")))
(pdf:in-text-mode
(pdf:set-font helvetica 36.0)
(pdf:move-text 100 800)
(pdf:draw-text "cl-pdf: Example 1"))
(pdf:translate 230 500)
(loop repeat 150
for i = 0.67 then (* i 1.045)
do (pdf:in-text-mode
(pdf:set-font helvetica i)
(pdf:set-rgb-fill (/ (random 255) 255.0)
(/ (random 255) 255.0)
(/ (random 255) 255.0))
(pdf:move-text (* i 3) 0)
(pdf:show-text "cl-typesetting"))
(pdf:rotate 13)))))
(pdf:write-document file)))
by running (example1 #P"/home/inaimathi/Desktop/ex1.pdf") it gives me this error
#<SB-SYS:FD-STREAM for "file /home/inaimathi/Desktop/test.pdf"
{CF9D931}> is not a binary output stream.
[Condition of type SIMPLE-TYPE-ERROR]
Restarts:
0: [ABORT] Exit debugger, returning to top level.
The same thing happens when I call (example1), or when I do
(with-open-file
(test-file #P"/home/inaimathi/Desktop/ex1.pdf"
:direction :output :if-does-not-exist :create)
(example1 test-file))
Finally, if I try
(with-open-file
(test-file #P"/home/inaimathi/Desktop/ex1.pdf"
:direction :output :if-does-not-exist :create
:element-type '(unsigned-byte 8))
(example1 test-file))
I get the error
#<SB-SYS:FD-STREAM for "file /home/inaimathi/Desktop/test.pdf"
{D197C99}> is not a character output stream.
[Condition of type SIMPLE-TYPE-ERROR]
Restarts:
0: [ABORT] Exit debugger, returning to top level.
Is there a way to declare a binary character stream? How do I get simple output out of cl-pdf? I'm using SBCL straight out of the debian repos (which is 1.0.29, I think), in case it matters.
(setf pdf:*compress-streams* nil) should help. It's trying to write binary data to a character stream, and while that works on LispWorks and some other systems, it doesn't work everywhere and particularly not on SBCL.
EDIT 2: asdf-install is unmaintained and deprecated. It is best to use Quicklisp. To install Quicklisp, you'll need to download it:
$ curl -O https://beta.quicklisp.org/quicklisp.lisp
Then add cl-pdf to your lisp installation:
$ sbcl --load quicklisp.lisp
* (quicklisp-quickstart:install)
* (ql:quickload "vecto")
* (ql:add-to-init-file)
* (exit)
Now all you need to do is add
(load "~/quicklisp/setup.lisp") ; if it installed in the default location
to your .lisp file, and you can then add
(ql:quickload "cl-pdf")
EDIT: This is what I ended up doing. The solution by xach above would also work.
In the end I had to wget http://www.fractalconcept.com/download/cl-pdf-current.tgz and install that.
For the newbs (since I remember how frustrating it is for someone new to Common Lisp to hear "just do a checkout and install it"):
1.Do the checkout as above (I assume you've done this in your home directory from now on)
2.Type in tar xvzf cl-pdf-current.tgz (the point is to get a tarball of the folder. You can do this through the GUI too, it makes no difference)
3.Hop into your SBCL prompt and enter
(require 'asdf)
(require 'asdf-install)
4.If you already installed cl-pdf using (asdf-install:install 'cl-pdf), then you'll need to enter (asdf-install:uninstall 'cl-pdf)
5.Type (asdf-install:install "/home/[your home folder name]/cl-pdf-current.tgz")
I got one compilation error throughout this process, which I just selected [Accept] for. It still seems to work fine.
Hopefully the upcoming release of quicklisp will reduce the need for this sort of package hunting.