x++ cannot read registry entry - x++

I have a problem reading a registry entry in x++.
I'm trying to find the install Directory of the HelpServer. I'm working with the client on the same computer of the AOS and help server.
The key is HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Dynamics\6.0\Setup\HelpServer
and the property is InstallDir.
When I try to read the node, the system returns no handle:
winapi::regOpenKey(#HKEY_LOCAL_MACHINE, #'SOFTWARE\Microsoft\Dynamics\6.0\Setup\HelpServer', #KEY_READ);)
If I try to read the key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Dynamics\6.0\Setup that has a property with the same name of the above, I can read the value without any problem.

Related

Opening a file in pyfilesystem's s3 filesystem fails

I'm trying to simply open a file in pyfilesystem's s3 filesystem as such:
>>> s3fs.listdir('dfparks/test')
['test.txt']
>>> s3fs.open('dfparks/test/test.txt')
I get the error:
fs.errors.ResourceNotFound: resource 'dfparks/test/test.txt' not found
I've tried every variant of the path / s3 url I can think of but I always get the not found error.
fs.s3fs by default works in strict mode, checking for existence of directory markers (keys ending with "/"). You can turn off strict mode by passing strict=False to S3FS constructor or append "strict=0" to url passed to fs.open_fs
But, unfortunately, S3FS still does these checks in few places even in strict=False mode. There is my PR waiting for review fixing that: https://github.com/PyFilesystem/s3fs/pull/60. In the meantime you can install fixed version using fs-s3fs-ng package:
pip install fs-s3fs-ng
Additionally it enables non-strict mode by default and turns on S3 streaming (other PR waiting for acceptance)
Please let me know if this works for you.

Delphi- How to get my full domain name

In my program I am trying to retrieve the domain name of the current machine.
i found some code that people wrote in forums but they all seem to work partially.
what i mean is that my domain name is something like 'mydomain.mydomain11.com'
and when trying to retrieve the domain name i always get only 'mydomain' instead of 'mydomain.mydomain11'
I also tried usng the 'GetEnvironmentVariable' function which returns the same thing.
If possible, i would like to know how can i retrieve the full path.
my final goal is to query active directory using LDAP protocol, so it will really help to know how can chunk the domain path to something like :
CN=Users,DC=mydomain,DC=mydomain11,DC=com
but getting my full domain name will do for now..
You can use the GetComputerNameEx function with the ComputerNamePhysicalDnsDomain parameter:
The name of the DNS domain assigned to the local computer. If the local computer is a node in a cluster, lpBuffer receives the DNS domain name of the local computer, not the name of the cluster virtual server.`
If your goal is to connect to LDAP to search objects in the directory the usual approach is to connect to RootDSE. Here is an example.
ref What's the best method for getting the local computer name in Delphi
ref http://www.delphipages.com/forum/showthread.php?t=29823
under LorAn, pronounced Lorne - great framework for fetch
rolled in Delphi variable MAXCHAR for buffer size, should be the largest size that can be returned in shortest timeframe
function getDomain: string;
var
vlDomainName : array[0..MAXCHAR] of char;
vlSize : ^DWORD;
begin
New(vlSize);
vlSize^ := MAXCHAR;
ExpandEnvironmentStrings(PChar('%USERDOMAIN%'), vlDomainName, vlSize^);
Dispose(vlSize);
Result := vlDomainName;
end;
To get DNSServer.DOMAIN.DOMAIN..
use ADSI library ADSystemInfo GetAnyDCName() function & split on the decimal [.]

Why is COMMON_APPDATA returned as a null string on Windows XP

One of my users at a large university (with, I imagine, the aggressive security settings that university IT departments general have on their computers) is getting an empty string returned by Windows XP for CSIDL_COMMON_APPDATA or CSIDL_PERSONAL. (I'm not sure which of these is returning the empty string, because I haven't yet examined his computer to see how he's installed the software, but I'm pretty sure it's the COMMON_APPDATA...)
Has anyone encountered this or have suggestions on how to deal with this?
Here's the Delphi code I'm using to retrieve the value:
Function GetSpecialFolder( FolderID: Integer):String;
var
PIDL: PItemIDList;
Path: array[0..MAX_PATH] of Char;
begin
SHGetSpecialFolderLocation(Application.Handle, FolderID, PIDL);
SHGetPathFromIDList(PIDL, Path);
Result := Path;
end; { GetSpecialFolder }
ShowMessage(GetSpecialFolder(CSIDL_COMMON_APPDATA)); <--- This is an empty string
Edit:
Figuring out this API made me feel like I was chasing my tail - I went in circles trying to find the right call. This method and others similar to it are said to be deprecated by Microsoft (as well as by a earlier poster to this question (#TLama?) who subsequently deleted the post.) But, it seems like most of us, including me, regularly and safely ignore that status.
In my searches, I found a good answer here on SO from some time ago, including sample code for the non-deprecated way of doing this: what causes this error 'Unable to write to application file.ini'.
If you want to find out why an API call is failing you need to check the return values. That's what is missing in this code.
You need to treat each function on its own merits. Read the documentation on MSDN. In the case of SHGetSpecialFolderLocation, the return value is an HRESULT. For SHGetPathFromIDList you get back a BOOL. If that is FALSE then the call failed.
The likely culprit here is SHGetSpecialFolderLocation, the code that receives the CSIDL, but you must check for errors whenever you call Windows API functions.
Taking a look at the documentation for CSIDL we see this:
CSIDL_COMMON_APPDATA
Version 5.0. The file system directory that contains application data for all users. A typical path is C:\Documents and Settings\All
Users\Application Data. This folder is used for application data that
is not user specific. For example, an application can store a
spell-check dictionary, a database of clip art, or a log file in the
CSIDL_COMMON_APPDATA folder. This information will not roam and is
available to anyone using the computer.
If the machine has a shell version lower than 5.0, then this CSIDL value is not supported. That's the only documented failure mode for this CSIDL value. I don't think that applies to your situation, so you'll just have to see what the HRESULT status code has to say.

Problem installing windows service

I am having a problem installing a Windows service. I installed and uninstalled the service numerous times (installutil..... installutil /u) without any problem but something went wrong and now when I attempt to install, I get the error message listed below. I checked the computer management console, and service CIMediator does not appear on the list of services. How do I remove the service?
System.ArgumentException: Source CIMediator already exists on the local computer.
Just solved the same problem, also after a numerous uninstalls/installs/restarts.
I have my own implementation of service installer (derived from [System.Configuration.Install.Installer][1]), and I have specified application EventLog as following:
public ProjectInstaller()
{
InitializeComponent();
EventLogInstaller installer = FindInstaller(this.Installers);
if (installer != null)
{
installer.Log = "MyService";
}
}
You might have the same feature implemented the following way ([MSDN: EventLog.CreateEventSource Method] [2]):
if(!EventLog.SourceExists("MySource"))
{
EventLog.CreateEventSource("MySource", "MyNewLog");
}
In my case, during some of the installs EventLog was successfuly created, but during uninstall something went wrong, and EventLog was not removed (although it was not displaying in EventViewer, it was still present in the registry).
So the error "MyService already exists on the local computer", was obviously error about EventLog, not the service itself.
You could try to do the following:
Go to your Start menu and type regedit. This will open Registry Editor. Be careful with it, it is always recommended to back up the whole registry before doing anything (File -> Export), or only the keys you are about to edit/delete.
Open Edit -> Find , type CIMediator and leave only Keys checked. Your service name should appear as key multiple times, on following locations
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\eventlog\CIMediator,
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\CIMediator,
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\CIMediator,
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\CIMediator
Try to delete these keys. It worked for me.
1
2
Check to see if the key is still there in the registry.
HKLM\System\CurrentControlSet\Services\CIMediator (probably, unless the key is defined differently)
If it is, export the key to a .reg file and then delete it.

How to get Excel version and macro security level

Microsoft has recently broken our longtime (and officially recommended by them) code to read the version of Excel and its current omacro security level.
What used to work:
// Get the program associated with workbooks, e.g. "C:\Program Files\...\Excel.exe"
SHELLAPI.FindExecutable( 'OurWorkbook.xls', ...)
// Get the version of the .exe (from it's Properties...)
WINDOWS.GetFileVersionInfo()
// Use the version number to access the registry to determine the security level
// '...\software\microsoft\Office\' + VersionNumber + '.0\Excel\Security'
(I was always amused that the security level was for years in an insecure registry entry...)
In Office 2010, .xls files are now associated with "“Microsoft Application Virtualization DDE Launcher," or sftdde.exe. The version number of this exe is obviously not the version of Excel.
My question:
Other than actually launching Excel and querying it for version and security level (using OLE CreateOLEObject('Excel.Application')), is there a cleaner, faster, or more reliable way to do this that would work with all versions starting with Excel 2003?
Use
function GetExcelPath: string;
begin
result := '';
with TRegistry.Create do
try
RootKey := HKEY_LOCAL_MACHINE;
if OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\excel.exe', false) then
result := ReadString('Path') + 'excel.exe';
finally
Free;
end;
end;
to get the full file name of the excel.exe file. Then use GetFileVersionInfo as usual.
As far as I know, this approach will always work.
using OLE CreateOLEObject('Excel.Application'))
you can get installed Excel versions by using the same registry place, that this function uses.
Basically you have to clone a large part of that function registry code.
You can spy on that function call by tools like Microsoft Process Monitor too see exactly how does Windows look for installed Excel - and then to do it exactly the same way.
You have to open registry at HKEY_CLASSES_ROOT\ and enumerate all the branches, whose name starts with "Excel.Application."
For example at this my workstation I only have Excel 2013 installed, and that corresponds to HKEY_CLASSES_ROOT\Excel.Application.15
But on my another workstation I have Excel 2003 and Excel 2010 installed, testing different XLSX implementations in those two, so I have two registry keys.
HKEY_CLASSES_ROOT\Excel.Application.12
HKEY_CLASSES_ROOT\Excel.Application.14
So, you have to enumerate all those branches with that name, dot, and number.
Note: the key HKEY_CLASSES_ROOT\Excel.Application\CurVer would have name of "default" Excel, but what "default" means is ambiguous when several Excels are installed. You may take that default value, if you do not care, or you may decide upon your own idea what to choose, like if you want the maximum Excel version or minimum or something.
Then when for every specific excel branch you should read the default key of its CLSID sub-branch.
Like HKEY_CLASSES_ROOT\Excel.Application.15\CLSID has nil-named key equal to
{00024500-0000-0000-C000-000000000046} - fetch that index to string variable.
Then do a second search - go into a branch named like HKEY_CLASSES_ROOT\CLSID\{00024500-0000-0000-C000-000000000046}\LocalServer ( use the fetched index )
If that branch exists - fetch the nil-named "default key" value to get something like C:\PROGRA~1\MICROS~1\Office15\EXCEL.EXE /automation
The last result is the command line. It starts with a filename (non-quoted in this example, but may be in-quotes) and is followed by optional command line.
You do not need command line, so you have to extract initial commanlind, quoted or not.
Then you have to check if such an exe file exists. If it does - you may launch it, if not - check the registry for other Excel versions.

Resources