Getting unique ID of a user's machine

That is strange because the docs say:

http://ruby-doc.org/core-2.2.4/Kernel.html#method-i-60

`cmd`

Returns the standard output of running cmd in a subshell. The built-in syntax %x{...} uses this method. Sets $? to the process status.

This is why I wrote the ol’ patch the way I did, and why there is the comment in it:

      # Override the private instance method #`() that all objects inherit,
      #  and rewire %x delimited execute strings, to use our backquote() patch:
      alias_method("`",:backquote)

I found the quote I refer to, a comment in <52>

When running the same script on a Windows machine with Cygwin, it failed because of the back ticks, but worked with %x[].

john

okay, how many SketchUp users would be using a Cygwin shell whilst SketchUp is running ?

And, that SO thread doesn’t really say why Cygwin caused the backtick method to fail. It could be that the method was aliased incorrectly, whilst the %{} still called the original method (or directly calls the C-side core function.) But I am just guessing. (I have no interest in digging into Cygwin.)

some others tests SketchUp17 only

ret_val = system("wmic csproduct get uuid")
puts ret_val
true

of course!

output = IO::popen("wmic csproduct get uuid") {|io| io.read}
success = $?.exitstatus == 0
puts success.to_s+", "+output
true, 

same issue

require 'open3'
cmd = 'wmic csproduct get uuid'
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
  puts "stdout is:" + stdout.read
  puts "stderr is:" + stderr.read
end
stdout is:
stderr is:

no change

Now time to read your replies…

@DanRathbun
nothing installed on all computers. only All SketchUp version EN or French with no extension.
Stop then restart SketchUp no effect
Stop then restart system no effect
%{} syntax no change

@john_drivenupthewall

require 'open3'
output='wmic csproduct get uuid'
out, err, st = Open3.capture3(output)
puts out
puts err
puts st

gives two blank lines then
pid 7496 exit 0

well I hope I replied all

Hello,
Many thanks all for the help
Here is Dan revisited code and checks. Need some improvements like checking Windows and Ruby version.
@DanRathbun
String.encode needed? Why?
How do you colorize your code on the forum?

so code picture


and code (thanks to Dan. I’ve got colorized code!)

def system_read(str_cmd)
      begin
        filename = nil
        raise('system_read(str_cmd). str_cmd must be a string.') unless str_cmd.is_a?(String)
        raise('system_read(str_cmd). str_cmd must not be empty string.') if str_cmd.length == 0
        str_data = IO::popen(str_cmd) {|io| io.read}.strip()
        bol_exit = ($?.exitstatus == 0)
        if str_data.empty? or !bol_exit
          filename = ENV['TMP'].encode('UTF-8').gsub('\\','/') + "/" + (Time.new.to_f * 1000).to_i.to_s
          bol_exit = system(str_cmd + " > " + filename)
          str_data = File.read(filename).strip()
        end
      return bol_exit, str_data
      rescue => e
        puts e.message
      ensure
        if filename && File::exist?(filename)
          File::delete(filename) rescue nil
        end
      end
    end

    bol_exit, str_data = system_read('echo "Hello world!"')
    puts "    with Sketchup " + Sketchup.version.split(".")[0]+"\n      "+
	bol_exit.to_s + ", ->" + str_data + "<-\n    end with"

now checks
PCintelWin7updatedWin10

    with Sketchup 17
      true, ->"Hello world!"<-
    end with
    with Sketchup 16
      true, ->"Hello world!"<-
    end with
    with Sketchup 15
      true, ->"Hello world!"<-
    end with
    with Sketchup 14
      true, ->"Hello world!"<-
    end with
    with Sketchup 13
      true, ->"Hello world!"<-
    end with
    with Sketchup 8
      true, ->"Hello world!"<-
    end with

PCamdWin10

    with Sketchup 17
      true, ->"Hello world!"<-
    end with
    with Sketchup 8
      true, ->"Hello world!"<-
    end with

PCintelWin7

    with Sketchup 16
      true, ->"Hello world!"<-
    end with
    with Sketchup 8
      true, ->"Hello world!"<-
    end with

all right. good news!

@john_drivenupthewall
may you run the script on your Macs and tell me results please?
@MSP_Greg or any other Windows User facing same issue
may you run the script and tell me results please?

Have a good day
WhyDi

it isn’t needed and won’t run on a mac without conditionals for the temp file path…

it also isn’t needed on all PC’s so you should keep @DanRathbun’s conditional…

 if `ver`.empty? # patch global backquote method:

look at this thread about getting the MAC address

john

Thanks for the Mac address link. Much to learn!

By the way and about temp file path on OSX
can I read temp file path from

 ENV['TMPDIR']

may you show me the right command and its result please?

Does OSX env[] have something for Windows env[ALLUSERSPROFILE]?

tmpdir = ENV["TMPDIR"] || ENV["TEMP"] || ENV["TMP"]

ENV["USERPROFILE"]

OSX (and all Unix-like OSes) have always defined “HOME”.
SketchUp Ruby started defining it around SU2014, I think.
In Ruby, when ENV["HOME"] is defined, then the tilde ~ character can be used in path strings as a shorthand for the user’s home directory on Unix-like OSes. But on Windows you would need to use File.expand_path to expand any path strings with a tilde in them.

home = ENV["HOME"] || ENV["USERPROFILE"]

We used to do this so that the Home var was defined on Windows:

ENV["HOME"]= ENV["USERPROFILE"] if ENV["HOME"].nil? && ENV["USERPROFILE"] 

I think OSX has a directory location, but I do not know know if there is an environment variable pointing at it.

I’ll let @john_drivenupthewall (John) or @slbaumgartner (Steve) answer this.

Great Dan!
and thanks for code color working fine - I edited my previous post!

waiting for John or Steve…

I don’t know what use you make of ENV[“ALLUSERSPROFILE”]. That could affect whether there is even an equivalent concept in OS X. But in any case, I think there is no equivalent ENV string.

You might consider making your code Windows specific. John (first reply) posted code sample that showed backticks are not an issue with OSX.

It would point the same place as ENV["ProgramData"] ("C:\ProgramData" by default,) on Windows 6+.

In older Windows versions it was called the “All Users” profile, and pointed at (depending upon if it was a clean install, or upgraded and whether the old OS was Windows or NT):

"C:\Documents and Settings\All Users"
or
"C:\Profiles\All Users"
perhaps
"C:\Users\All Users"

These are not equivalent to the “Public” folders on Windows 6+. They should have restricted permissions, ie only application processes should be writing to these locations. (Older versions Windows 5 and earlier, may not have had such strict restrictions.)

[Not to be confused with the “Default User” profile that is used as a template, when creating a new user account.]


On Mac, it be "HD/Application Support/" wouldn’t it ? as opposed to the "~/Application Support/" ?


ADD: There are OS differences. On Windows, this “shared profile” contains special sub-folders like “Start Menu”, “Desktop”, etc. whose contents appear (display) to all users as if their contents where also in each user’s folders of the same name. I doubt if OSX does things in the same way.

You missed my real point: having found that directory, what content would the script expect to find there and what would it want to use it for? Need to answer those to figure out where OS X keeps the equivalent info (or if anything equivalent even exists).

Those paths are missing a stage: “/Library/Application Support” and “~/Library/Application Support”.

Indeed, it does not!

1 Like

Yes, I know. I’d guess, shared company extension data. Some extension companies wish to actually install their extensions there (which I think just causes more problems than not.)

it works with a conditional path and returns the same as on windose…

but you really should only write/read files when you need to. on a mac you don’t need to…

only two of the ENV entries are useful to you…

ENV.entries.each{|k| p k[0]};nil
"TMPDIR" # same path as OSX $TMPDIR and it is a unique per User folder
"__CF_USER_TEXT_ENCODING"
"HOME" # File.expand_path('~') == ENV['HOME'] # => true
"SHELL"
"Apple_PubSub_Socket_Render"
"SSH_AUTH_SOCK"
"PATH" # path to shell
"LOGNAME"
"DISPLAY"
"XPC_SERVICE_NAME"
"USER"
"XPC_FLAGS"
"IG_ROOT"
"GEM_PATH"
"GEM_HOME"
"SSL_CERT_FILE"
"RLM_DIAGNOSTICS"
"RLM_ROAM"

john

1 Like

The simplest way to find the temp folder is:

temp_dir = Sketchup.temp_dir

available since v2014

2 Likes

Hello,

@slbaumgartner
I answered using private message. Thanks for the reply. I learnt Mac OSX is per user level.

@MSP_Greg
We - unfortunately - are going to make specific code, no doubt but do not know what kind yet. I was pleased to learn no extra window opening on the Mac - thank to John - but have no solution on Windows. wmi is slow through backtick and shows that annoying small black window. We would like bringing an elegant but robust answer. Perhaps a extra exe.

@danRathbun
You’re right looks like OSX does things it’s own way, not Windows like regarding system-level location

@john_drivenupthewall
Of course and fortunately no need of extra file on OSX, only Windows requires. The - bad - script above was just for test purposes. Thanks for the commented ENVironment variable list.

@TIG
It was my first place but SUalive back compatibility down to SketchUp 8 needs ENV[] use.

about OSX
what is /usr/share/ folder for on the Mac?

Have a good day
WhyDi

it’s now a restricted folder that can only be used by Apple certified application installers/updaters, etc…

you can not modify any files in /System, /bin, /sbin, or /usr (except /usr/local) using code or even as Root…

there is however a /Users/Shared folder that is intended for sharing folders, files, settings between all users but programatic access to it needs to be hardcoded into any shared ‘parent’ application…

SU doesn’t look for files in /Users/Shared even though it would be very useful on shared computers…

john

Ah hah! The equiv. of ENV["Public"] on Windows.