Unicode characters in LnkFile

Help
bethran
2006-01-05
2013-04-25
  • bethran

    bethran - 2006-01-05

    I'm trying to create shortcuts to files which contain one or more (Unicode) characters from an extended character set (Japanese) as well as ASCII.  Whilst these filenames are not correctly displayed in Windows they are valid and a shortcut can be created to them through explorer.

    The shortcuts created by the LnkFile class corrupt this character into two or more characters from the standard character set making the shortcuts point at non-existent files.

    Am I missing something obvious here or is there some easy work around??  From what I understand of the C++ wrappers, handling of the full Java String character set is implemented.

    B.

     
    • Arne Plöse

      Arne Plöse - 2006-01-05

      Can you break the problem to a small example, that I can find the bug and try to fix it?

      Arne

       
    • bethran

      bethran - 2006-01-05

      FileSystemView fsv = FileSystemView.getFileSystemView() ;

      try {
      File f = new File("C:\\battamn\\test");
      File[] files = m_fsv.getFiles(f, false);
                     
      for(int i = 0; i < files.length; i++) {
        String strFileName = files[i].getName();
        String strFilePath = files[i].getParentFile().getAbsolutePath();
        String strTargetPath = files[i].getAbsolutePath();
                         
        LnkFile shortCut = new LnkFile();
        shortCut.setName(strFileName);
      shortCut.setFolder(strFilePath);                     // shortcut location
                          shortCut.setPath(strTargetPath);   // shortcut target
                          shortCut.save();
                      }
                  }
                  catch (Win32Exception ex) {
                      System.err.println(ex.getMessage());
                      ex.printStackTrace();
                  }

       
    • bethran

      bethran - 2006-01-05

      Arne,

      This is the code I'm using, where C:\test contains a the file named: 488511.txt

      The resulting shortcut is named (and points to a file called) 488511.txt.

      Cheers,

      B.

      FileSystemView fsv = FileSystemView.getFileSystemView() ;

      try {
      File f = new File("C:\\test");
      File[] files = m_fsv.getFiles(f, false);
                     
      for(int i = 0; i < files.length; i++) {
        String strFileName = files[i].getName();
        String strFilePath = files[i].getParentFile().getAbsolutePath();
        String strTargetPath = files[i].getAbsolutePath();
                         
        LnkFile shortCut = new LnkFile();
        shortCut.setName(strFileName);
        shortCut.setFolder(strFilePath);
        shortCut.setPath(strTargetPath);
        shortCut.save();
      }
      }
      catch (Win32Exception ex) {}

       
    • bethran

      bethran - 2006-01-05

      Sorry for the replication there.

      The filename appears to be corrupting in the message when I copy it out again.
      I can send you a file with the appropriate name is you mail me an address.

      B.

       
    • Arne Plöse

      Arne Plöse - 2006-01-05

      Ok, I think ether you or I should file a bug against it.

      if the following codesnipplet (JUnit TestCase) produce the errror on your system as well, you can put it in a java file and attacht that file to the bug:

      public void testUTF8File() {
              try {
                  // File utf8File = File.createTempFile("488511", ".txt");
                  File utf8File = File.createTempFile("488511", ".txt");

                  String strFileName = utf8File.getName();
                  String strFilePath = utf8File.getParentFile().getAbsolutePath();
                  String strTargetPath = utf8File.getAbsolutePath();
                 
                  LnkFile shortCut = new LnkFile();
                  shortCut.setName(strFileName + ".lnk");
                  System.out.println("link target: " + strFileName);
                  System.out.println("link file:   " + shortCut.getName());
                 
                  shortCut.setFolder(strFilePath);
                  shortCut.setPath(strTargetPath);
                  shortCut.save();

              } catch (Win32Exception ex) {
              } catch (IOException e) {
                  fail(e.toString());
              }
          }

       
    • Arne Plöse

      Arne Plöse - 2006-01-05

      Or this is the complete test case:

                  File utf8File = File.createTempFile("488511", ".txt");

                  String strFileName = utf8File.getName();
                  String strFilePath = utf8File.getParentFile().getAbsolutePath();
                  String strTargetPath = utf8File.getAbsolutePath();
                 
                  LnkFile shortCut = new LnkFile();
                  shortCut.setName(strFileName + ".lnk");
                  shortCut.setFolder(strFilePath);
                  shortCut.setPath(strTargetPath);
                  shortCut.save();

                  LnkFile shortCut1 = new LnkFile(shortCut.getFolder(), shortCut.getName());

                  assertEquals("link file folder", shortCut.getFolder(), shortCut1.getFolder());
                  assertEquals("link file name", shortCut.getName(), shortCut1.getName());
                  assertEquals("link file target", shortCut.getPath(), shortCut1.getPath());

       
    • Arne Plöse

      Arne Plöse - 2006-01-06

      Hi bethran,

      please check out the current cvs, compile (dist) and test the fix ... and let me know if it works as expected.

      I filed a bug against it.

      Arne

       
    • bethran

      bethran - 2006-01-06

      Arne,

      Looks like that's fixed it for the UFT8 chars, it still fails for UTF16 though.

      For example, if you try to include the arabic letter Sad in your above example
      utf16File = File.createTempFile("48_\uFEBA_511", ".txt")

      The shortCut.save() command throws:

      com.roxes.win32.Win32Exception: save lnk file failed : Failed to save shortcut C:\...\Temp\48_?_5117512.txt.lnk

      Unfortunately, my spurious characters are in the UTF16 character set.

      B.
      B.

       
      • Arne Plöse

        Arne Plöse - 2006-01-07

        Ok see cvs log ;-),
        in short now the native part uses for all stings wchar_t (wide strings).
        This should fix your problem. The test can't detect the wrong link destinationn on its own at the moment. So you must check manually if the link works. The formally uses Ansi part cant handle chars that are not present in the current codepage (therfore the arabic char fails).
        I hope the the sources compile, if not Im rewrite the whole native stuff to use wide-strings ;-). Your bug is there all over the place.

        Arne

         
    • bethran

      bethran - 2006-01-07

      Arne,

      The revised source compiles, but unfortunately this doesn't seemed to have fixed things. 
      Running the following code fragment against the recompiled jar still throws a "save lnk file failed : Failed to save shortcut C:\...\Temp\48_?_51142301.txt.lnk" exception

      B.

      try {

      File utf8File = File.createTempFile("48_\uFEBA_511", ".txt");
      String strFileName = utf8File.getName();
      String strFilePath = utf8File.getParentFile().getAbsolutePath();
      String strTargetPath = utf8File.getAbsolutePath();
                 
      LnkFile shortCut = new LnkFile();
      shortCut.setName(strFileName); shortCut.setFolder(strFilePath);                     shortCut.setPath(strTargetPath);
      shortCut.save();
      } catch (Win32Exception ex) {
      System.err.println(ex.getMessage());
      } catch (IOException ex) {
      System.err.println(ex.getMessage());
      }

       
    • Arne Plöse

      Arne Plöse - 2006-01-08

      I added the win error number to the exception.
      This should help finding the problem.

      If the problem isnt solved let me know which windows do you use (the testcases passes all on a german w2k). Win95/98 dont work because there missing the used IShellLinkW.

      Arne

       
    • bethran

      bethran - 2006-01-08

      Arne,

      Many thanks for all your help on this.

      I've recompiled the current source from CVS and added a catch block {fail(ex.toString);} for the Win32Exception in the LnkFileTest set.

      The results of executing these tests are included below.  I don't see the win-error number in the exception.

      I'm running on Windows XP Home and Professional (UK)

      B.

      Testsuite: com.roxes.win32.LnkFileTest
      Tests run: 11, Failures: 1, Errors: 0, Time elapsed: 0.219 sec

      Testcase: testUTF16File(com.roxes.win32.LnkFileTest):    FAILED
      com.roxes.win32.Win32Exception: save lnk file failed : Failed to save shortcut C:\...\48_?_51148947.txt.lnk
      junit.framework.AssertionFailedError: com.roxes.win32.Win32Exception: save lnk file failed : Failed to save shortcut C:\...\Temp\48_?_51148947.txt.lnk
              at com.roxes.win32.LnkFileTest.testUTF16File(LnkFileTest.java:173)
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

      name: test48935

      name: test48937

      name: test48938

      name: test48939

      name: test48940

      name: test48941

      name: test48942

      name: test48943

      name: ÄÖÜ48945.txt

      name: 48_?_51148947.txt

       
    • Arne Plöse

      Arne Plöse - 2006-01-08

      Ok the errormessages indicates that you use an old lnkfile.dll.

      First search your JRE/JDK for files named "roxes-*.dll" and delete them, they will be copied as needed.

      Make sure you use the latest dll if the error messages begins with >>>"save lnk file failed :"<<< Failed to save ... you still have the old dll.

      Here is the source of that string: "Failed to save shortcut %s WinError: \&quot;%d\&quot;".

      the current version is "roxes-lnkfile-1.0.5.dll".

      Happy debugging

      Arne

       
      • bethran

        bethran - 2006-01-08

        I'll go and stand in the corner of the room with a 'Fool's hat on.  I've been carefully deleting the target directory each re-build, but forgot about that!

        Both your LnkTest and my test file work correctly under Java1.5.0_03 on my home machine.

        I've also recompiled the JAVA and sucessfully run the tests under 1.4.2_04 as well. 
        Note: recompiling the source under 1.4, the @Override tag in Registry.java has to be removed and there is some issue with the xalan.jar in the doc-reference build step so I skipped that.

        One observation: the files I've taken out of CVS are still marked as 1.0.3 not 1.0.5.

        I'll have to test this on the target platform on Tuesday but I see no reasons why it shouldn't work and I'll let you know if there are any other problems.

        Many thanks for all your efforts, Arne.

        B. 

         
    • Arne Plöse

      Arne Plöse - 2006-01-08

      Thats li(v|f)e!

      I know about the xalan behaviour, if you need a solution for 1.4, see the initial (oragevolt 1.3 from may 2005) build.xml. Its working under 1.4 but unfortunatly not under 1.5.

      With the 1.4/1.5 problem, someone suggested using retroweaver (on sourcefoge), if I have more time, I will try it out.
      I will check the cvs to check whats going on.
      So there will be a new alpha just around the corner.
      And many thanks for undigging that bug.

      Arne

       

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks