In my application there is a GenServer, which can create other processes. All process IDs are saved to a list.
def create_process do
GenServer.call(__MODULE__, :create_process)
end
def handle_call(:create_process, _from, processes) do
{:ok, pid} = SomeProcess.start_link([])
{:reply, {:ok, pid}, [pid | processes]}
end
There is also a function to get the list of PIDs.
def get_processes do
GenServer.call(__MODULE__, :get_processes)
end
def handle_call(:get_processes, _from, processes) do
{:reply, processes, processes}
end
I tried to write a doctest for the get_processes function like this:
#doc """
iex> {:ok, pid} = MainProcess.create_process()
iex> MainProcess.get_processes()
[pid]
"""
However the test runner doesn't seem to see the pid variable, and I get an undefined function pid/0 error.
I know it could be simply solved in with a regular test, but i want to know it it possible to solve in doctest.
The problem is the [pid] line in your expected result. The expected result should be an exact value, not a variable. You can't reference the variable from the expected result. You can work around it by checking the pid on the previous line:
iex> {:ok, pid} = MainProcess.create_process()
iex> [pid] === MainProcess.get_processes()
true
I have an Application, that runs multiple instances of itself. e.g
AppName.exe instance1
AppName.exe instance2
AppName.exe instance3
Using Powershell v2 I am trying to create a simple script that given an array of AppNames and instances, it loops through them, checks if they are running, and then shuts them down.
I figured the best way to do this would be check for each instance, if found capture it's processID, and pass that to the stop-process cmdlet.
BUT, I can't figure out how to get the process id.
So far I have:
$appName = "AppName.exe"
$instance = "instance1"
$filter = "name like '%"+$appName+"%'"
$result = Get-WmiObject win32_process -Filter $filter
foreach($process in $result )
{
$desc = $process.Description
$commArr = $process.CommandLine -split"( )"
$inst = $commArr[2]
$procID = "GET PROCESS ID HERE"
if($inst -eq $instance)
{
Stop-Process $procID
}
}
Can anyone tell me where to get the process ID from please?
you can use the get-process cmdlet instead of using wmi :
$procid=get-process appname |select -expand id
$procid=(get-process appname).id
When using Get-WmiObject win32_process ..., the objects returned have an attribute named ProcessId.
So, in the question, where you have:
$procID = "GET PROCESS ID HERE"
use:
$procID = $process.ProcessId
You could also use that in the $filter assignment, e.g.
$filter = "ProcessId=1234"
I've read PIL and the ModulesTutorial on creating modules but I'm having trouble require()ing them correctly.
Here is my setup:
-- File ./lib/3rdparty/set.lua
local ipairs = ipairs
module( "set" )
function newSet (t)
local set = {}
for _, l in ipairs(t) do set[l] = true end
return set
end
And:
-- File ./snowplow.lua
local set = require( "lib.3rdparty.set" )
module( "snowplow" )
local SUPPORTED_PLATFORMS = set.newSet { "pc", "tv", "mob", "con", "iot" }
Then if I run snowplow.lua:
lua: snowplow.lua:4: attempt to index local 'set' (a boolean value)
stack traceback:
snowplow.lua:4: in main chunk
[C]: ?
What am I doing wrong in my module definition - what is the boolean exactly? Also, if I append a return _M; at the bottom of my set.lua, then everything starts working - why?
true is usually returned by require if module function is not used inside module and module code doesn't return a value.
But anyway it seems strange.
-- file m0.lua
module'm0'
--file dir1\m1.lua
module'm1'
--file test.lua
print(require'm0')
print(m0)
print(require'dir1.m1')
print(m1)
for k,v in pairs(package.loaded) do
if k:match'm%d' then print(k, v) end
end
--output
table: 0036C8C8
table: 0036C8C8
true
table: 0036B6B0
m0 table: 0036C8C8
m1 table: 0036B6B0
dir1.m1 true
So, you can simply use global variable set instead of local set assigned a value returned by require.
UPD :
It is recommended to avoid using module function and always return your table at the end of your module. In that case the whole picture is just fine:
-- file m0.lua
return 'string0'
--file dir1\m1.lua
return 'string1'
--file test.lua
print(require'm0')
print(m0)
print(require'dir1.m1')
print(m1)
for k,v in pairs(package.loaded) do
if k:match'm%d' then print(k, v) end
end
--output
string0
nil
string1
nil
m0 string0
dir1.m1 string1
UPD2 :
Problem disappears if you replace module( "set" ) with module('lib.3rdparty.set').
So, each module must remember its relative path.
Now you could access it either by calling require'lib.3rdparty.set' or by reading global variable lib.3rdparty.set - the result would be the same.
require("lib.moduleName")
local moduleName = moduleName
I'm not sure why Lua returns a boolean when you require a module on a different directory, but it seems the module is correctly set on the the global variable. So I simply used that and put it on a local variable with the same name.
Tried the following:
config.time_zone = 'Pretoria'
config.active_record.default_timezone = 'Pretoria'
Not getting any errors, but it is still showing as London Time not Pretoria which is +2 Hours.
Any idea why?
maybe try to set the timezone on each request? That way you can eventually let the user set their own timezone and each request can be relevant to their time zone setting.
class ApplicationController < ActionController::Base
around_filter :set_time_zone
def set_time_zone
if logged_in?
Time.use_zone(current_user.time_zone) { yield }
else
yield
end
end
end
http://api.rubyonrails.org/classes/Time.html#method-i-zone-3D
Is it possible to call a COM method from PowerShell using named parameters? The COM object method I am working with has dozens of parameters:
object.GridData( DataFile, xCol, yCol, zCol, ExclusionFilter, DupMethod, xDupTol,
yDupTol, NumCols, NumRows, xMin, xMax, yMin, yMax, Algorithm, ShowReport,
SearchEnable, SearchNumSectors, SearchRad1, SearchRad2, SearchAngle,
SearchMinData, SearchDataPerSect, SearchMaxEmpty, FaultFileName, BreakFileName,
AnisotropyRatio, AnisotropyAngle, IDPower, IDSmoothing, KrigType, KrigDriftType,
KrigStdDevGrid, KrigVariogram, MCMaxResidual, MCMaxIterations, MCInternalTension,
MCBoundaryTension, MCRelaxationFactor, ShepSmoothFactor, ShepQuadraticNeighbors,
ShepWeightingNeighbors, ShepRange1, ShepRange2, RegrMaxXOrder, RegrMaxYOrder,
RegrMaxTotalOrder, RBBasisType, RBRSquared, OutGrid, OutFmt, SearchMaxData,
KrigStdDevFormat, DataMetric, LocalPolyOrder, LocalPolyPower, TriangleFileName )
Most of those parameters are optional and some of them are mutually exclusive. In Visual Basic or Python using the win32com module you can use named parameters to specify only the subset of options you need. For example (in Python):
Surfer.GridData(DataFile=InFile,
xCol=Options.xCol,
yCol=Options.yCol,
zCol=Options.zCol,
DupMethod=win32com.client.constants.srfDupMedZ,
xDupTol=Options.GridSpacing,
yDupTol=Options.GridSpacing,
NumCols=NumCols,
NumRows=NumRows,
xMin=xMin,
xMax=xMax,
yMin=yMin,
yMax=yMax,
Algorithm=win32com.client.constants.srfMovingAverage,
ShowReport=False,
SearchEnable=True,
SearchRad1=Options.SearchRadius,
SearchRad2=Options.SearchRadius,
SearchMinData=5,
OutGrid=OutGrid)
I can't figure out how to call this object from PowerShell in the same way.
This problem did interest me, so I did some real digging and I have found a solution (though I have only tested on some simple cases)!
Concept
The key solution is using [System.Type]::InvokeMember which allows you to pass parameter names in one of its overloads.
Here is the basic concept.
$Object.GetType().InvokeMember($Method, [System.Reflection.BindingFlags]::InvokeMethod,
$null, ## Binder
$Object, ## Target
([Object[]]$Args), ## Args
$null, ## Modifiers
$null, ## Culture
([String[]]$NamedParameters) ## NamedParameters
)
Solution
Here is a reusable solution for calling methods with named parameters. This should work on any object, not just COM objects. I made a hashtable as one of the parameters so that specifying the named parameters will be more natural and hopefully less error prone. You can also call a method without parameter names if you want by using the -Argument parameter
Function Invoke-NamedParameter {
[CmdletBinding(DefaultParameterSetName = "Named")]
param(
[Parameter(ParameterSetName = "Named", Position = 0, Mandatory = $true)]
[Parameter(ParameterSetName = "Positional", Position = 0, Mandatory = $true)]
[ValidateNotNull()]
[System.Object]$Object
,
[Parameter(ParameterSetName = "Named", Position = 1, Mandatory = $true)]
[Parameter(ParameterSetName = "Positional", Position = 1, Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]$Method
,
[Parameter(ParameterSetName = "Named", Position = 2, Mandatory = $true)]
[ValidateNotNull()]
[Hashtable]$Parameter
,
[Parameter(ParameterSetName = "Positional")]
[Object[]]$Argument
)
end { ## Just being explicit that this does not support pipelines
if ($PSCmdlet.ParameterSetName -eq "Named") {
## Invoke method with parameter names
## Note: It is ok to use a hashtable here because the keys (parameter names) and values (args)
## will be output in the same order. We don't need to worry about the order so long as
## all parameters have names
$Object.GetType().InvokeMember($Method, [System.Reflection.BindingFlags]::InvokeMethod,
$null, ## Binder
$Object, ## Target
([Object[]]($Parameter.Values)), ## Args
$null, ## Modifiers
$null, ## Culture
([String[]]($Parameter.Keys)) ## NamedParameters
)
} else {
## Invoke method without parameter names
$Object.GetType().InvokeMember($Method, [System.Reflection.BindingFlags]::InvokeMethod,
$null, ## Binder
$Object, ## Target
$Argument, ## Args
$null, ## Modifiers
$null, ## Culture
$null ## NamedParameters
)
}
}
}
Examples
Calling a method with named parameters.
$shell = New-Object -ComObject Shell.Application
Invoke-NamedParameter $Shell "Explore" #{"vDir"="$pwd"}
## the syntax for more than one would be #{"First"="foo";"Second"="bar"}
Calling a method that takes no parameters (you can also use -Argument with $null).
$shell = New-Object -ComObject Shell.Application
Invoke-NamedParameter $Shell "MinimizeAll" #{}
Using the Invoke-NamedParameter function did not work for me. I was able to find an interesting solution here https://community.idera.com/database-tools/powershell/ask_the_experts/f/powershell_for_windows-12/6361/excel-spreadsheet-export which did work for me.
$excel = New-Object -ComObject excel.application
$objMissingValue = [System.Reflection.Missing]::Value
$Workbook = $excel.Workbooks.Open($datafile,$objMissingValue,$False,$objMissingValue,$objMissingValue,$objMissingValue,$true,$objMissingValue)
Any parameter I did not use I added a missing value.