Getting unique ID of a user's machine

Hello,

First the code

output=`wmic csproduct get uuid`
puts "with command\n  ->"+output+"<-\nend with"
puts $?

and now SketchUp17 output

start version -----2.2.4
with command
  -><-
end with
pid 11108 exit 0
---------------------end

old SketchUp08 output

start version -----1.8.6
with command
  ->UUID                                  
78DC00C8-26EF-1210-1207-132829000000  

<-
end with
0
---------------------end

What’s going on? seems no longer working on Ruby2. where am I wrong?

Best Regards

# back tics in v17 on a mac works fine
output=`whoami`
puts "with command\n  ->#{output.chomp}<- \nend with"
puts $?

# returns
with command
  ->johns_iMac<- 
end with
pid 690 exit 0

john

Are you running both versions on SketchUp on the same computer, or different ones? That is, could this be due to a difference in Windows versions rather than SketchUp/Ruby versions?

I just a tested similar code in SU2017, and I have the same problem. I tested my code in stand-alone ruby, and it works fine.

To clarify the issue for other members, the return value of a backticked command is not being processed correctly in SU.

This might have something to do with SU redirecting what one might call system pipes to work with the newer Ruby console. I’ll have to get back to it…

Somewhere I have SU8, but not currently loaded. I believe you…

Later Edit:

When I was writing the original post, in the back of my mind I was thinking ‘I just wrote some code re-routing stdio, what was it?’. Nagged at me, I found it…

Hence, I tried -

  1. Using STOUT - didn’t test for what it is, but it doesn’t appear to be what you would expect
  2. Open3.popen3
  3. Running in another thread

Of course, just to frustrate anyone, all code worked in stand-alone Ruby, but none worked in SU.

In SketchUp 2014 (when we first switched to Ruby 2.x,) we had a similar issue.

I created a little patch script (at that time) to fix the situation, until it was fixed (SU2015 M0?)

backquote_patch.rb (1.2 KB)

# encoding: UTF-8
#  file : backquote_patch.rb
#
#  Windows ONLY : Ruby v1.9+
#  Needed as of SketchUp 2014 M0 RC4
#
#  v 1.0.0  -  2014-02-19

if RUBY_VERSION.to_f > 1.8 && RUBY_PLATFORM !~ /darwin/i

  # We are running under MS Windows
  if `ver`.empty? # patch global backquote method:

    module Kernel

      # The backquote method `() already has a module function copy: Kernel::`()
      # so we do not need to alias it, in order to access it's functionality.

      def backquote(cmd)
        #
        tempfile = nil
        raise(TypeError,'string argument expected.',caller) unless cmd.is_a?(String)
        #
        tempfile = ENV['TMP'].encode('UTF-8').gsub('\\','/')
        tempfile << '/backquote.out'
        #
        ::Kernel::method('`').call("#{cmd} > #{tempfile}")
        return File.read(tempfile)
        #
      rescue
        raise
      ensure
        if tempfile && File::exist?(tempfile)
          File::delete(tempfile) rescue nil
        end
      end

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

  end # conditional patch

end # if not OSX
2 Likes

Good post. That was the next thing I’d look at later. One would hope there’s an easier way than using ‘pipe to file’.

Maybe IO.copy_stream

you could try and see if open3 shows where the issue is…

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

windows syntax may need to be slightly different…

john

And just for info, … are any people having SU2017 issues, have the Trimble Developer Console installed ?

Or any other 3rd party console that might redirect IO ?

… if so, try switching them off, restart SketchUp and see if the issue persists.

Not enough time to read all your posts
here are all test I could
PCintelWin7updatedWin10

with Sketchup 17, code puts `echo "hi"` puts $? return
  -><-, pid 8624 exit 0
end with
with Sketchup 16, code puts `echo "hi"` puts $? return
  -><-, pid 496 exit 0
end with
with Sketchup 15, code puts `echo "hi"` puts $? return
  -><-, pid 6048 exit 0
end with
with Sketchup 14, code puts `echo "hi"` puts $? return
  -><-, pid 2556 exit 0
end with
with Sketchup 13, code puts `echo "hi"` puts $? return
  ->'hi'<-, 0
end with
with Sketchup 8, code puts `echo "hi"` puts $? return
  ->'hi'<-, 0
end with

PCamdWin10

with Sketchup 17, code puts `echo "hi"` puts $? return
  ->'hi'<-, pid 5324 exit 0
end with
with Sketchup 8, code puts `echo "hi"` puts $? return
  ->'hi'<-, 0
end with

PCintelWin7

with Sketchup 16, code puts `echo "hi"` puts $? return
  -><-, pid 3816 exit 1
end with
with Sketchup 8, code puts `echo "hi"` puts $? return
  ->'hi'<-, 0
end with

I’m back soon

1 Like

@SUalive, for the 3 machines, can you answer the question I posed above:
Getting unique ID of a user's machine - #8 by DanRathbun

I recall reading that on some versions of Windows %x[] works but it’s alias back ticks fails…

john

That is strange because the docs say:

Module: Kernel (Ruby 2.2.4)

`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.