SAS - Fails to load program with long name from Windows Explorer - windows

I am using Base SAS 9.4 on Windows 7. For various reasons, which are detailed below, some of my programs have extremely long names. Exacerbating this further, the programs are stored deep in the abyss of a network drive. This causes problems when trying to open from Windows Explorer. I believe the problem lies with SAS, but have tagged the question with Windows in case not. I'm hoping there is some way to address this problem via a configuration file or an edit to the registry.
To open a program, I typically double click on the .sas file in Windows Explorer. This opens the Enhanced Editor after a brief waiting period in which a SAS message box states:
The SAS System is processing requests. Please wait...
When a program's full name, including path and extension, exceeds 182 characters (i.e. has form: \\network-location\a\bunch\of\....\folders\program path exceeding 182 char.sas), the same "SAS System is processing requests" message appears, but then a Windows error is generated.
Not surprisingly, no solution is proffered by Windows.
When the program name is such that the full path is exactly 182 characters, nothing happens. I double click on the program and the only result is to select the file in Windows Explorer. If I monitor "Processes" within the Windows Task Manager, no new processes are started when such a program is double clicked.
When the program name is such that the full path is less than 182 characters, the program opens in the Enhanced Editor as expected.
According to MSDN, the max path is 260 characters. Clearly, 182 is well below that limit. SAS is the only application which has a problem with the path length. For example, I can copy the file name and extension, create a new text document with the same name (plus .txt) and open the file in Notepad, Notepad++, Word, Wordpad, Emacs, etc.
I have deduced two workarounds for working with names exceeding 182 characters.
If I open SAS via SAS.exe, I can load a program through the Open dialog with a path exceeding 182 characters just fine. This is not a good solution, however, as the Open dialog does not allow paths to be copy/pasted. The entire file path must be traversed. I can also drag such a program into the editor window within SAS to load it. This too is not a good solution, as a program will only load if there is a blank editor window. If the program is accidentally dragged on the the log window, it will execute automatically. Also, the program does not open in a convenient location. It opens in the middle of the Enhanced Editor and must be manually resized. That the programs can be loaded and executed at all leads me to believe that there is some way to fix this problem. It seems that somewhere in the process of loading the file, SAS violates some variable limit.
Of course, people would suggest that I use a different network location or shorter names. To the former, I am required to use a specific network location. To the latter, these programs are being developed in parallel with various reports. Many of the programs are similar and the corresponding references (table/figure numbers) in the reports change multiple times/aren't always communicated to me. Through experience, I've found the surest way to work with these uncertainties is to simply name the file by the label it's given in the report. Otherwise, I need to adopt unclear abbreviations, bad organizational practices, or introduce intermediate steps (like creating codes or a document which indexes the programs).
Edit: Per Joe's comment, it seems that the Open dialog allows copy and paste for specific file names. A file path can be copied in Windows Explorer via Shift + Right Mouse Click > Copy as Path and pasted into the "File Path" box in the Open dialog.
To avoid traversing the tree, the Current Folder may be updated before accessing the Open dialog. This is located at the bottom right of the Enhanced Editor.
The Open dialog starts at whatever the Current Folder location is set to.

I suspect your issue is that your 260 limit is in fact applicable.
When you double-click a program file, it doesn't just copy the path to SAS. Instead, what happens is SASOACT.exe is called, with a command of something similar to this:
"C:\Program Files\SAS94\SASFoundation\9.4\core\sasexe\sasoact.exe" action=Open datatype=Access filename="%1" progid=SAS.Application.940
That's well over 100 characters already by itself; presumably, behind the scenes, you end up with something like
"C:\Program Files\SAS94\SASFoundation\9.4\core\sasexe\sasoact.exe -open ""%1"""
Which adds around 70 or 80 characters to what you're passing it. Thus the 260 character limit.
You should use one of the workarounds - I personally prefer to just file->open, myself, but really whatever works best for you is fine. You could also consider using another editor for the simple double-click actions, though any editor you chose would still have some issues.
You could also consider asking IT to install SAS itself in a location that had a shorter path name, though realistically that might save 10 characters or so.
As for pasting; you can paste a path name just as easily as a file name into the file->open dialog. I have no idea why you don't seem to think you can, but I just did so now with no more difficulty than any other folder dialog...
Another workaround to consider, by the way, is mapping a drive letter to the network path. I.e., if your network path is
//myserver/projects/financial/projectnumber/.../
You map some letter (let's say R: arbitrarily) to that root path, //myserver/projects/financial/projectnumber, which is not changing anything other than how you refer to it locally. Then you can use:
R:\...\filename.sas
And you don't have to navigate paths, etc. You'd have to repeat that mapping process on any machine that you wanted to do this on, but if this mostly about your own workflow, that shouldn't be an issue. Just don't refer to R: inside the program itself and nobody else will ever know that you've changed anything.

Related

Searching for Command Prompt Parameters?

Is there anyway to search command prompt parameters in a general sense. Or are we hostage to the documentation of such programs? For example in the command prompt I type explorer or notepad... but if I put the first parameter as a file path it will open that file path for me... how am I supposed to know this parameter input exists and perhaps there is a bunch of other parameter fields I am unaware of. Is there anyway to search program parameters systematically?
In Windows programs are responsible for processing their own command line parameters, and they can do so in any way they please. (It is common to hand off tokenization to the C runtime library, but not mandatory.)
This gives the programmer maximum flexibility, but does mean that if the programmer has not documented the command line there is no straightforward way to reverse engineer it after the fact.
(UNIX isn't very much different; the tokenization is handled by the shell, but the rest of the processing is the applications responsibility. In VMS, by contrast, the entire command-line processing is handled by the shell, based on syntax information that must be embedded in the application.)
It is conventional for an application to provide a command-line syntax summary in response to one or more of the following options:
application /?
application -?
application /help
application -help
application --?
application --help
(Arranged approximately from most-common to least-common; the variants with two hyphens are usually only found in software that has been ported from UNIX.)
I haven't looked for actual statistics, but my impression is that the majority of command-line applications (perhaps 80% or more) do provide such a summary. It is less common for GUI applications.
Failing that, you can sometimes find command-line options by looking for strings in the executable file. Microsoft provides a utility that does this, strings.exe, downloadable from their web site. (Of course, knowing the existence of a possible command-line option doesn't necessarily mean you'll be able to figure out what it does!)
If you have access to the source code, or are skilled at disassembly, that may provide another option if you are desperate enough.
No. Though you can always try programname /?.
Notepad takes a single filename only OR takes /p filename ... (you can see the command in txtfiles print entry in the registry).
Here's something from Windows 98 Explorer's it still the same.
Explorer
explorer [/n] [/e][,/root,object][[,/select],subobject]
None Explorer rooted at the Desktop
/n Opens a new window.
/e Explorer View (default if nothing else is on the command line.)
/root,object Starts Explorer with object the top item (normally Desktop is the top item). Eg: explorer /e,/root,c:\Starts Explorer with the C drive as the only drive available.
/select,subobject Selects the specified subobject.
Replaceable parameters are %1 (one) which is the short file or folder name and %l (L) which is the long file name.
/IDLIST
This is an additional parameter that means a Windows internal structure is being passed. eg:
Explorer.exe /e,/idlist,%I
The %I is a replacable parameter representing an IDLIST.
Rooted Views
To open an explorer item that starts with a special folder as the top folder use the following syntax.
Where the special folder is a sub folder of the desktop
explorer /e,root,::{CLSID of special folder}
Where the special folder is a sub folder of another special folder (usually, if not always My Computer)
explorer /e,root,::{CLSID of parent}/::{CLSID of special folder}
Where the special folder is part of the file system
explorer /e,root,path to folder
See Namespaces on the Icons Page for a list of CLSIDs for special folders.
Examples
Note that /select is inconsistent. Sometime the / is required, sometimes it should be left out, and sometimes it doesn't matter.
Starts explorer with the Windows folder opened and selected.
explorer /e,select,c:\windows
Starts explorer with Windows the top level folder and command opened and selected.
explorer /e,/root,c:\windows,select,c:\windows\command
Starts explorer with Windows the top level folder and Tips.txt showing instead of the file listing.
explorer /e,/root,c:\windows,select,c:\windows\tips.txt
Starts explorer with My Computer the top level folder and all branches except for drives collapsed.
explorer /e,/root,::{20d04fe0-3aea-1069-a2d8-08002b30309d}
Starts explorer with C:\ the top level folder.
explorer /e,/root,c:\
Starts the Dial Up Networking folder in folder view.
explorer.exe ::{20d04fe0-3aea-1069-a2d8-08002b30309d}\::{992cffa0-f557-101a-88ec-00dd010ccc48}

FTYPE/ASSOC priority and adding to OpenWithList from the command line

(Not sure if this belongs on superusers, but it seems there is a cmd.exe tag here, so here goes...)
As background, I'm working on a Firefox add-on (This question does not require knowledge of Firefox, btw, as Firefox add-ons can call the command line.) The add-on aims to build different kinds of shortcuts to cmd.exe (especially for the sake of my project https://github.com/brettz9/webappfind which allows files to be opened directly from the desktop into web apps).
Anyways, I'd like to give users the option to associate these shortcuts:
As the default handler for specific file extensions or file types.
To show up within the Open With list of applications (even if the user opts not to make the apps as default handlers)
As far as the default handling, I have found the ftype and assoc (and associate) commands, but I have read that user selections will override their behavior. Is there some way to ensure that I can get priority from the command line in associating file extensions to types and specific executables (until the user changes it again), or if it is not possible, then at least through C++ or the like?
As far as the Open With list:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\<file extension>\OpenWithList
...in my testing (with an exe), this command:
reg add HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.svg\OpenWithList /v d /d D:\wamp\www\webappfind\cplusplus\WebAppFinder-view-mode-Firefox.exe
...did cause the exe file to show up in:
reg query HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.svg\OpenWithList
...but it did not show up when I subsequently right-clicked a file with the ".svg" extension.
I would really appreciate any help with these two points.
REGEDIT4
[HKEY_CURRENT_USER\Software\Classes\Applications\MYFOO.exe\shell\open\command]
#="\"C:\\MYFOO.exe\" \"%1\""
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.myfoo]
"Application"="MYFOO.EXE"
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.myfoo\OpenWithList]
"a"="MYFOO.EXE"
"MRUList"="a"
So I got to an investigation what makes those file associations. It appears that you have to create a mapping from the bare EXE name to the full path as shown in the first two long-ish lines. Then you must only use the EXE name in the .extension branch. Setting the .extension's Application value will give you your default app instantly. Remember, only use APP.EXE, its full path must be defined as above. This was your main error. The "%1" part allows you to customize the parameters of your program so that it doesn't have to be just the opened document in quotes, as shown here. The backslashes are just escape characters for Regedit, you may discard them as you see fit.
The OpenWithList is tricky in the sense that there are letters for entries and just a blind write may overwrite some of the user's favorite apps. One approach would be to call your item "z" to lower the probability of overwriting. The right way would be enumerating the key and giving your app the first free letter. The MRUList is not essential, although it should have each used letter once and yours bumped to the start.
Note about user friendliness: Explorer will cache these values until next reboot. Make sure you update the registry and place exe first and create your file later. Although the caching only fully influences the display of the file and when it is run, the registry is read again and it will execute as you want.
TIP: If you decide to use Regedit instead of reg, the /s parameter skips the confirmation message and applies the values right away. Make sure you use double backslashes in the full path as shown. When preparing your temporary .reg file, make sure you append two CRLF's to the end or a glitch may cause your last line of code to be ignored. This sample starts with REGEDIT4 which signifies an ANSI file. If you need support for Unicode in your app path, you'll have to start the file with Windows Registry Editor Version 5.00 and store it in UTF16. This is already a superior solution to calling reg because there's no way you could get CMD.EXE to process special UTF stuff through the command line without mangling.

Can the last opened file location be directly altered?

As I understand it, when a file open dialog box (such as GetOpenFileName) is used, Windows will automatically remember where the last file was that was opened by the program, and Windows remembers these locations separately for each program. Is there a way to directly alter this, in order to cause the file picking dialog for program X to start in C:\Example\Directory?
I'm attempting to automate a program which has been programmed to work only through a GUI, and I don't have any access to the internals of this program (such as being able to alter how it calls the file picker). Instead, I'm using a mouse macro (via AutoHotkey). If I can be completely sure that the file picker will start in a particular place, I should be able to automate the rest with mouse clicks.
If you had access to the source code, I'd suggest you just change the lpstrInitialDir property of the OPENFILENAME passed to GetOpenFileName().
Outside of that, you'll want to change the registry keys for the MRUs:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32
What might make more sense, and might fix the issue you're having, is also changing the Working Directory so that the default location isn't "My Documents", if you're experiencing that.
Depending on the operating system, the results vary:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646839%28v=vs.85%29.aspx

Opening a CHM file produces: "navigation to the webpage was canceled"

I am trying to open a .chm file.
I downloaded the source, extracted it, and double clicked on Waffle.chm and clicked "Open" but no matter what element in the chm file I click, I get the message:
Navigation to the webpage was canceled.
What you can try:
Retype the address.
What's going on here?
Summary
Microsoft Security Updates 896358 & 840315 block display of CHM file contents when opened from a network drive (or a UNC path). This is Windows' attempt to stop attack vectors for viruses/malware from infecting your computer and has blocked out the .chm file that draw data over the "InfoTech" protocol, which this chm file uses.
Microsoft's summary of the problem: http://support.microsoft.com/kb/896054
Solutions
If you are using Windows Server 2008, Windows 7, windows has created a quick fix. Right click the chm file, and you will get the "yourfile.chm Properties" dialog box, at the bottom, a button called "Unblock" appears. Click Unblock and press OK, and try to open the chm file again, it works correctly. This option is not available for earlier versions of Windows before WindowsXP (SP3).
Solve the problem by moving your chm file OFF the network drive. You may be unaware you are using a network drive, double check now: Right click your .chm file, click properties and look at the "location" field. If it starts with two backslashes like this: \\epicserver\blah\, then you are using a networked drive. So to fix it, Copy the chm file, and paste it into a local drive, like C:\ or E:. Then try to reopen the chm file, windows does not freak out.
Last resort, if you can't copy/move the file off the networked drive. If you must open it where it sits, and you are using a lesser version of windows like XP, Vista, ME or other, you will have to manually tell Windows not to freak out over this .chm file. HHReg (HTML Help Registration Utility) Utility Automates this Task. Basically you download the HHReg utility, load your .chm file, press OK, and it will create the necessary registry keys to tell Windows not to block it. For more info: http://www.winhelponline.com/blog/fix-cannot-view-chm-files-network-xp-2003-vista/
Windows 8 or 10? --> Upgrade to Windows XP.
"unblocking" the file fixes the problem. Screenshot:
Win 8 x64:
just move it to another folder or rename your folder (in my case: my folder was "c#").
avoid to use symbol on folder name. name it with letter.
done.
In addition to Eric Leschinski's answer, and because this is stackoverflow, a programmatical solution:
Windows uses hidden file forks to mark content as "downloaded". Truncating these unblocks the file. The name of the stream used for CHM's is "Zone.Identifier". One can access streams by appending :streamname when opening the file. (keep backups the first time, in case your RTL messes that up!)
In Delphi it would look like this:
var f : file;
begin
writeln('unblocking ',s);
assignfile(f,'some.chm:Zone.Identifier');
rewrite(f,1);
truncate(f);
closefile(f);
end;
I'm told that on non forked filesystems (like FAT32) there are hidden files, but I haven't gotten to the bottom of that yet.
P.s. Delphi's DeleteFile() should also recognize forks.
The definitive solution is to allow the InfoTech protocol to work in the intranet zone.
Add the following value to the registry and the problem should be solved:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\HTMLHelp\1.x\ItssRestrictions]
"MaxAllowedZone"=dword:00000001
More info here: http://support.microsoft.com/kb/896054
Go to Start
Type regsvr32 hhctrl.ocx
You should get a success message like:
" DllRegisterServer in hhctrl.ocx succeeded "
Now try to open your CHM file again.
other way is to use different third party software. This link shows more third party software to view chm files...
I tried with SumatraPDF and it work fine.
I fixed this programmatically in my software, using C++ Builder.
Before I assign the CHM help file, Application->HelpFile = HelpFileName, I check to see if it contains the "Zone.Identifier" stream, and when it does, I simply remove it.
String ZIStream(HelpFileName + ":Zone.Identifier") ;
if (FileExists(ZIStream))
{ DeleteFile(ZIStream) ; }
There are apparently different levels of authentication. Most articles I read tell you to set the MaxAllowedZone to '1' which means that local machine zone and intranet zone are allowed but '4' allows access for 'all' zones.
For more info, read this article:
https://support.microsoft.com/en-us/kb/892675
This is how my registry looks (I wasn't sure it would work with the wild cards but it seems to work for me):
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\HTMLHelp]
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\HTMLHelp\1.x]
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\HTMLHelp\1.x\ItssRestrictions]
"MaxAllowedZone"=dword:00000004
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\HTMLHelp\1.x\ItssRestrictions]
"UrlAllowList"="\\\\<network_path_root>;\\\\<network_path_root>\*;\\ies-inc.local;http://www.*;http://*;https://www.*;https://*;"
As an additional note, weirdly the "UrlAllowList" key was required to make this work on another PC but not my test one. It's probably not required at all but when I added it, it fixed the problem. The user may have not closed the original file or something like that. So just a consideration. I suggest try the least and test it, then add if needed. Once you confirm, you can deploy if needed. Good Luck!
Edit: P.S. Another method that worked was mapping the path to the network locally by using mklink /d (symbolic linking in Windows 7 or newer) but mapping a network drive letter (Z: for testing) did not work. Just food for thought and I did not have to 'Unblock' any files. Also the accepted 'Solution' did not resolve the issue for me.
Moving to local folder is the quickest solution, nothing else worked for me esp because I was not admin on my system (can't edit registery etc), which is a typical case in a work environment.
Create a folder in C:\help drive, lets call it help and copy the files there and open.
Do not copy to mydocuments or anywhere else, those locations are usually on network drive in office setup and will not work.

GVim runs very slowly when editing files on a windows share

On my computer at work, any time I open a file located on a network share, GVim becomes completely unusable. Scrolling through the document can take 15 seconds to go one "page". Even using the movement keys to go from one word to another can take 2 to 3 seconds. This seems to be a new behavior, but for the life of me I can't remember changing anything that would cause it. I'm under the impression that Vim doesn't actually access a file except on open and on save. Is that right?
There are a few factors which may affect this.
First, make sure you have Vim setup to prefer storing the swapfile locally. If your $HOME is on a local drive, I tend to put this in my vimrc (which will either be at $HOME\_vimrc or $VIM\_vimrc). Make sure you create that directory, otherwise Vim will continue to use one of the other directories in the list.
set directory^=$HOME/tmp
This prepends the $HOME/tmp directory to the start of the list that Vim checks for where to place swapfiles.
Second, do the same for the backup file that Vim creates. Same situation as above but the option you'll be changing is backupdir instead of directory.
Third, make sure you disable the matchparen plugin. This plugin is new to Vim 7, so you may be used to using an older version of Vim. This causes frequent scanning of the file for matching parens, braces, etc. which can drastically slow Vim down when the file is on a network share. Again, this should go in your vimrc.
let g:loaded_matchparen = 1
If you only want to disable the plugin temporarily, you can use the command :NoMatchParen and then :DoMatchParen to re-enable it later in that Vim session.
Finally, if none of those help you can always copy the file locally and edit it.
Swap file has nothing to do with it. I have my swap file local and still have the problem. I use Process Monitor from SysInternals.com and it revealed bad behavior when attempting to open "\server\TestTool\foo\ReadMe.TXT"
It first attempts a CreateFile (aka, Directory open) on "\serve\". Notice the last character is missing. This will cause 4 seconds to time out with "OBJECT PATH INVALID".
Then it tries CreateFile on "\server\TestToo\". Server name is correct by the last letter of "TestTool" is clipped. Again, a 3 second time out with "BAD NETWORK NAME".
Finally it gets it right and calls CreateFile on "\server\TestTool\" which works right away.
Then CreateFile on "\server\TestTool\foo" which works right away.
Then CreateFile on "\server\TestTool\foo\ReadMe.TXT" which works right away.
WHY is it trying bad names for the server and the root directory??? What madness is this?
I fixed this issue after setting HOME path by force in advanced system settings.
(Your current HOME path would be a network directory.)
Control Panel > All Control Panel Items > System > Advanced system settings > Environment variables
Press "New..."
Variable name: HOME
Variable value: c:\Home\ **<-- Type your home directory**
A follow up on jamessan's answer: to disable the plugin automatically when you edit files on a share, put this line in you _vimrc
autocmd BufReadPre //* :NoMatchParen
You could consider installing LargeFile plugin. It disables a couple of features impacting the performance.
Having a similar issue as David Anderson, but no solution yet.
When loading \\ServerName\A$\B\C\File.txt Vim will do:
Open \ServerName\A$\B\C\File.txt
Then it does many loops like:
CreateFile \ServerName\A$ <-- Each taking roughly 1 sec
QueryDirectory \ServerName\A$\B
QueryDirectory \ServerName\A$
QueryDirectory \ServerName\A$\B\C
QueryDirectory \ServerName\A$\B
To compare with Notepad++ which loads files almost instantaneously there are more lines and Notepad++ never queries \\ServerName\A$.
Also the duration (Duration column) written in Process Monitor is low, but the time taken by Vim seem quiet high (Time of Day column) for the CreateFile \\ServerName\A$.
I've no plugins installed as far as I know and followed other tips to speed up network shares loading.
Note: The dollar is in the path. More weird is that Vim will load very fast on more recent Windows Server (2008 instead of 2003) with the same folder structure.
I had the same problem (slow gvim editing over network drive) and have fixed it. It was for me -- no kidding -- the titlestring.
Background: I use a vertically arranged taskbar with Windows 10. This has the advantage that my open windows behave like a growing stack from top to bottom. For example, see here some currently open windows with how-to-run.txt as a network file:
With that it makes sense, that the filename is going first in the window title of gvim and the path goes after that. So I used exactly the titlestring in my vimrc, which is still officially recommended in the help file vim81/doc/options.txt, line 8202:
set titlestring=%t%(\ %M%)%(\ (%{expand(\"%:~:.:h\")})%)%(\ %a%)
For local files that's ok, but for network files this is way too slow.
Now my fix:
set titlestring=
Same effect (filename first), but now gvim runs very fast for remote files as well!
BTW, I also tried all the above mentioned recommendations (directory, backupdir, matchparen, disabled all the plugins, tried the LargeFile plugin although I observed the slow gvim also for small files, etc.). I also changed my statusline to something really simple.
It all had no effect for me. But the funny titlestring...

Resources